PDA

View Full Version : SQL Stored Procedure mit Dateinamen in einer Variablen aufrufen



Seiten : [1] 2

Erol
16-04-20, 10:37
Liebe Gemeinde,
gibt es die Möglichkeit einen Dateinamen als Variable an eine Stored Procedure zu übergeben?
Die Stored Procedure soll ein Update auf die in der Variablen übergebenen Datei ausführen.

Das unten angegebene Beispiel soll mein Anliegen etwas verdeutlichen.

create or replace procedure LIB1.TEST (
in §LIB char(10) default(''),
in §FILE char(10),
in FELDA char(6) default(' '),
in FELDB char(30) default(' '))
Language sql
Deterministic
P1: begin
update §LIB / §FILE set FELDB = (select FELDC from FILE_z where FELDD = FELDA) ;
end P1 ;


call TEST ('LIB_x', 'FILE_y') ;

Gibt es vielleicht ein Repository mit vielen Beispielen von Stored Procedures?

Im Voraus vielen Dank für einige gute Tipps.

Fuerchau
16-04-20, 11:48
Leider sind Variablen als Lib und Table nie erlaubt.
Allerdings gibt es die Execute-Anweisung mit der ynmaische SQL's ausgeführt werden können.

Erol
16-04-20, 13:01
Vielen Dank für deine schnelle Antwort!
Hättest du vielleicht ein kleines Beispiel für ein dynamisches SQL mit Execute-Anweisung in der Stored Procedure?

Zur Not kann ich meine individuelle Datei auch immer mit demselben Namen in der QTEMP speichern, auf die die Stored Procedure dann das Update ausführt, aber eine variable lösung wäre natürlich eleganter. Die nicht angesprochenen, dann unterschiedlichen Felder interessieren die Stored Procedure vermutlich nicht.

Fuerchau
16-04-20, 20:11
So flexibelmuss eine Stored Procedure (SP) ja nicht sein.
Das Konzept dahinter ist ja, dass ich eine SP für eine bestimmte Aufgabe schreibe.
Wenn man also für verschiedene Objekte SP's braucht, so macht man für jedes Objekt eine SP.
Immerhin kostet eine SP "keinen Strom", wie es so schön heißt.

Und der Aufrufer ruft dann nicht
call AnyProc('MYLIB', 'MYTABLE', ...)
sondern
call MyLib.MyTableProc(...)

Konzeptionell ist das wesentlich klarer und auch sicherer.

Hier:
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/pdftable/pdftable.htm
findest du SQL-Reference und SQL-Programming Handbücher.
Die habe ich mir auch runtergeladen und da schaue ich immer wieder gerne rein.

B.Hauser
17-04-20, 06:39
Du machst das einfach mit dynamischem SQL, d.h. du bildest zur Laufzeit einen String mit dem kompletten SQL Statement und dann führst Du es mit EXECUTE IMMEDIATE aus.

Etwa so:


Create Or Replace Procedure LIB.TEST (In PARLIB Char(10) Default (''),
In PARFILE Char(10),
In PARFELDA Char(6) Default (' '),
In PARFELDB Char(30) Default (' '))
Language SQL
Deterministic
P1: Begin
Declare CmdSQL VarChar(1096) Not NULL Default '';

Set CmdSQL = 'Update ' concat Trim(ParLib) concat '/' concat Trim(ParFile) concat
' set ' concat Trim(ParFeldB) Concat
' = (Select FeldC
From File_Z
Where FeldD = ''' concat ParFeldA Concat ''')';
Execute Immediate CmdSQL;

End P1;

Noch ein paar kleine Anmerkungen.
1. Du solltest NIE Sonderzeichen in Deinem Source Code verwenden, da diese nicht immer international sind und dann auf anderen Maschinen Probleme bereiten können. Gerade das Paragraphen-Zeichen kann in der US-amerikanischen Umgebung nicht verwendet werden. In deren Zeichensatz steht an dieser stelle das @-Zeichen.

2. Du solltest eine Fehler-Prüfung einbauen.
Entweder über einen Handler oder zumindest über GET DIAGNOSTICS den SQLCODE (DB2_RETURNED_SQLCODE), SQLSTATUS (RETURNED_SQLSTATE)oder die Fehlermeldung (MESSAGE_TEXT) ermitteln.

Birgitta

BenderD
17-04-20, 07:13
... ohne errorhandler kommst du nicht bis zur Abfrage des SQLCODES.

D*B

ILEMax
17-04-20, 07:41
Oder du machst deine Version auf *curlib und rufst vorher ein cl, das als Parameter die Lib empfängt.
Parameter gefüllt, rette curlib, setze curlib
Parameter leer setze gerettete Curlib wieder ein.

nicht schön, aber immer richtig

Der ILEMax

Erol
17-04-20, 09:47
Super, vielen Dank für eure Beiträge!
Birgitta, die Set-Anweisung entspricht doch in etwa dem prepare im embedded SQL? Das ist genau, was ich gesucht habe.
Kann ich den Sqlcode einfach als out-Parameter definieren und ihn im aufrufenden Programm ggf. interpretieren?
Viele Grüße und ein schönes Wochenende

andreaspr@aon.at
17-04-20, 09:58
Die SET Anweisung ist lediglich die String zuordnung (wie EVAL im RPG).
Das Execute Immediate macht automatisch das Prepare.
Du kannst es aber auch in 2 Steps machen, zuerst ein Prepare und dann das Execute.
Der Vorteil beim Prepare ist, dass du das Statement öfters ausführen kannst, es aber nur 1 mal interpretiert (PREPARE) werden muss.
Außerdem kannst du dann auch beim Execute, mit Hilfe der USING Klausel, Hostvariablen verwenden und somit mit Parametermarkern arbeiten, was mehr Sicherheit in diversen Bereichen liefert.

lg Andreas

B.Hauser
17-04-20, 13:22
Die SET Anweisung ist lediglich die String zuordnung (wie EVAL im RPG).
Das Execute Immediate macht automatisch das Prepare.
Du kannst es aber auch in 2 Steps machen, zuerst ein Prepare und dann das Execute.
Der Vorteil beim Prepare ist, dass du das Statement öfters ausführen kannst, es aber nur 1 mal interpretiert (PREPARE) werden muss.
Außerdem kannst du dann auch beim Execute, mit Hilfe der USING Klausel, Hostvariablen verwenden und somit mit Parametermarkern arbeiten, was mehr Sicherheit in diversen Bereichen liefert.

lg Andreas

... allerdings sind wir da soweit wie vorher.
Auch in dynamischem SQL bzw. beim PREPARE und EXECUTE bzw. bei der Verwendung von Parameter Marken darf die Datei nicht als Variabler Wert gehandelt werden.
Deshalb muss in diesem Fall immer ein PREPARE und EXECUTE erfolgen (oder eben auch ein EXECUTE IMMEDIATE).