PDA

View Full Version : SQL-replace auf Host-Variable



Schacht6
16-04-19, 17:13
Hallo Ihr Wissenden,

ich möchte in einem RPG-PGM mit einem prepared statement ein Dateifeld (Typ String) updaten.

Zum Ausführungszeitpunkt soll das "where"-Feld dann noch quasi "normalisiert" werden (Dadurch soll Groß/Kleinschreibung irrelevant werden, und bestimmt Zeichen sollen zum Vergleichszeitpunkt ersetzt werden).

Nun das Problem:
Unten seht ihr drei austauschbare Zeilen zum "where"-Teil des Statements.
In der ersten mein Versuch, in der Hostvariablen ein mögliches P durch ein L zu ersetzen zum Vergleichszeitpunkt. Das führt blöderweise zu einem SQL-Error "-518". Hm.

Aber:
In der zweiten Zeile ist beweisen, dass man eine Host- Variable grundsätzlich zum Vergleichszeitpunkt manipulieren kann; Das Statement funktioniert.
Und in der dritten Zeile ist bewiesen, dass man grundsätzlich zum Vergleichszeitpunkt den zu vergleichenden Wert replacen kann (Allerdings habe ich dabei keine Hostvariable verwendet, sondern eine normale, also kein prepSt).

Wenn das beides geht, warum funktioniert dann das prep.St in Zeile 1 nicht?

stmt= 'update myFile set MyField= ''X'' where +
MyField = replace(? , ''P'', ''L'') '; // 1. <-Geht nicht. Wieso -518?

// MyField = upper(?) '; // 2. <-Geht. Man kann also Host-Var's verändern

// MyField = replace(''P'' , ''P'', ''L'')'; // 3. <-Geht. Replace
funktioniert grundsätzlich,
solange keine Host-Var.
Exec sql prepare s1 from :stmt;
Exec sql execute s1 using :statusP;


Ich würde es gern verstehen, habt ihr dafür eine Erklärung?

Besten Dank schon mal,
Andy

Fuerchau
17-04-19, 08:00
Ganz einfach, schon mal was von Hostvariablen gehört;-)?

exec sql set : MyField = upper(: MyField);

Bei Replace(?,....) weiß SQL nichts über den Typ zur Ausführung. Man kann allerding "cast(? as char(10))" in einem dynamischen SQL verwenden.
Und warum machst du das Ganze überhaupt dynamisch?

exec sql update myfile set myfield = replace(: MyField, 'P', 'L')
where myfield = upper(: MyField);

Du kannst auch die Parameter P und L wiederum in Hostvariablen setzen.

Schacht6
17-04-19, 16:11
Ok, recht vielen Dank

ExAzubi
23-04-19, 13:08
Versteh auch nicht, warum eine HostVariable mit SQL geändert werden soll. Da kann man im RPG doch auch die BiF %REPLACE() benutzen?!

Fuerchau
23-04-19, 13:40
Da es da einen kleinen Unterschied gibt:

%REPLACE(replacement string: source string{:start position {:source
length to replace}}

%REPLACE returns the character string produced by inserting a replacement string into the source string,
starting at the start position and replacing the specified number of characters.

Du meinst da wohl eher diese Funktion:

%SCANRPL(scan string : replacement : source { : scan start { : scan length } )

%SCANRPL returns the string produced by replacing all occurrences of the scan string in the source
string with the replacement string. The search for the scan string starts at the scan start position and
continues for the scan length. The parts of the source string that are outside the range specified by the
scan start position and the scan length are included in the result.

Die aber erst ab irgend einem Release kam.
Des weiteren kommt es immer auf den Einsatz an. Wenn ichmit SQL mischen muss, nehme ich doch gleich SQL, da das Ergebnis einer Bif erst in eine Variable muss.

ExAzubi
23-04-19, 14:56
Ja ich meinte natürlich %SCANRPL verwechselte ich auch immer in der Implementierung :) :o
Welche übringens mit V7R1 Einzug hielt...

Ich gebe dir Recht Fuerchau, wenn es im SQL geht dann mach es auch da, aber da hier in dem Bsp eine Hostvariable geändert werden soll, kann ich das auch gleich im RPG machen und dann anschließend die in dem SQL Statements weiter zu nutzen.

Fuerchau
23-04-19, 14:59
Wich ich schon sagte: Betrachte das Gesamtkonstrukt.
In diesem Fall braucht man weder eine zusätzliche Variable noch dynamisches SQL:

exec sql update myfile set myfield = replace(: MyField, 'P', 'L')
where myfield = upper(: MyField);

was den (relativ hohen) Aufwand des vorherigen Konstrukts vereinfachte.