PDA

View Full Version : %UCS2



KM
15-01-10, 12:04
Hallo,

wir haben folgende Konstellation:

-> Datenbankdatei mit CCSID 65535 (wegen Mehrsprachigkeit)
-> Job-CCSID 1153
-> RPG-Statement: kdname2 = %UCS2(kdname1:13488)

Im Debug hab ich jetzt verfolgt, dass durch die Built-In Funktion %UCS2 nicht wie erwartet die polnischen Zeichen nach Unicode konvertiert werden, sondern die Zeichen der Codepage 1141, die demselben Hex-Wert entsprechen. Das war im Debug eindeutig zu erkennen.

Ist es hier nicht so, dass die Job-CCSID als Basis für die Konvertierung genommen wird? Woher holt sich die Funktion %UCS2 die Ursprungs-CCSID?

Gruß,
KM

Fuerchau
15-01-10, 12:34
Da gibts ggf. verschiedene Ursachen.
- Default-CCSID des Job's (aus Sprache des Users bzw. QLANGID)
- CCSID der Source (DSPPGM->Module->5)

Fuerchau
15-01-10, 12:59
Im Programmierhandbuch (ab V5R2) habe ich noch einen Hinweis entdeckt, ggf. funktioniert dieser wie gewünscht:

kdname2 = %UCS2(kdname1:*JOBRUN)

KM
15-01-10, 14:00
Die Sache ist jetzt doch etwas komplizierter als ich dachte. Ich habe folgenden Ablauf:

PGM --> SRVPGM1 --> SRVPGM2

PGM übergibt Daten und eine CCSID als Parameter an eine Prozedur von SRVPGM1. Dieses reicht die Daten und die CCSID an eine Prozedur von SRVPGM2 weiter. Dort wird ein CHGJOB mit der übergebenen CCSID durchgeführt. Danach erfolgt der %UCS2.

Jetzt ist es so, dass beim ersten Aufruf offenbar alles passt. Wenn ich beim zweiten Aufruf eine andere CCSID übergebe, wird zwar auch der CHGJOB damit durchgeführt, jedoch wird diese "neue" CCSID dann nicht mehr beim %UCS2 berücksichtigt. Nach einem Signoff und Signon und erneutem Aufruf stimmen die Zeichen wieder.

Ich vermute jetzt mal, dass das irgendwie an der Aktivierung der Prozeduren liegt. Kann es sein, dass nach der Aktivierung einer Prozedur ein CHGJOB keine Auswirkungen mehr hat?

Gruß,
KM

Fuerchau
15-01-10, 14:32
Ich denke, %UCS2 ruft intern iconv() auf. Hierzu wird beim erstmaligen Aufruf die Codetabelle geladen.
Solange das Programm aktiv bleibt, ändert sich das dann wohl nicht mehr.

Alternativ verwende folgendes API:
Convert a Graphic Character String (CDRCVRT, QTQCVRT) API (http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/apis/CDRCVRT.htm)

Das kann das auch.

KM
15-01-10, 14:42
Es scheint tatsächlich an der Aktivierung zu liegen. Ich habe dem SRVPGM2 jetzt eine benannte Aktivierungsgruppe gegeben und mache jedesmal vor dem Aufruf der betreffenden Prozedur einen RCLACTGRP und damit funktioniert's. Aber das kann ja nicht so ganz Sinn der Sache sein.

Der iconv() funktioniert ohne Probleme. Das hatte ich schon probiert. Also scheint %UCS2 nicht unbedingt was mit iconv() zu tun zu haben.

Ich denke ich werde jetzt auf iconv() umsteigen, da ich hier längere Felder verwenden kann. UCS2 erlaubt unter V5R4 ja nur 16323 Stellen.

Gruß,
KM

Fuerchau
15-01-10, 15:11
Mittels iconv bildest du ja erst ein Handle um dann die Konvertierung durchzuführen.
Wenn du das Handle dann wieder freigibst, lädst du ja auch die Ressourcen später wieder neu.

%ucs2 merkt sich wohl das Handle nach dem 1. Aufruf und gibt es nicht mehr frei.

BenderD
15-01-10, 16:43
... die SQL Implementierung ist genauso lausig, da kann man zwar beliebig nach CCSID vor, zurück und drumherum casten, muss die CCSID aber zur Compiletime outen (bei static SQL). Da ist der iconv scheints besser, die Handle könnte man ja auch korrespondierend zu einem Array mit CCSIDs cachen.

D*B


Mittels iconv bildest du ja erst ein Handle um dann die Konvertierung durchzuführen.
Wenn du das Handle dann wieder freigibst, lädst du ja auch die Ressourcen später wieder neu.

%ucs2 merkt sich wohl das Handle nach dem 1. Aufruf und gibt es nicht mehr frei.

Fuerchau
15-01-10, 17:48
Bei ODP's (egal ob SQL oder Native) ist das ja wohl das selbe Problem.
Wenn ich zwischen Open und Close die CCSID ändere, hätte ich da auch plötzlich andere Daten.
Insbesonders wenn Daten geblockt werden ist die Codewandlung ja längst erfolgt.
Ausserdem hätte ich bei Parallelverarbeitung (SQL/Threads) ja auch noch unterschiedliche Daten, wenn mir ein Thread plötzlich die CCSID wechselt.

BenderD
15-01-10, 20:28
... das hat mit ODPs und Blockung (interessiert außerhalb des AS/400 Hühnergartens niemanden, innerhalb ist es wohl eines der spannendsten Themen - vielleicht ist das auch schon der Sumpf, der von unten an den Füßen zieht...) nicht die Bohne zu tun. Open und Close ist zur Runtime und die CCSID muss in diesem Fall zur Compiletime vernagelt werden!!! Am Rande sei zum Thema Threads vermerkt: SQL Anforderungen werden immer synchronized implementiert - jede SQL Anforderung muss so abgearbeitet werden, als ob sie in einem Thread verarbeitet worden wäre und sogar so, als ob der Benutzer die Datenbank für sich alleine gehabt hätte (aber auch das wird ja im AS/400 Umfeld zugunsten von vermuteten Performance Vorteilen durch das Prinzip Hoffnung ersetzt, siehe Threads zu FRCRATIO u.ä.)

D*B



Bei ODP's (egal ob SQL oder Native) ist das ja wohl das selbe Problem.
Wenn ich zwischen Open und Close die CCSID ändere, hätte ich da auch plötzlich andere Daten.
Insbesonders wenn Daten geblockt werden ist die Codewandlung ja längst erfolgt.
Ausserdem hätte ich bei Parallelverarbeitung (SQL/Threads) ja auch noch unterschiedliche Daten, wenn mir ein Thread plötzlich die CCSID wechselt.