Hallo zusammen,
ich suche eine Möglichkeit, um aus meinem Python-Programm heraus Skripte mit PL/SQL-Befehlen auszuführen. Ich verwende dabei eine Oracle-Datenbank.
Kann hierbei jemand helfen?
Vielen Dank!
PL/SQL-Befehle ausführen
-
- User
- Beiträge: 4
- Registriert: Donnerstag 16. März 2017, 11:18
Hallo BlackJack,
vielen Dank für deine schnelle Antwort. Die Methoden bringen mich aber leider nicht weiter. Mir geht es um das Ausführen von PL/SQL-Skripten/Blöcken, welche in der Regel folgende Form haben:
Ich hoffe es ist jetzt etwas verständlicher geworden.
vielen Dank für deine schnelle Antwort. Die Methoden bringen mich aber leider nicht weiter. Mir geht es um das Ausführen von PL/SQL-Skripten/Blöcken, welche in der Regel folgende Form haben:
Code: Alles auswählen
define name='Justus';
DECLARE
jahr NUMBER(1, 0);
CURSOR c IS SELECT * FROM tabelle;
BEGIN
OPEN c;
LOOP
FETCH c INTO ...
update ...
END LOOP;
CLOSE c;
END;
Zuletzt geändert von Anonymous am Donnerstag 16. März 2017, 16:50, insgesamt 1-mal geändert.
Grund: Quelltext in Codebox-Tags gesetzt.
Grund: Quelltext in Codebox-Tags gesetzt.
@JustusJonas: Wenn das mit `execute()` nicht geht, nach dem man das in einzelne Anweisungen aufgeteilt hat (in diesem Fall wohl zwei — ``define… ;`` und der Rest), dann vermute ich mal, dass das mit `cx_Oracle` nicht geht. Dann müsste man wahrscheinlich auf Kommandozeilenprogramme zurückgreifen die man von Python aus starten kann. Bei Oracle ist das IIRC SQL*Plus.
-
- User
- Beiträge: 4
- Registriert: Donnerstag 16. März 2017, 11:18
Mit 'cursor.execute' scheint es ein Stück weit zu funktionieren, sofern ich alle Befehle in eine Zeile schreibe und auf das 'define' verzichte. Auch wenn ich den 'define'-Befehl einzeln absetze wird er nicht erfolgreich ausgeführt. Ich erhalte dann die Fehlermeldung:
Hier sicherheitshalber noch der Befehl, welchen ich ausführe:
Führe ich den Befehl mit dem SQL-Developer aus bekomme ich keine Fehlermeldung.
Auf SQL-Plus würde ich an der Stelle sehr gerne verzichten.
"Fehlermeldung: ORA-00900: Ungültige SQL-Anweisung".
Hier sicherheitshalber noch der Befehl, welchen ich ausführe:
Code: Alles auswählen
cursor.execute("define v_name='Justus';")
Auf SQL-Plus würde ich an der Stelle sehr gerne verzichten.
@JustusJonas: DEFINE ist undefiniert. Soweit ich das im Netz verstanden habe ist das etwas was SQL*Plus versteht und SQL-Developer nur in einem bestimmten (COMMAND-)Fenster. Das gehört also wohl nicht zu PL/SQL sondern ist etwas von diesen Programmen. Das Syntaxhighlighting hier im Forum färbt DEFINE auch nicht ein.
-
- User
- Beiträge: 4
- Registriert: Donnerstag 16. März 2017, 11:18
Da hast du wohl recht. Ich konnte die define-Anweisungen aus den Skripten jetzt anderweitig umsetzen. Eine Sache, die mir jetzt noch Schwierigkeiten macht sind Prozeduren. Ich kann sie zwar erstellen:
jedoch nicht ausführen:
Fehlermeldung:
Ein weiteres Problem habe ich, sobald ich in der Prozedur Variablen mit 'DECLARE' definieren möchte. Hier erhalte ich jedoch keine Fehlermeldung. Die gesamte Anweisung scheint daraufhin ignoriert zu werden.
Bei einem PL/SQL Block an sich kann ich mit der DECLARE-Anweisung jedoch arbeiten:
Die Ausführung natürlich wieder in einer Zeile und mittels 'execute'.
Ehrlich gesagt, verwirrt mich das alles etwas :K ...
Code: Alles auswählen
CREATE OR REPLACE PROCEDURE neue_einheit (p_einheit_kurz in varchar2, p_bezeichnung in varchar2) AS
BEGIN
INSERT INTO einheit (einheit_kurz, bezeichnung) VALUES (p_einheit_kurz, p_bezeichnung);
END;
Code: Alles auswählen
execute neue_einheit('sdf', 'fds');
Sowohl das Erstellen(alles in einer Zeile geschrieben), als auch das Ausführen erfolgt mitORA-00900: Ungültige SQL-Anweisung
Code: Alles auswählen
cursor.execute(command)
Bei einem PL/SQL Block an sich kann ich mit der DECLARE-Anweisung jedoch arbeiten:
Code: Alles auswählen
DECLARE
tab_count int := 0;
BEGIN
select count(*) into tab_count from all_tables where OWNER = 'ANGABE' and table_name = 'EINHEIT';
if tab_count > 0 then
execute immediate 'DROP TABLE ' || 'EINHEIT';
end if;
END;
Ehrlich gesagt, verwirrt mich das alles etwas :K ...
@JustusJonas: Na für Prozeduren müsste doch dann aber `Cursor.callproc()` das richtige sein.
Ich finde das alles auch etwas verwirrend, weil's halt kein SQL ist.
Da das sowieso alles nicht portabel ist, gibt es vielleicht auch ein anderes Modul als `cx_Oracle`‽
Ich finde das alles auch etwas verwirrend, weil's halt kein SQL ist.

