cx_Oracle problem mit parametern im execute befehl

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
z0mg
User
Beiträge: 4
Registriert: Dienstag 5. Dezember 2006, 21:07

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??
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.
z0mg
User
Beiträge: 4
Registriert: Dienstag 5. Dezember 2006, 21:07

ok, da kann ich mit leben das desc nicht geht.

gibt es sonst keinen weg auch bezeichner dynamisch in execute befehlen zu benutzen?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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...)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
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.
Antworten