PL/SQL-Befehle ausführen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
JustusJonas
User
Beiträge: 4
Registriert: Donnerstag 16. März 2017, 11:18

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!
JustusJonas
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:

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;
Ich hoffe es ist jetzt etwas verständlicher geworden.
Zuletzt geändert von Anonymous am Donnerstag 16. März 2017, 16:50, insgesamt 1-mal geändert.
Grund: Quelltext in Codebox-Tags gesetzt.
BlackJack

@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.
JustusJonas
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:
"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';")
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.
BlackJack

@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.
JustusJonas
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:

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;
jedoch nicht ausführen:

Code: Alles auswählen

execute neue_einheit('sdf', 'fds');
Fehlermeldung:
ORA-00900: Ungültige SQL-Anweisung
Sowohl das Erstellen(alles in einer Zeile geschrieben), als auch das Ausführen erfolgt mit

Code: Alles auswählen

cursor.execute(command)
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:

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;
Die Ausführung natürlich wieder in einer Zeile und mittels 'execute'.

Ehrlich gesagt, verwirrt mich das alles etwas :K ...
BlackJack

@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`‽
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

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.
JustusJonas hat geschrieben:Eine Sache, die mir jetzt noch Schwierigkeiten macht sind Prozeduren. Ich kann sie zwar erstellen:
[...]
jedoch nicht ausführen: [...]

Code: Alles auswählen

execute neue_einheit('sdf', 'fds');
Fehlermeldung:
ORA-00900: Ungültige SQL-Anweisung
Sowohl das Erstellen(alles in einer Zeile geschrieben), als auch das Ausführen erfolgt mit

Code: Alles auswählen

cursor.execute(command)
Eexecute ist kein PLSQL Befehl. Das könntest du so also z.B. auch nicht in einen Prozedur Body schreiben.
Folgendes würde funktionieren.

Code: Alles auswählen

BEGIN
    neue_einheit('sdf', 'fds');
END;
BlackJack's Alternative mit `callproc()` sollte jedoch die bevorzugte Methode sein.
JustusJonas 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.
Bei Prozeduren schreibt man die Deklarationen zwischen und

Code: Alles auswählen

BEGIN
bzw. zwischen und

Code: Alles auswählen

BEGIN
; 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
Antworten