Escapovani SQL pro Oracle

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
ventil
Člen | 3
+
0
-

S Nette teprve začínám, ale po shlédnutí instruktážních videí a pročtení dokumentace jsem se pustil do přepracovávání jednoho z mých projektů. Rozčarován jsem byl hned na začátku, když mi jeden modul nechtěl pomocí dibi načíst jednoduchý SQL dotaz.

Po zkoušení různých syntaxí:

dibi::query('SELECT * FROM [table] WHERE [id] = %i', $id);
dibi::query('SELECT * FROM `table` WHERE `id`=%i', $id);
dibi::select(*)->from('table')->where('id = %d', $id);

byla výsledkem vždy stejná výjimka: „ORA-00942: table or view does not exist“. V debugu jsem si všiml, že Nette vždy vyprodukuje dotaz ve tvaru: "SELECT * FROM "table" WHERE "id" ... ", což jsem nechtěl. Pátraje po tom, kde se tam ty uvozovky neustále berou jsem se dostal až k drivers/oracle.php k funkci escape($value, $type), kde je následující:

...
  case dibi::IDENTIFIER:
  // @see http://download.oracle.com/docs/cd/B10500_01/server.920/a96540/sql_elements9a.htm
    $value = str_replace('"', '""', $value);
    return '"' . str_replace('.', '"."', $value) . '"';
...

Na uvedeném odkazu je specifikace, že pokud se identifikátor uvede do uvozovek, pak je case-sensitive, jinak je case-insensitive. Takže jinými slovy mohou identifikátory "table", "Table", "TABLE" apod. představovat naprosto odlišné objekty v DB. Ve svém okolí neznám žádného databázistu, který by tuto zhýralost využíval.

Jelikož mám spoustu skriptů napsaných čitelnou formou á la "SELECT * FROM albums WHERE interpret LIKE 'Jackson%'", chci se pozeptat (než si oracle.php přepíšu sám). Co k tomu vedlo, že jsi se rozhodl dávat identifikátory Oracle do uvozovek namísto jejich běžné formy (která je CI) ??
Popřípadě je možno v oficiálním releasu upravit ony str_replace funkce, tak aby uvozovky (u názvů identifikátorů objektů) nepoužívaly ?

Pokud bych chtěl využívat dibi musel bych vše přepisovat do této nepěkné formy:

dibi::query('SELECT * FROM [TABLE] WHERE [ID] = %i', $id);
dibi::query('SELECT * FROM `TABLE` WHERE `ID`=%i', $id);
dibi::select(*)->from('TABLE')->where('ID = %d', $id);

Prostě vše psát velkými písmeny, což je pro mě dost nezvyk :-)

Díky moc za odpověď…

Editoval ventil (6. 8. 2009 1:30)

Petr Motejlek
Člen | 293
+
0
-

Tohle patří do forum.dibiphp.com ;).

PetrP
Člen | 587
+
0
-

Nette forum != dibi forum
takže příště zde

Jinak ty máš v databazi ti tabulky velkejma pismenama, nebo to oracle dělá velkejma automaticky?

tady je revize kdy to tam bylo přidaný

Petr Motejlek
Člen | 293
+
0
-

Takže jsem to testoval — všem doporučuji používat uvozovky při definici názvů tabulek a sloupců (nebo cokoliv, co vaše DB používá jako identifikátor, nejlíp použít dibi už pro CREATE TABLE). Např. ten Oracle je docela zajímavě case sensitive – když použiju při CREATE TABLE v názvu tabulky něco bez uvozovek, uloží si to oracle jako case insensitive identifikátor — jako takový k němu lze dojít buď použitím uvozovek a uvedení identifikátoru ve velkých písmenech (např. „MOJE_TABULKA“), nebo bez uvozovek (a pak Oracle udělá automaticky upper case a uvozovky si dodá).

To, co výše popisuji, bohužel není na všech DB stejné, dokonce se to i (jako např. u MySQL) může na různých platformách chovat různě. Proto všem doporučuju používat identifikátory tam, kde se mají používat a nespoléhat se na DB, že jí všechno dojde ;).

ventil
Člen | 3
+
0
-

Omlouvám se za nevhodné zařazení do fóra (dibi by asi vážně bylo vhodnější :-).

Podíval jsem se ještě na jeden zdroj: http://www.amler.biz/…racle-mssql/ a opravdu se to chová tak jak popisoval Petr Motejlek. Ach jo…

Díky tomu, že jsem SQL nikdy neuvozoval, nesetkal jsem se s tímto problémem. Díval jsem se na tu revision 147 a opravdu netuším jak dál. Opravit spoustu SQL skriptů a přepsat vše na velká písmena aby mi to schroustalo dibi, nebo si udělat vlastní verzi oracle.php a tento quoted identifiers security fix si tam zrušit ?

Editoval ventil (6. 8. 2009 12:07)

PetrP
Člen | 587
+
0
-

ventil napsal(a):

Opravit spoustu SQL skriptů a přepsat vše na velká písmena aby mi to schroustalo dibi, nebo si udělat vlastní verzi oracle.php a tento quoted identifiers security fix si tam zrušit ?

Nebo si v tom vlastnim driveru prevadet nazvy tabulek na velky pismena, je to nic moc, ale asi lepší než uvozovky zrusit.

Petr Motejlek
Člen | 293
+
0
-

To převádění na upper case už ve vlastním driveru zní asi nejlíp – nebo použij namísto např. [id] ⇒ [ID] – to ti bude fungovat, i když nebudeš měnit DB schéma.

Pro příště a pro všechny — používejte Dibi i pro CREATE příkazy (nebo si ručně „ouvozovkujte“ identifikátory).

ventil
Člen | 3
+
0
-

Nakonec jsem tedy zvolil variantu UpperCase (vlastní drivers/oracleuc.php s třídou DibiOracleUCDriver), tak abych u nových projektů (kde budu datový model teprve tvořit) používal originální třídu.

Až se někdy dostanu k případné změně (aktualizaci) datového modelu této aplikace, pak už si dám na identifikátory v CREATE TABLE ... či u CREATE OR REPLACE VIEW ... bacha.

Díky všem za rady.