JSON_TABLE 中的 SQLRPGLE 和 CCSID 问题

Íñi*_*igo 4 sql json rpgle ibm-midrange

我的一个程序有问题,它与源文件 CCSID 相关。\n我需要生成一个 JSON 字段。\n在原始程序中,它是从公共表(具有不同列)插入到一个表,定义为 CLOB 以包含使用源表列生成的 JSON。

\n

这是该程序的一个示例,它显示了问题,并且存在相同的问题:

\n
**free\n\nctl-opt dftactgrp(*no) option(*srcstmt:*NODEBUGIO);\n\ndcl-s jsonv varchar(256) ccsid(1145);\ndcl-s text varchar(34) ccsid(1145);\n\nTEXT='TEST, AND TEXT';\nexec sql set :jsonv=json_object('test_text' value :text);\n\nreturn;    \xe2\x80\x8b\n
Run Code Online (Sandbox Code Playgroud)\n

编译为:

\n
CRTSQLRPGI OBJ(TESTJSON) SRCFILE(LET) SRCMBR(TESTJSON) OPTION(*EVENTF) REPLACE(*YES) DBGVIEW(*SOURCE) LANGID(ESP) CVTCCSID(*JOB)\n
Run Code Online (Sandbox Code Playgroud)\n

问题是,当我编译来自 CCSID 284 源文件的代码时,它工作正常。

\n

但是当我从 CCSID 65535 的不同源文件编译它时,程序失败。\xc2\xa0

\n

这些是错误:

\n
Derived operands not valid for operator JSON_OBJECT. Reason code 12. \nCharacter conversion between CCSID 65535 and CCSID 1208 not valid.   \n  12 -- The CCSIDs (Coded Character Set Identifiers) of the operands cannot\nbe made compatible.                                                        \n\nMessage . . . . :   Character conversion between CCSID 65535 and CCSID 1208   \n  not valid.                                                                  \nCause . . . . . :   Character or graphic conversion has been attempted for    \n  data that is not compatible. There is no conversion defined between CCSID   \n  65535 and CCSID 1208.                                                       \n    If one CCSID is 65535, the other CCSID is a graphic CCSID. Conversion is  \n  not defined between 65535 and a graphic CCSID.                              \n    If this is a CONNECT statement, conversion is not defined between the     \n  default application requester SBCS CCSID and the application server SBCS    \n  CCSID.  If the second CCSID is 0, the application server did not return its \n  default SBCS CCSID.  An application server other than DB2 for IBM i may not \n  support a CCSID of 65535.                                                   \nRecovery  . . . :   Ensure that all character or graphic comparisons,       \n  concatenation, or assignments are between columns or host variables with  \n  compatible CCSID values.                                                  \n    If this is a CONNECT statement, change either the SBCS CCSID of the     \n  application requester or the application server, so conversion between the\n  CCSID values is defined.                   \n                               \n
Run Code Online (Sandbox Code Playgroud)\n

并且,在程序中,我收到 SQLSTT 57017 - 未定义字符转换。\n我尝试了以下选项:

\n
    \n
  • 更改作业 CCSID。失败。
  • \n
  • 更改程序中的 CCSID 字段。失败
  • \n
  • 使用参数 LANGID 和 CVTCSID 的不同组合进行编译。失败
  • \n
\n

唯一可以正常工作的是更改源文件 CCSID(我已将其复制到使用 CCSID 284 创建的另一个源文件)。

\n

因此,我知道一种解决方案是将 65535 更改为 284(或更适合我们的语言设置的 1145)。\n但是,有其他解决方案吗?

\n

谢谢!

\n

Cha*_*les 6

正确的答案是不要将 CCSID 65535 用于任何实际上不包含二进制数据的内容......

我认为正确使用 CCSID 控制规范可能会解决您的问题。但据我所知,情况并非如此。

我认为您实际上遇到了 SQL 预编译器如何处理具有 CCSID(65535) 的源文件中的文字的问题。

删除 SQL 语句中的文字,为我停止了运行时错误。

**free

ctl-opt dftactgrp(*no) option(*srcstmt:*NODEBUGIO);

dcl-s jsonv varchar(256) ccsid(1145);
dcl-s text varchar(34) ccsid(1145);
dcl-s key varchar(10) ccsid(1145);

TEXT='TEST, AND TEXT';
key = 'test_text';
exec sql set :jsonv=json_object(:key value :text);

return;
Run Code Online (Sandbox Code Playgroud)

CRTSQLRPGI 命令有一个新的“Conversion CCSID . . . CVTCSID”参数,但这似乎是专门针对UTF-8 流文件源的

您可以向 IBM 提出案例,因为预编译器似乎不支持ctl-opt ccsid(*char:1145);. 但我怀疑他们会告诉您他们不会修复它,并且您不应该使用 CCSID(65535) 定义源文件。