Anmelden

View Full Version : SQL mit variablen Tabellennamen



Seiten : [1] 2

THH
16-10-06, 10:55
Hallo Zusammen.

Ich habe da mal nen Problem für SQL
Spezialisten.

Ich habe ein RPG-Rprogramm ILE(nicht freiformat)

muss nun verschiedene Selects
auf verschiedene Tabellen machen

Problem ist, die Tabellen haben alle eine
unterschiedliche endung (xxx06 xxx07 xxx08 usw) des weiteren ligen sie auch noch in verschiedenen Bibliotheken.

wie bekomme ich nun ein statment
(select * from xxx where -----) wobei
xxx jeweils eine andere Tabelle sein kann
also ein variables select *

für schnelle hilfe währe ich dankbar

thomas

GraueEminenz
16-10-06, 11:23
Hallo.

So spontan fällt mir da folgendes ein:

Den Tabellenname als Parameter an das Programm
übergeben.

Im Programm mittel Zeichkettenverarbeitung
den SQL-Ausdruck wie gewünscht zusammen daddeln
und mittel QCMDEXEC ein Runsqlstm durchführen.

MfG
GraueEminenz

B.Hauser
16-10-06, 12:11
Hallo,

Wenn Dateien/Tabellen variabel gehandelt werden sollen gibt es zwei Möglichkeiten:

1. Statisches SQL verwenden und die benötigten Dateien mittels OVRDBF überschreiben. Die überschriebenen Dateien dann im SQL Statement verwenden.

2. Das SQL-Statement wird zu Laufzeit als String zusammengestellt und mit PREPARE in ein ausführbares SQL-Statement konvertiert.
Wenn Du mit einem SELECT-Statement arbeitest, muss Du einen Cursor verwenden.

Beispiel: (Es ist egal, ob die RPG-Statments im Free-Format oder nicht geschrieben sind. Die SQL-Statements könnten sogar in RPGIII-Code eingebunden werden!)



