Anmelden

View Full Version : SQL fehler im CAST



Seiten : [1] 2

ILEMax
25-08-09, 17:01
Hallo,
was ist falsch ?

embeded SQL



eval stmt = "SELECT COUNT(*) FROM datei WHERE numf1 = 2126646 AND alpa1 <> '2128929' AND numf2 IN(17, 30, 97)"
/exec sql
c+ set :cntr = (
c+ :stmt
c+ )
c/end-exex

numf1 ist gepackt 7 0
alpa1 ist 7 A
nunf2 ist gepackt 3 0

cntr ist 5s0 und auch schon 5P0 definiert


Fehler zur Laufzeit

SQL0420, Zeichen in CAST-Argument ungültig.

ich hab keine Idee mehr
Danke
Max

Fuerchau
25-08-09, 17:09
Ich weiß ja nicht wass dein "set" hier bewirken soll, ein Select wird da nicht ausgeführt sondern eine Zuweisung.

Das mach eigentlich der
eval cntr = stmt;

Vielleicht wird jetzt klar wieso SQL0420 ?
Eine Zuweisung Alpha nach Numerisch geht nicht ohne cast.

Wenn du allerdings den "Select" ausführen willst, dann musst du folgendes codieren:

exec sql
SELECT COUNT(*) into : cntr
FROM datei WHERE numf1 = 2126646 AND alpa1 <> '2128929' AND numf2 IN(17, 30, 97);

Du bemerkst den Unterschied ;) ?

ILEMax
25-08-09, 17:37
mit der Erklärung : ja


Das Prob. ist ich brauch die Eierlegende Wollmilchsau.

Hier wird RPT programmiert, was leider kein SQL erlaubt (RPTSQL gibt es nicht)

Es ist auch (fast) kein ILE möglich.
also wollt ich den SQL-Befehl einfach übergeben.

das

SELECT COUNT(*) INTO :CNTR
FROM :STMT geht nämlich auch nicht.

Noch ne idee ?
Max

Fuerchau
25-08-09, 17:42
Dann wirds etwas komplizierter.
Übergebe den "select count(*) from datei", mach einen "prepare", und "execute", dann kannst du einen Cursor mit dem Statement deklarieren, diesen öffnen und per "fetch ... into ..." lesen.
Anschließend noch "close" und "drop statement".

Den genauen Vorgang musst du bitte im SQL-Programmierhandbuch nachlesen, für das Forum ist das zuviel (es sei denn es findet sich jemand).

B.Hauser
25-08-09, 20:48
Hallo,

SELECT ... INTO wird im dynamischen SQL ebensowenig unterstützt wie SET + Select-Statement!
Was jedoch untertützt wird ist VALUES INTO!



String = 'Values(Select Count(*) from ' + %Trim(Stmt) +') Into ?';
Exec SQL Prepare MySQL from :String;
Exec SQL Execute MySQL using :Anzahl;


String ist ein alphanumerisches Feld (z.B. 1024A Varying).
Anzahl ist eine ganzzahlige Variable (z.B. 10I 0).

Birgitta

ILEMax
26-08-09, 08:16
Super Birgitta !!
Du bist genial

so geht es, danke

Gruß
ILEMax

tarkusch
26-04-19, 21:26
Hallo,

ich kann mein Sql mit STRSQL absetzen ohne Fehlermeldung:




SELECT
TBL1CDE AS CDE, // 16 A
TBL1FO# AS FO#, // 5, 0
TBL1TNR AS TNR, // 16 A
TBL1MEN AS MEN, // 5, 2
case when ifnull((select ART2BEZ from ART2P
where TBL1IMP = PETIMP
AND TBL1TNR = PETTNR ), TBL1BEZ) = ' '
then (select ARTBZ1 FROM ART1P where TBL1TNR = ARTNR)
else ifnull((select ARTBZ2 from ART2P
where TBL1IMP = PETIMP
AND TBL1TNR = PETTNR) , TBL1BEZ)
end as BEZ // 40 A
FROM TABLE1 A INNER JOIN TABLE2
ON TBL1CDE = TBL2ACD)

select CDE, FO#, TNR, BEZ, MEN
from x
ORDER BY CDE, FO#