Hallo Justus,
Zeige doch bitte den Code den du tatsächlich ausführst. BlackJack hatte schon darauf hingewiesen, dass Oracle keine SQLPlus Eigenheiten versteht. Ggf. könnte es sich also als sinnvoll erweisen, wenn du zuerst nach der entsprechenden PLSQL Variante zu den Befehlen suchst, die du verwendest. Insbesondere wenn du wie in deinem Fall tatsächlich eine sprechende Fehlermeldung bekommt, die dich darauf hinweist, dass du einen unbekannten/ungültigen Befehl verwendest.
Folgendes würde funktionieren.
BlackJack's Alternative mit `callproc()` sollte jedoch die bevorzugte Methode sein.
und bzw. zwischen und ; Je nachdem welches der gleichwertigen Schlüsselwörter du verwendest.
Ich würde dir nahelegen deine Funktionen und Prozeduren in separaten SQL Dateien abzulegen und diese mit SQLPlus einzuspielen oder ggf. per Copy&Paste mit dem SQLDeveloper. Mit dem richtigen Editor hast du dann auch vernünftiges Syntax Highlighting und du brauchst dich nicht um Escaping zu kümmern.
Als kleiner Tipp, da du mit unteschiedlichen Tools arbeitest: Die Arten wie Statements und PLSQL Blöcke abgeschlossen werden unterscheiden sich. Bei SQLPlus z.B. schließt man Befehle mit Semikolon ab und Blöcke mit Semikolon und Backslash. Bei anderen Tools bekommst du damit eine Fehlermeldung.
Boa
Zeige doch bitte den Code den du tatsächlich ausführst. BlackJack hatte schon darauf hingewiesen, dass Oracle keine SQLPlus Eigenheiten versteht. Ggf. könnte es sich also als sinnvoll erweisen, wenn du zuerst nach der entsprechenden PLSQL Variante zu den Befehlen suchst, die du verwendest. Insbesondere wenn du wie in deinem Fall tatsächlich eine sprechende Fehlermeldung bekommt, die dich darauf hinweist, dass du einen unbekannten/ungültigen Befehl verwendest.
Eexecute ist kein PLSQL Befehl. Das könntest du so also z.B. auch nicht in einen Prozedur Body schreiben.JustusJonas hat geschrieben:Eine Sache, die mir jetzt noch Schwierigkeiten macht sind Prozeduren. Ich kann sie zwar erstellen:
[...]
jedoch nicht ausführen: [...]Fehlermeldung:Code: Alles auswählen
execute neue_einheit('sdf', 'fds');
Sowohl das Erstellen(alles in einer Zeile geschrieben), als auch das Ausführen erfolgt mitORA-00900: Ungültige SQL-AnweisungCode: Alles auswählen
cursor.execute(command)
Folgendes würde funktionieren.
Code: Alles auswählen
BEGIN
neue_einheit('sdf', 'fds');
END;
Bei Prozeduren schreibt man die Deklarationen zwischenJustusJonas hat geschrieben: Ein weiteres Problem habe ich, sobald ich in der Prozedur Variablen mit 'DECLARE' definieren möchte. Hier erhalte ich jedoch keine Fehlermeldung. Die gesamte Anweisung scheint daraufhin ignoriert zu werden.
Code: Alles auswählen
IS
Code: Alles auswählen
BEGIN
Code: Alles auswählen
AS
Code: Alles auswählen
BEGIN
Ich würde dir nahelegen deine Funktionen und Prozeduren in separaten SQL Dateien abzulegen und diese mit SQLPlus einzuspielen oder ggf. per Copy&Paste mit dem SQLDeveloper. Mit dem richtigen Editor hast du dann auch vernünftiges Syntax Highlighting und du brauchst dich nicht um Escaping zu kümmern.
Als kleiner Tipp, da du mit unteschiedlichen Tools arbeitest: Die Arten wie Statements und PLSQL Blöcke abgeschlossen werden unterscheiden sich. Bei SQLPlus z.B. schließt man Befehle mit Semikolon ab und Blöcke mit Semikolon und Backslash. Bei anderen Tools bekommst du damit eine Fehlermeldung.
Boa