Seite 1 von 1

cx_Oracle problem mit parametern im execute befehl

Verfasst: Dienstag 5. Dezember 2006, 21:26
von z0mg
hallo,
ich benutze Oracle 10g, python 2.4, das passende cx_Oracle und habe folgendes problem.

cursor = connection.cursor()
cursor.arraysize = 50
cursor.execute("""SELECT :a FROM yat""",a="NO")
result=cursor.fetchall()
print result

als regebniss wird folgendes ausgegeben:
[('NO',), ('NO',), ('NO',)]

bei
cursor.execute("""SELECT NO FROM yat""")
[(1000,), (1001,), (1002,)]

wenn ich NO anstelle von :a im execute benutze funktioniert es.
auch wenn ich einen string vorher zusammensetze und ihn dem execute übergebe geht es. nur mit parametern nicht.
woran kann das liegen?

da war nochwas,
cursor.execute("desc yat")
ergibt eine fehlermeldung:
DatabaseError: ORA-00900: invalid SQL statement
das gleiche gilt für "describe yat"

irgendwelche ideen??

Verfasst: Dienstag 5. Dezember 2006, 21:39
von BlackJack
Die Parameter sind für *Werte* nicht für Bezeichner von Tabellen oder Spalten.

``DESC`` bzw. ``DESCRIBE`` sind keine SQL-Anweisungen. Jedenfalls kein Standard-SQL.

Verfasst: Dienstag 5. Dezember 2006, 21:57
von z0mg
ok, da kann ich mit leben das desc nicht geht.

gibt es sonst keinen weg auch bezeichner dynamisch in execute befehlen zu benutzen?

Verfasst: Mittwoch 6. Dezember 2006, 06:52
von jens
Ja, bei MySQLdb ist es das selbe mit den Bezeichnern... Irgendwie habe ist das aber auch nicht ganz verstanden, warum das anders gehandhabt wird. Was hat das für ein tieferen Sinn?

Zu dem "desc", selbst wenn es kein SQL nach irgendeinem Standard ist, sollte das DB Modul es an die DB schicken und das Ergebnis zurück liefern und das tut es ja auch. Ansonsten würde nicht die Meldung kommen:
DatabaseError: ORA-00900: invalid SQL statement

btw. bei MySQL geht das mit "SHOW CREATE TabellenName" (Wenn es ein äquivalent für desc ist. Hab keine Ahnung von Oracle...)

Verfasst: Mittwoch 6. Dezember 2006, 11:14
von BlackJack
jens hat geschrieben:Ja, bei MySQLdb ist es das selbe mit den Bezeichnern... Irgendwie habe ist das aber auch nicht ganz verstanden, warum das anders gehandhabt wird. Was hat das für ein tieferen Sinn?
Der tiefere Sinn, ist dass eine SQL-Anweisung von der Datenbank intern in ein optimiertes "Abfrageprogramm" übersetzt wird, das die Datenwerte als Argumente entgegennimmt. Die verwendeten Tabellen/Spalten haben Einfluss darauf, wie das übersetzte "Programm" aussieht, die Datenwerte aber nicht.

Man kann das gleiche "Programm" mit verschiedenen Werten aufrufen ohne neu übersetzen zu müssen, aber wenn eine andere Tabelle oder Spalte benutzt wird, dann muss man die SQL-Anweisung komplett neu übersetzen und optimieren.

Bei einer "vernünftigen" Datenbank-API werden die Daten auch nicht in die SQL-Anweisung eingefügt, sondern dort bleiben die Platzhalter drin und SQL-Anweisung und Daten werden getrennt an die Datenbank übermittelt. So spart man sich das einfügen und escapen, das beim Übersetzen der SQL-Anweisung ja wieder rückgängig gemacht werden muss. Und wie gesagt, wenn man die gleiche SQL-Anweisung für viele Werte benutzen will (`cursor.executemany()`), muss das "Programm" nur einmal erstellt werden und kann nacheinander mit allen Werten ausgeführt werden.