Wenn ich es im RPG-Programm umsetze bekomme ich die Fehlermeldung:


Sqlcode= -420 Sqlstate= 22018; Zeichen in CAST-Argument ungültig.


ich fetche das in eine Datenstruktur:


D SqlRs_Sfl1...
D DS INZ Qualified
D CDE LIKE(TBL1CDE)
D FO# LIKE(TBL1FO#)
D TNR LIKE(TBL1TNR)
D MEN LIKE(TBL1MEN)
D BEZ LIKE(ARTBZ1)


Ich habe in der Datenbank auch nachgesehen ob korrupte Daten vorhanden sind aber es schaut alles ok aus.
Was kann ich noch probieren?
Alles mit IFNULL versehen habe ich schon ausprobiert.

Wenn ich eine Tempfile aus der Abfrage erstelle (create table qtemp/test1 as( ..) with data)
sehe ich das die Definitionen auch korrekt angegeben wurden:


Feld Datei Art Länge Skala
CDE TEST1 CHARACTER 16
FO# TEST1 DECIMAL 5
TNR TEST1 CHARACTER 16
BEZ TEST1 CHARACTER 40
MEN TEST1 DECIMAL 5 2


Lg

Fuerchau
27-04-19, 09:04
Starte mal den DEBUG-Mode, dann wird der CAST-Fehler meist im Joblog ausgewiesen.
Schuld ist der Autocast. D.h., in einer der Where- oder Joinklauseln muss eine Typanpassung erfolgen, die dann aber nicht passt.

Dein Case-Konstrukt kann auch vereinfacht werden:

coalesce( (select ......), (Select .....), (Select .....) )

Coalesce nimmt den ersten Wert, der nicht NULL ist.
Noch besser und effektiver wäre, wenn du die 3 Selects per Left join anhängst und dann per Coalesce auswählst:

coalesce(t1.Art2bez, t2.ArtBez, ...)
:
left join art2p t1 ...
left join xxx t2 ...

Dies könnte sogar performanter sein, auf jeden Fall übersichtlicher.

tarkusch
27-04-19, 11:39
Leider hatte ich Debug-Modus eh vorher schon probiert aber da kann ich leider keinen Hinweis finden:


RPG-PGM:
Der Zugriffsplan der Abfrage wurde erneut erstellt.
****: Debug-Nachrichten für Abfrage werden beendet.
ODP erstellt.
Blockung für Abfrage.
Cursor SQLCSR eröffnet.
Anweisung GET DIAGNOSTICS beendet.
Zeichen in CAST-Argument ungültig.
Schritt in Zeile 1168 beendet.

STRSQL:
****: Debug-Nachrichten für Abfrage werden beendet.
ODP erstellt.
Blockung für Abfrage.
Verbindung zur relationalen Datenbank DEGRPA50 beendet.
SQL-Cursor geschlossen.



Das mit dem coalesce hätte ich schon im Hinterkopf.
Meine Anforderung war das ich folgenden RPG-Code als Sql-Statement abbilden wollte:




FILE: ART1P ART2P ART3P
FELD: ARTBZ1 ARTBZ2 ARTBZ3
READ ART1P


CHAIN KEY3 ART3P;
*IN50 = NOT %FOUND;
IF *IN50;
ARTBZ3 = *BLANKS;
else;
ARTBZ1 = ARTBZ3;
endif;
if ARTBZ1 = *blanks;
chain tnr ART2P;
if %found(ART2P);
ARTBZ1 = ARTBZ2;
endif;
endif;


Inhalt von ARTBZ1 wird dem Bildschirmfile zugewiesen

Hier habe ich das nur mit dem Case-Konstruct hingebracht.

Fuerchau
27-04-19, 14:19
Drück mal auf der Meldung "Zeichen in cast ungültig" auf F1 um die Details zur Meldung anzusehen.
Manuell ist es schon aufwändig den cast zu entdecken.
Dazu musst du alle Ausprägungen der Where und On-Klauseln prüfen. Irgendwo gibt es da einen Wechsel von Zeichen auf Numerisch.

Nun, dein Chain entspricht dem Left Join, die Feldauswahl dann dem COALESCE.