StringSQL = 'Select * from ' + LibFile +
' Where Feld1 = ''' + MyVar1 + ''' and Feld2 = ' + MyVar2 +
' For Read Only';
/End-Free
C/Exec SQL Prepare PrepSQL from :StringSQL
C/End-Exec

C/Exec SQL Declare CsrC1 Cursor For PrepSQL
C/End-Exec

C/Exec SQL Open CsrC1
C/End-Exec

C Do *HiVal
C/Exec SQL Fetch next from CsrC1 into :MyDS
C/End-Exec
/Free
If SQLCod = 100; //Datei-Ende
Leave;
Endif;
If SQLCod < *Zeros; //Fehler
//Fehler-Handling
EndIf;
// Weitere Verarbeitung
EndDo;
/End-Free
C/EXEC SQL Close CsrC1;
C/END-EXEC


Sollten die Tabellen unterschieldlichen Aufbau haben, wird das Ganze um einiges komplizierter, d.h. es muss mit einer Descriptor-Area gearbeitet werden.

@Graue Eminenz
Select-Statements kannst Du nicht mit RUNSQLSTM verarbeiten, sondern nur Befehle wie Insert, Update, Delete aber auch Create Table u.a.

Birgitta

Squall
18-10-06, 17:03
Hallo,

ich habe heute auch versucht mit dynamischen SQL zu arbeiten. Bekomme jedoch den Fehler 501 (Cursor beim Fetch geschlossen).

Mein Code:

Wird dem Programm übergeben: SQLSTM = 'Select * from LIB/Tab'

C/EXEC SQL
C+ Prepare MyStmt from :SQLSTM
C/End-Exec

C/EXEC SQL
C+ Declare MyCsr Cursor for MyStmt
C/END-EXEC

C/EXEC SQL
C+ Open MyCsr
C/END-EXEC
C
C/EXEC SQL
C+ Fetch MyCsr
C+ into :FLD1,
C+ :FLD2,
C+ :FLD3
C/END-EXEC

Die Felder stimmen so. Schleife etc muss hierbei nicht beachtet werden, da es nur ein Ausschnitt meines Codes ist.

Gruß Martin

Fuerchau
18-10-06, 18:21
Schau dir nach dem Open den SQLCOD an.
ggf. steht beim Create Programm das Naming aud *SQL dann musst du "LIB.TABLE" statt "LIB/TABLE" kodieren.

B.Hauser
19-10-06, 06:23
Hallo,

der SQLCOD/SQLCODE oder der SQLSTT/SQLSTATE sollte nach jedem SQL-Statement geprüft werden. (Das hatte ich der Einfachheit halber in meinem Beispiel weggelassen)
Gerade bei dynamischem SQL kann es leicht passieren, das die Syntax nicht stimmt. Dann würde schon das Prepare-Statement scheitern.

Was welcher SQL-Code bedeutet kann relativ einfach ermittelt werden:
Alle SQL-Nachrichten sind in der Nachrichten-Datei QSQLMSG hinterlegt. Die Message-Id setzt sich zusammen aus SQL + Absolut-Wert des SQL-Codes, z.B. -204 --> SQL0204.

Für weitere Informationen würde ich Dir empfehlen doch mal die Online-Bibliothek zu konsultieren.
In den folgenden Redbooks findest Du einiges an Beispiel-Codes und auch relativ einfache und gute Erklärungen zu dem Thema Embedded SQL.
Who Knew You Could Do That with RPG IV? A Sorcerer's Guide to System Access and More
(http://www.redbooks.ibm.com/abstracts/sg245402.html?Open)
Modernizing IBM eServer iSeries Application Data Access - A Roadmap Cornerstone (http://www.redbooks.ibm.com/abstracts/sg246393.html?Open)

Ansonsten findest Du noch Beispiele in:
Embedded SQL Programming (http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/rzajp/rzajp.pdf)

Noch eine allgemein Anmerkung:
Host-Variablen sollten niemals mit SQL, SQ, RDI oder DSN beginnen. Diese Variablen sind für den Datenbanken-Manager reserviert. Selbst wenn heute noch keine Probleme auftreten, kann in einem zukünftigen Release IBM eine Variable mit einem Namen, der bereits als Hostvariable definiert wurde, verwenden. Im besten Fall stürzt das Programm ab. Im schlimmsten Fall werden wichtige Werte überschrieben und kein Mensch kann sich erklären was passiert ist.

Birgitta

Squall
19-10-06, 08:18
Hallo,

ja es findet schon beim Prepare ein Fehler statt.


Nachrichten-ID . . . . . . . : SQL0311
Nachrichtendatei . . . . . . : QSQLMSG
Bibliothek . . . . . . . . : QSYS
Nachrichtentext . . . . . . : Länge einer Host-Variablen variabler Länge oder
einer LOB-Host-Variablen ungültig.

Aber ist jetzt mein SQLSTM(jetzt STMSQL ^^) zu lang?
D STMSQL 1024A varying

Eine andere Variable wird ja im Prepare nicht benutzt.

Gruß Martin

Fuerchau
19-10-06, 08:33
Prüfe genau den Inhalt deiner Variablen STMSQL (ggf. hex, dann wird auch das Längenattribut angezeigt), ggf. lass besser das varying weg.

Squall
19-10-06, 08:44
Es lag scheinbar am varying. Aber meinen Qualifizierten Namen mag er nicht. Entweder SQL5016(Qualifizierter Objektname &1 nicht gültig.): LIB.FILE
oder SQLCOD0104(Token &1 ungültig. Gültige Token: &2.) bei LIB/FILE oder nur FILE.

Gibt es noch andere Zusammensetzungsmöglichkeiten?

Gruß Martin

Fuerchau
19-10-06, 09:18
Schau dir den String mal genau (auch HEX) an. Vielleicht enthält dein STMSQL ja irgendwo ungültige Zeichen, ansonsten kann ich mir das nicht erklären.

Ggf. ist das auch VARPG-spezifisch, dass nicht mit mehreren LIB's umgegangen werden kann.
In diesem Fall musst du OVRDBF's (per CALL) absetzen und ohne Qualifizierung arbeiten.