PDA

View Full Version : SQL ... where feld in(:invar)



Seiten : [1] 2

Robi
27-06-12, 10:24
Hi,

SQLRPGLE, V7R1

ich habe eine Variable inVar, char 100 und eine Datei mit einem Feld FELD Numerisch 3

wenn ich inVar mit '100' fülle und


C*EXEC SQL
C* SET :C =(SELECT COUNT(*) FROM DATEI
C* WHERE KEY1 = 9000000 AND FELD IN(:inVar))
C*END-EXEC

ausführe bekomme ich eine Zahl.

fülle ich inVar mit '100, 124' bekomme ich einen Fehler
cpd4374 und sql0302, code 6, Ungültige numerische Daten


1. Warum
2. gibt es alternativen

Danke
Robi

Fuerchau
27-06-12, 10:29
Auch dieses Thema hatten wir schon mehrfach. Die Syntax laut SQL ist ja:

in (V1, V2, ...)

Mit Variablen eben dann:

in(: V1, : V2, ...)

Dein Ansatz geht so halt nicht.
Außerdem solltest du den Feldtyp der Vergleichsvariablen anpassen, damit kein casting provoziert wird.

Alternative 1:

Mehrere Variablen (max. soviel wie benötigt) und ggf. Init mit einem nicht vorhandenen Wert (*loval).

Alternative 2:

Dynamischen SQL mit Cursor from Statement, Prepare, Open, Fetch, Close.

B.Hauser
27-06-12, 10:33
Das kannst Du so nicht machen!
Du musst entweder für jedes Element in der IN-Anweisung eine Hostvariable angeben oder dynamisches SQL verwenden.

Alternativ geht aber auch so was:


/Free
MyString = 'Value1' + ', ' + Value2 + ', ' + ... 'ValueN' + ', ';

Exec SQL Declare Cursor ... For
Select ...
From ...
Where :MyString Like '%' concat Trim(MyColumn) concat ', %'
...
/End-Free

Performancemäßig musst Du allerdings prüfen wie sich das Ganze verhält. Könnte in einem Table Scan enden.

Birgitta

Robi
27-06-12, 10:47
@beide

Ich dachte halt, ich könnte das System überlisten.
ca. 30 Variablen definieren... hm, nicht wirlich.

Hab nun dynamisches sql drin. geht auch. Sind halt nur mehr Zeilen code.

Schade eingentlich.

Danke
Robi

malzusrex
27-06-12, 11:18
@beide

Sind halt nur mehr Zeilen code.

Schade eingentlich.

Danke
Robi

Es gab mal Zeiten, da war jede Zeile Code bares Geld
;)

Robi
27-06-12, 11:31
Einige Zeilen mehr, die der lesbarkeit dienen, sind immer willkommen. Kommentare die das Problem beschreiben und nicht den RPG Befehl

C key chain datei datei lesen

sind auch gewünscht.

aber SQL im RPG, erst recht ohne /free, und das wilde zusammenbasteln des Strings verunstalten machmal eine Source.
Das versuchen wir zu vermeiden.

Chris.jan
28-06-12, 08:15
30 Variablen? Warum so kompliziert.
Das sind doch Werte die man einfach in eine Datei schreiben kann und dann mit einem JOIN verknüpfen kann.

Robi
28-06-12, 08:46
Ja Natürlich.
Nur wirds dann noch komplizierte und langsamer.

Die Werte werden erst zur Laufzeit bekannt und sind fast immer anders.
Ich müßte also in Lauf 1 die Datei mit den Werten erzeugen und in Lauf 2 hoffen das sie noch gelten (ok, das ist warscheinlich in 99,99 % der Fälle so)

In meinem Bsp.: (So gehts halt nur nicht)
eval invar = '100'
:loop bis ...
sql
verarbeitung
eval invar = %trim(invar) + ', ' + char(Feld
)
endloop

Robi

Chris.jan
28-06-12, 09:36
Ein select where in() ist mit Sicherheit nicht schneller als ein Join. Notfalls richtet man noch nen dauerhaften Index ein, wenn man das Ganze zusätzlich beschleunigen will.
Aber von außen ist es auch schwer da eine Einschätzung zu machen was da jetzt kompliziert ist oder nicht und wo man da den besten Lösungsansatz vornimmt.
Wohlmöglich sollte man der Datenbank einfach einen fertigen Wert verpassen, damit das Count obsolete wird. Das ist meist noch am besten für die Performance.

Fuerchau
28-06-12, 10:35
Ein IN(...) mit Konstanten statt "Select" ist sicherlich schneller als ein Join, der ja einen zusätzlichen Zugriff bedeutet.