tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

Problém s uvozovkami, Oracle

před 8 lety

Semik
Člen | 124

Zdravím, mám problém s dotazy na databázi driverem oracle.

Posílám úplně jednoduchý dotaz:

->query('SELECT [id_uzivatele], [email], [heslo], [nazev_role]
         FROM [www_uzivatele]
         JOIN [www_role] using([id_role])
         WHERE [email] = %s', $email)->fetch();

Problém je ten že výsledkem je exception:
oci_execute(): ORA-00905: missing keyword

na řádku 108, query($sql) metody oracle driveru

oci_execute($res, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);

V profileru je dotaz jako

SELECT "id_uzivatele", "email", "heslo", "nazev_role"
FROM "www_uzivatele"
JOIN "www_role" using("id_role")
WHERE "email" = 'uuu'

Myslím že problém je v tom, že se řetězec zpracovává jako string taky ve dvojitých uvozovkách a to s těmi co už uzavírají sloupce a tabulky nejde dohromady.

před 8 lety

HosipLan
Moderator | 4693

A jak by měl dotaz podle tebe vypadat?

před 8 lety

Semik
Člen | 124

Takže změna, chyba odhalena.
Nastává při volání explainu.
DibiProfiler před dotaz pouze přidává EXPLAIN, což je ale v Oracle špatně, tam je EXPLAIN PLAN.

před 6 lety

Stranger
Člen | 5

Semik napsal(a):

Takže změna, chyba odhalena.
Nastává při volání explainu.
DibiProfiler před dotaz pouze přidává EXPLAIN, což je ale v Oracle špatně, tam je EXPLAIN PLAN.

Narazil jsem na stejný problém, v prvním kroku jsem opravil EXPLAIN PLAN na EXPLAIN PLAN FOR.
Tím jsem se dostal dál, ale jen o krok, kde dostávám chybu:
File: …\libs\dibi\drivers\oracle.php Line: 350
oci_fetch_array(): ORA-24374: definice neuskutečněna před vyvoláním nebo provedením a vyvoláním
348: public function fetch($assoc)
349: {
350: return oci_fetch_array($this->resultSet, ($assoc ? OCI_ASSOC : OCI_NUM) | OCI_RETURN_NULLS);
351: }

S tímto si už rady nevím, poradí někdo?

Prozatím jsem chybu zaignorvoal podmínkou níže (DibiNettePanel):
if ($this->explain && $event->type === DibiEvent::SELECT && false) {
try {
$backup = array($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime);
$event->connection->onEvent = NULL;
$cmd = is_string($this->explain) ? $this->explain : ($event->connection->getConfig(‚driver‘) === ‚oracle‘ ? ‚EXPLAIN PLAN FOR‘ : ‚EXPLAIN‘);
$explain = dibi::dump($event->connection->nativeQuery(„$cmd $event->sql“), TRUE);
} catch (DibiException $e) {}
list($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime) = $backup;
 }

Editoval Stranger (22. 4. 2013 14:51)

před 6 lety

@lex
Člen | 5

Narazil jsem na stejny problem jako popisuje uzivatel Stranger. Chci se zeptat pokrocil jsi nejak s timto problemem ?

před 6 lety

Stranger
Člen | 5

Na základě nového komentáře, jsem ještě jednou pátral co s tím a zjistil jsem následující:
EXPLAIN PLAN FOR pouze vygeneruje plán, pro jehož zobrazení je nutné volat například
SELECT * FROM TABLE(dbms_xplan.display), či select * from plan_table (kde jsou ale všechny vytvořené plány)
Když jsem se ale snažil zjistit, co přesně se s tím v rámci DibiNettePanel děje, tak dle jiné aplikace na MSSQL mám zato, že se vypíše jen výstup SQL, tedy s daty o plánu se nijak nepracuje, proč se to tedy nespouští jako čisté SQL, ale jako EXPLAIN?
Řešení pro zajištění korektní funkce dle MSSQL je vypuštění $cmd, tedy ⇒ $explain = dibi::dump($event->connection->nativeQuery(„$event->sql“), TRUE);