因此,我尝试在 AS400 RPG 中开发一个函数,该函数接收 4 个字符串参数,使用 DB2 XMLSERIALIZE 使用所述参数构建 XML 标头,并以字符串形式返回该标头。当我使用 RPG 变量时,返回字符串在标记值中显示不同的字符。我认为问题可能出在字符编码上,但我尝试了很多解决方案,但没有一个有效。
这是RPG函数的代码:
dcl-proc SWFS02801_generaHeaderMX export;
dcl-pi *n Ind;
bicFrom Char(12);
bicTo Char(12);
BizMsgIdr Char(20);
MsgDefIdr Char(20);
AppHeaderData Char(2000);
end-pi;
dcl-s AppHeader SQLTYPE(CLOB:2000);
dcl-s bicFromClob SQLTYPE(CLOB:12);
dcl-c BizSvc 'swift.cbprplus.01';
bicFromClob_DATA = bicFrom;
Exec Sql SELECT XMLSERIALIZE(
XMLELEMENT(NAME "AppHdr", XMLNAMESPACES(DEFAULT
'urn:iso:std:iso:20022:tech:xsd:head.001.001.02'),
XMLFOREST(
XMLELEMENT(NAME "FiId", XMLELEMENT(NAME "FinInstId",
XMLFOREST( :bicFrom as "BicFi") ) ) as "Fr",
XMLELEMENT(NAME "FiId", XMLELEMENT(NAME "FinInstId",
XMLFOREST( :bicTo as "BicFi") )) as "To",
:BizMsgIdr as "BizMsgIdr",
:MsgDefIdr as "MsgDefIdr",
:BizSvc as "BizSvc",
CubDDat.UbdFGenFec(Current date) as "CredDt"
)
) as CLOB(2000) ) AS RESULTADO
INTO :AppHeader
FROM SYSIBM.SYSDUMMY1;
If SQLCODE = 0;
AppHeaderData = AppHeader_DATA;
return *on;
Else;
return *off;
ENDIF;
END-PROC;
问题具体在于变量:bicFrom、bicTo、BizMsgIdr、MsgDefIdr。
预期的 XML 标头如下:
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<Fr>
<FiId>
<FinInstId>
<BicFi>BICFROM1</BicFi>
</FinInstId>
</FiId>
</Fr>
<To>
<FiId>
<FinInstId>
<BicFi>BICTO1</BicFi>
</FinInstId>
</FiId>
</To>
<BizMsgIdr>tstBizMsgIdr</BizMsgIdr>
<MsgDefIdr>tstMsgDefIdr</MsgDefIdr>
<BizSvc>swift.cbprplus.01</BizSvc>
<CredDt>2021-12-28T06:00:00.0Z</CredDt>
</AppHdr>
返回的(不正确)输出如下(注意标签 BicFi、BizMsgIdr、MsgDefIdr、BizSvc):
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<Fr>
<FiId>
<FinInstId>
<BicFi>wsnDxtnW1PFAQEBA</BicFi>
</FinInstId>
</FiId>
</Fr>
<To>
<FiId>
<FinInstId>
<BicFi>wsnDxuPW8UBAQEBA</BicFi>
</FinInstId>
</FiId>
</To>
<BizMsgIdr>oqPCianUoofJhJlAQEBAQEBAQEA=</BizMsgIdr>
<MsgDefIdr>oqPUoofEhYbJhJlAQEBAQEBAQEA=</MsgDefIdr>
<BizSvc>oqaJhqNLg4KXmZeTpKJL8PE=</BizSvc>
<CredDt>2021-12-28T06:00:00.0Z</CredDt>
</AppHdr>
欢迎任何想法。预先感谢!
编辑: 这是调用者代码:
Ctl-opt bnddir('SERVICEBCO') DftActGrp( *No ) actgrp('QILE');
//TXT containing the procedure prototype
/include LIBLCF/QSRCTXT,SWFS02801H
Dcl-S bicFrom Char(12) Inz( 'BICFROM1' );
Dcl-S bicTo Char(12) Inz( 'BICFTO1' );
Dcl-S BizMsgIdr Char(20) Inz( 'stBizMsgIdr' );
Dcl-S MsgDefIdr Char(20) Inz( 'stMsgDefIdr');
Dcl-S CreDt Char(30) Inz(*blanks);
Dcl-S headerMX Char(2000) Inz( *Blanks );
EXEC SQL SET OPTION CLOSQLCSR = *ENDMOD;
If Swfs02801_generaHeaderMX(bicFrom :bicTo : BizMsgIdr : MsgDefIdr : headerMX );
dsply %subst(headerMX:1:30);
//dsply just to check the result
Endif;
*inlr = *on;
原型:
/if defined(SWFS02801_INCLUDED)
/eof
/endif
/define SWFS02801_INCLUDED
dcl-pr SWFS02801_generaHeaderMX ind;
bicFrom Char(12);
bicTo Char(12);
BizMsgIdr Char(20);
MsgDefIdr Char(20);
AppHeader Char(2000);
end-pr;
系统和作业CSSID为65535。
使用传递的变量(bicfrom、bicto、BizMsgIdr 和 AppHeaderData)进行序列化时会出现问题。
我能够重复这个问题,所以我得到了与你得到的变量相同的奇怪字符。
此示例使用 (1) CLLE pgm、(2) SQLRPGLE pgm 和 (3) SQL 存储过程有效。
要运行它,在编译对象后,从 AS400 命令行,在调试中,
call test6c
PGM
chgjob ccsid(37)
调用测试6
结束PGM
测试6C SQLRPGLE
d wbic来自 s 12
d wbicTo s 12
d wBizMsgIdr s 20
d wMsgDefIdr s 20
d wP输出 s 2000
exsr mainsr;
exsr endpgm;
begsr endpgm;
*INLR='1';
return;
endsr;
begsr *inzsr;
endsr;
begsr mainsr;
wbicFrom = 'BICFROM1' ;
wbicTo = 'BICFTO1' ;
wBizMsgIdr = 'stBizMsgIdr' ;
wMsgDefIdr = 'stMsgDefIdr' ;
wPoutput = *blanks;
EXEC SQL
Call snagle.test6pr(:wbicFrom ,
:wbicTo ,
:wBizMsgIdr ,
:wMsgDefIdr ,
:wPoutput ) ;
endsr;
SQL 过程 SNAGLE.TEST6PR
创建或替换过程 snagle.test6pr (
在 bicFrom CHAR(12) 中,
在 bicTo CHAR(12) 中,
在 BizMsgIdr CHAR(20) 中,
在 MsgDefIdr CHAR(20) 中,
OUT p 输出 CHAR(2000)
)
语言 SQL
开始
声明光标 1 光标为
选择 XML 序列化(
XMLELEMENT(名称“AppHdr”,XMLNAMESPACES(默认
'瓮:iso:std:iso:20022:技术:xsd:head.001.001.02'),
XML森林(
XMLELEMENT(名称“FiId”, XMLELEMENT(名称“FinInstId”,
XMLFOREST( 修剪(bicFrom) as "BicFi") ) ) as "Fr",
XMLELEMENT(名称“FiId”, XMLELEMENT(名称“FinInstId”,
XMLFOREST( 修剪(bicTo) as "BicFi") )) as "To",
修剪(BizMsgIdr)为“BizMsgIdr”,
修剪(MsgDefIdr)为“MsgDefIdr”,
'swift.cbprplus.01' 作为“BizSvc”,
20240831 为“CredDt”
)
) 作为 CLOB(2000) ) 作为结果
--INTO应用程序头
来自 SYSIBM.SYSDUMMY1
;
打开光标1;
从游标 1 读取到 poutput;
关闭光标1;
结束;