Db2 这是SQL GET诊断的正确行为吗?
SQL语句Db2 这是SQL GET诊断的正确行为吗?,db2,ibm-midrange,db2-400,rpgle,Db2,Ibm Midrange,Db2 400,Rpgle,SQL语句GET DIAGNOSTICS的for表示可以请求将诊断数据放入特定变量中,并列出相关变量名称和类型。文章和演示了如何在RPG程序的上下文中使用此SQL语句 看起来我从DB2得到的一些结果与文档和文章中所说的不匹配。我使用的是IBMi,版本7.3 我正在查看从SQL用户定义表函数(UDTF)返回的诊断数据。如果使用“ALL”子句,则可以得到包含所有值的字符串: COMMAND_FUNCTION=FETCH; COMMAND_FUNCTION_CODE=+45; DB2_NUMBER_C
GET DIAGNOSTICS
的for表示可以请求将诊断数据放入特定变量中,并列出相关变量名称和类型。文章和演示了如何在RPG程序的上下文中使用此SQL语句
看起来我从DB2得到的一些结果与文档和文章中所说的不匹配。我使用的是IBMi,版本7.3
我正在查看从SQL用户定义表函数(UDTF)返回的诊断数据。如果使用“ALL”子句,则可以得到包含所有值的字符串:
COMMAND_FUNCTION=FETCH;
COMMAND_FUNCTION_CODE=+45;
DB2_NUMBER_CONNECTIONS=+1;
MORE=N;
NUMBER=+1;
CONDITION_NUMBER=+1;
DB2_MESSAGE_ID=SQL0443;
DB2_MESSAGE_ID1=CPF503E;
DB2_MODULE_DETECTING_ERROR=QSQFETCH;
DB2_ORDINAL_TOKEN_1=*N.*N;
DB2_ORDINAL_TOKEN_2=DUMMYUDTF;
DB2_ORDINAL_TOKEN_3=*******.DUMMYUDTF;
DB2_ORDINAL_TOKEN_4=Parameter '2' cannot be null.;
DB2_RETURNED_SQLCODE=-443;
DB2_TOKEN_COUNT=+4;
DB2_TOKEN_STRING=*N.*NDUMMYUDTFDUMMYUDTFParameter '2' cannot be null.;
MESSAGE_LENGTH=Parameter '2' cannot be null.;
MESSAGE_OCTET_LENGTH=Parameter '2' cannot be null.;
MESSAGE_TEXT=Parameter '2' cannot be null.;
RETURNED_SQLSTATE=90002;
ROUTINE_NAME=DUMMYUDTF;
ROUTINE_SCHEMA=QGPL;
SERVER_NAME=******;
SPECIFIC_NAME=DUMMYUDTF;
DB2_SQLERRD_SET=Y;
DB2_SQLERRD1=-168758331;
CONNECTION_NAME=******;
DB2_AUTHORIZATION_ID=********;
DB2_CONNECTION_METHOD=D;
DB2_CONNECTION_NUMBER=+1;
DB2_CONNECTION_STATE=+1;
DB2_CONNECTION_TYPE=+1;
DB2_PRODUCT_ID=QSQ07030;
DB2_SERVER_CLASS_NAME=DB2 for i;
DB2_SERVER_NAME=******;
文档规定字段消息长度
和消息八位字节长度
应为整数。正如你所看到的,他们都是瓦查尔人。如果我编写的代码将这些变量定义为整数,则会得到转义消息:标量操作数没有指令所需的属性。
在作业日志和两个诊断中,严重程度为50SQL系统错误。
以及SQL服务转储qsvcdmp
。另一个反常现象是变量DB2_MESSAGE_ID2
看起来不像是实现的,它会使程序在SQL分配它的行上崩溃
相反,如果我在内置函数上使用GET DIAGNOSTICS
,则数据类型都与文档中所述相符,并且所有变量似乎都可用:
COMMAND_FUNCTION=SELECT;
COMMAND_FUNCTION_CODE=+65;
DB2_NUMBER_CONNECTIONS=+1;
MORE=N;
NUMBER=+1;
CLASS_ORIGIN=ISO9075;
CONDITION_NUMBER=+1;
DB2_MESSAGE_ID=SQL0138;
DB2_MESSAGE_ID1=CPF4278;
DB2_MESSAGE_ID2=CPD4317;
DB2_MODULE_DETECTING_ERROR=QSQOPEN;
DB2_ORDINAL_TOKEN_1=*N;
DB2_RETURNED_SQLCODE=-138;
DB2_TOKEN_COUNT=+1;
DB2_TOKEN_STRING=*N;
MESSAGE_LENGTH=+47;
MESSAGE_OCTET_LENGTH=+47;
MESSAGE_TEXT=Argument *N of substringing function not valid.;
RETURNED_SQLSTATE=22011;
ROUTINE_CATALOG=******;
SERVER_NAME=******;
SUBCLASS_ORIGIN=ISO9075;
DB2_SQLERRD_SET=Y;
DB2_SQLERRD1=-185403400;
DB2_SQLERRD2=-185339401;
CONNECTION_NAME=******;
DB2_AUTHORIZATION_ID=********;
DB2_CONNECTION_METHOD=D;
DB2_CONNECTION_NUMBER=+1;
DB2_CONNECTION_STATE=+1;
DB2_CONNECTION_TYPE=+1;
DB2_PRODUCT_ID=QSQ07030;
DB2_SERVER_CLASS_NAME=DB2 for i;
DB2_SERVER_NAME=******;
这是一个应该向IBM报告的bug吗?一个人是如何做到这一点的?我制作了一个UDTF和一个调用RPGLE程序来演示这个问题。如果有人想验证我的发现,代码如下。您可能需要在RPGLE程序TSTDIAUDTF
中注释掉几行,因为您没有我的错误消息服务程序ERRFUNC
DUMMYUDTF
是一个外部用户定义的SQL函数,代码在SQL和RPGLE中TSTDIAUDTF
是一个RPGLE程序,我正在使用它来测试GET DIAGNOSTICS
SQL语句的行为
例如,这似乎与过去报告的一些bug大体相似,但细节不同
编辑:
更正了早期错误粘贴操作中的代码格式错误
DUMMYUDTF,TXT
-- Build function by calling:
-- RUNSQLSTM SRCFILE(*******/QTXTSRC) SRCMBR(DUMMYUDTF) COMMIT(*NONE)
CREATE OR REPLACE FUNCTION DummyUDTF(
parm1 NUMERIC(7,0),
parm2 VARCHAR(7)
parm3 VARCHAR(4))
RETURNS TABLE (Out1 NUMERIC(7,0),
Out2 VARCHAR(13),
Out3 VARCHAR(4),
Out4 NUMERIC(7,2),
Out5 NUMERIC(5,4))
LANGUAGE RPGLE
DETERMINISTIC
READS SQL DATA
CALLED ON NULL INPUT
DISALLOW PARALLEL
NOT FENCED
EXTERNAL NAME '******/DUMMYUDTF'
PARAMETER STYLE DB2SQL;
DUMMYUDTF,SQLRPGLE
/IF DEFINED (*CRTBNDRPG)
H DFTACTGRP(*NO) ACTGRP('DUMMYUDTF')
/ENDIF
H DEBUG
H ALWNULL(*USRCTL) OPTION(*NoDebugIO) EXTBININT(*YES)
D DUMMYUDTF PI
* Input Parameters
D parm1 7S 0
D parm2 7A VARYING
D parm3 4A VARYING
* Columns to be returned
D out1 7S 0
D out2 13A VARYING
D out3 4A VARYING
D out4 7S 2
D out5 5S 4
* NULL Indicators for all input and output parameters
D parm1_n 5I 0
D parm2_n 5I 0
D parm3_n 5I 0
D out1_n 5I 0
D out2_n 5I 0
D out3_n 5I 0
D out4_n 5I 0
D out5_n 5I 0
* SQL Function Parameters
D OutputSQLState 5A
D FunctionName 517A VARYING CONST
D SpecificName 128A VARYING CONST
D MessageText 1000A VARYING
D CallType 10I 0
* Locals
D CallTypeFirst C CONST(-2)
D CallTypeOpen C CONST(-1)
D CallTypeFetch C CONST(0)
D CallTypeClose C CONST(1)
D CallTypeFinal C CONST(2)
D out DS TEMPLATE QUALIFIED
D out1 7S 0
D out2 13A VARYING
D out3 4A VARYING
D out4 7S 2
D out5 5S 4
D results DS DIM(99) LIKEDS(out)
D index S 2S 0
D count S 2S 0
D var4 S 7S 2
D var5 S 5S 4
MONITOR;
OutputSQLState = *ZEROS; // Initialize Output Parameters
CLEAR MessageText;
SELECT;
WHEN CallType = CallTypeOpen;
IF parm1_n = -1;
MessageText = BuildNullError('1');
RETURN;
ENDIF;
IF parm2_n = -1;
MessageText = BuildNullError('2');
RETURN;
ENDIF;
IF parm3_n = -1;
MessageText = BuildNullError('3');
RETURN;
ENDIF;
IF parm1 < 1;
OutputSQLState = '90002';
MessageText = 'Parameter 1 must be a number greater than 0.';
RETURN;
ENDIF;
EXSR BuildDummyData;
WHEN CallType = CallTypeFetch;
index += 1;
IF index > count;
OutputSQLState = '02000';
RETURN;
ENDIF;
out1 = results(index).out1;
out2 = results(index).out2;
out3 = results(index).out3;
out4 = results(index).out4;
out5 = results(index).out5;
WHEN CallType = CallTypeClose;
*INLR = *ON;
ENDSL;
ON-ERROR;
DUMP; // This dump ends up in the output queue QUSRSYS\QEZDEBUG
OutputSQLState = '90001';
MessageText = 'Error occurred in RPG program ''DUMMYUDTF''. ' +
'See program dump for additional details.';
ENDMON;
RETURN;
********************************************************************
BEGSR BuildDummyData;
EXEC SQL SELECT 350.05, .65
INTO :var4, :var5
FROM SYSIBM.SYSDUMMY1;
SaveToResults(parm1 : parm2 : parm3 : var4 : var5);
SaveToResults(219 : 'ABCDEF' : 'ZYXW' : 20.1 : .65);
SaveToResults(438 : 'GHIJKLMNOP' : 'ZYXW' : 2.95 : 0);
ENDSR;
********************************************************************
P BuildNullError...
P B
D PI 1000A VARYING
D parmName 20A VALUE VARYING
OutputSQLState = '90002';
RETURN 'Parameter ''' + parmName + ''' cannot be null.';
P E
********************************************************************
P SaveToResults...
P B
D PI
D loc1 7S 0 VALUE
D loc2 13A VALUE VARYING
D loc3 4A VALUE VARYING
D loc4 7S 2 VALUE
D loc5 5S 4 VALUE
IF count = 99;
OutputSQLState = '10Z01';
MessageText = 'SQL warning in DUMMYUDTF +
More than 99 parts generated.';
ELSE;
count += 1;
results(count).out1 = loc1;
results(count).out2 = loc2;
results(count).out3 = loc3;
results(count).out4 = loc4;
results(count).out5 = loc5;
ENDIF;
P E
H DEBUG(*YES)
H MAIN(Main)
H DFTACTGRP(*NO)
H BNDDIR('ERRFUNC')
/copy QRPGLESRC,ERRFUNCPR
D Message DS LIKEDS(ErrorMsg)
D success S 3I 0
D failure S 3I 0
D diagAll S 32740A VARYING
D displayText S 52A
D dummyItem DS INZ
D out1 7S 0
D out2 13A
D out3 4A
D out4 7S 2
D out5 5S 4
D SQLDiagData DS INZ
D MessageID 10A
D MessageID1 7A
D MessageID2 7A
D MessageLength 5I 0
D MessageText 32740A VARYING
D otherType 32740A VARYING
D ReturnedSQLCode...
D 5A
D ReturnedSQLState...
D 5A
D RowCount 10I 0
P Main B
DSPLY 'Beginning of test';
TestDummyUDTF();
TestDiagnoticsFromUDTF();
TestDiagnoticsFromBIF();
DSPLY ('Successful tests: ' + %char(success));
DSPLY ('Failed tests: ' + %char(failure));
RETURN;
BEGSR *PSSR;
DUMP;
DSPLY 'Unexpected error while running tests.';
GetErrorMsg(Message);
DSPLY ('Message.MsgId: ' + Message.MsgId);
DSPLY (%subst(Message.MsgText:1:52));
RETURN;
ENDSR;
P E
********************************************************************
P TestDiagnoticsFromBIF...
P B
D text S 10A
DSPLY 'Causing error from SUBSTR to read diagnostics.';
EXEC SQL SELECT SUBSTR('ABC', 1, -1) INTO :text
FROM SYSIBM.SYSDUMMY1;
IF SQLSTATE = '00000';
failure +=1;
DSPLY 'Test failed. Data returned, no error.';
ELSEIF SQLSTATE = '02000';
failure +=1;
DSPLY 'Test failed. No error returned.';
ELSE;
ReadSQLDiagnosticsAll();
IF diagAll <> '';
success += 1;
DisplayTextWindow(diagAll : 'CPF9898':'QCPFMSG');
DSPLY 'GET DIAGNOSTICS ALL succeeded.';
ELSE;
failure +=1;
DSPLY 'GET DIAGNOSTICS ALL failed.';
ENDIF;
ReadSQLDiagnosticsAllCondition();
IF diagAll <> '';
success += 1;
DisplayTextWindow(diagAll : 'CPF9898':'QCPFMSG');
DSPLY 'GET DIAGNOSTICS ALL CONDITION succeeded.';
ELSE;
failure +=1;
DSPLY 'GET DIAGNOSTICS ALL CONDITION failed.';
ENDIF;
ReadSQLDiagnostics();
IF ReturnedSQLCode <> '-138 ' OR
ReturnedSQLState <> '22011';
failure +=1;
DSPLY 'Test failed. Unexpected diagnostic.';
displayText = 'SQLCODE ' + ReturnedSQLCode +
' SQLSTATE ' + ReturnedSQLState;
DSPLY displayText;
ELSE;
displayText = MessageText;
DSPLY displayText;
displayText = 'MESSAGE_LENGTH ' + %char(MessageLength);
DSPLY displayText;
displayText = 'DB2_MESSAGE_ID ' + MessageID +
' DB2_MESSAGE_ID1 ' + MessageID1;
DSPLY displayText;
displayText = 'DB2_MESSAGE_ID2 ' + MessageID2;
DSPLY displayText;
IF MessageText <> '';
success += 1;
DSPLY 'GET DIAGNOSTICS MessageText succeeded.';
ELSE;
failure +=1;
DSPLY 'GET DIAGNOSTICS MessageText failed.';
ENDIF;
ENDIF;
ENDIF;
P E
********************************************************************
P TestDiagnoticsFromUDTF...
P B
D var2 S 7A
D var2_n S 5I 0
var2_n = -1;
DSPLY 'Causing error from DummyUDTF to read diagnostics.';
EXEC SQL DECLARE CUR_DIAG_UDTF CURSOR FOR (
SELECT ITEMS.*
FROM TABLE (QGPL.DummyUDTF(22, :var2 :var2_n, 'ZZ')) AS ITEMS
);
EXEC SQL OPEN CUR_DIAG_UDTF;
DOW 1=1;
EXEC SQL FETCH CUR_DIAG_UDTF INTO :dummyItem;
IF SQLSTATE = '00000';
failure +=1;
DSPLY 'Test failed. Records returned, no error.';
LEAVE;
ELSEIF SQLSTATE = '02000';
failure +=1;
DSPLY 'Test failed. No error returned.';
LEAVE;
ELSE;
ReadSQLDiagnosticsAll();
IF diagAll <> '';
success += 1;
DisplayTextWindow(diagAll : 'CPF9898':'QCPFMSG');
DSPLY 'GET DIAGNOSTICS ALL succeeded.';
ELSE;
failure +=1;
DSPLY 'GET DIAGNOSTICS ALL failed.';
ENDIF;
ReadSQLDiagnosticsAllCondition();
IF diagAll <> '';
success += 1;
DisplayTextWindow(diagAll : 'CPF9898':'QCPFMSG');
DSPLY 'GET DIAGNOSTICS ALL CONDITION succeeded.';
ELSE;
failure +=1;
DSPLY 'GET DIAGNOSTICS ALL CONDITION failed.';
ENDIF;
ReadSQLDiagnosticsUDTF();
IF ReturnedSQLCode <> '-443 ' OR
ReturnedSQLState <> '90002';
failure +=1;
DSPLY 'Test failed. Unexpected diagnostic.';
displayText = 'SQLCODE ' + ReturnedSQLCode +
' SQLSTATE ' + ReturnedSQLState;
DSPLY displayText;
ELSE;
* DSPLY MessageID;
* DSPLY %char(MessageLength);
displayText = MessageText;
DSPLY displayText;
displayText = 'MESSAGE_LENGTH ' + OtherType;
DSPLY displayText;
displayText = 'DB2_MESSAGE_ID ' + MessageID +
' DB2_MESSAGE_ID1 ' + MessageID1;
DSPLY displayText;
IF MessageText <> '';
success += 1;
DSPLY 'GET DIAGNOSTICS MessageText succeeded.';
ELSE;
failure +=1;
DSPLY 'GET DIAGNOSTICS MessageText failed.';
ENDIF;
ENDIF;
LEAVE;
ENDIF;
ENDDO;
EXEC SQL CLOSE CUR_DIAG_UDTF;
P E
********************************************************************
P TestDummyUDTF...
P B
D expected DS DIM(3) LIKEDS(dummyItem)
D index S 3I 0
expected(1).out1 = 22;
expected(1).out2 = 'AAAA';
expected(1).out3 = 'ZZ';
expected(1).out4 = 350.05;
expected(1).out5 = .65;
expected(2).out1 = 219;
expected(2).out2 = 'ABCDEF';
expected(2).out3 = 'ZYXW';
expected(2).out4 = 20.1;
expected(2).out5 = .65;
expected(3).out1 = 438;
expected(3).out2 = 'GHIJKLMNOP';
expected(3).out3 = 'ZYXW';
expected(3).out4 = 2.95;
expected(3).out5 = 0;
DSPLY 'Running test on DummyUDTF, success expected.';
EXEC SQL DECLARE CUR_UDTF CURSOR FOR (
SELECT ITEMS.*
FROM TABLE (QGPL.DummyUDTF(22, 'AAAA', 'ZZ')) AS ITEMS
);
EXEC SQL OPEN CUR_UDTF;
DOW 1=1;
EXEC SQL FETCH CUR_UDTF INTO :dummyItem;
IF SQLSTATE = '00000';
index += 1;
IF out1 <> expected(index).out1 OR
out2 <> expected(index).out2 OR
out3 <> expected(index).out3 OR
out4 <> expected(index).out4 OR
out5 <> expected(index).out5;
failure +=1;
DSPLY 'Test failed. Data mismatch from UDTF.';
ELSE;
success += 1;
DSPLY 'Test succeeded.';
ENDIF;
LEAVE;
ELSEIF SQLSTATE = '02000';
IF index = 0;
failure +=1;
DSPLY 'Test failed. No records returned.';
ENDIF;
LEAVE;
ELSE;
failure +=1;
DSPLY ('Test failed. SQLSTATE ' + SQLSTATE);
// ReadSQLDiagnostics();
LEAVE;
ENDIF;
ENDDO;
EXEC SQL CLOSE CUR_UDTF;
RETURN;
P E
**************************************************************************
P ReadSQLDiagnostics...
P B
D PI
D condition# 5I 0 VALUE OPTIONS(*NOPASS)
IF %parms = 0 OR condition# < 1;
condition# = 1;
ENDIF;
EXEC SQL GET DIAGNOSTICS CONDITION :condition#
:SQLDiagData.ReturnedSQLCode = DB2_RETURNED_SQLCODE,
:SQLDiagData.ReturnedSQLState = RETURNED_SQLSTATE,
:SQLDiagData.MessageText = MESSAGE_TEXT,
:SQLDiagData.MessageLength = MESSAGE_LENGTH,
:SQLDiagData.MessageID = DB2_MESSAGE_ID,
:SQLDiagData.MessageID1 = DB2_MESSAGE_ID1,
:SQLDiagData.MessageID2 = DB2_MESSAGE_ID2;
RETURN;
P E
**************************************************************************
P ReadSQLDiagnosticsUDTF...
P B
D PI
D condition# 5I 0 VALUE OPTIONS(*NOPASS)
IF %parms = 0 OR condition# < 1;
condition# = 1;
ENDIF;
EXEC SQL GET DIAGNOSTICS CONDITION :condition#
:SQLDiagData.ReturnedSQLCode = DB2_RETURNED_SQLCODE,
:SQLDiagData.ReturnedSQLState = RETURNED_SQLSTATE,
:SQLDiagData.MessageText = MESSAGE_TEXT,
:SQLDiagData.otherType = MESSAGE_LENGTH,
:SQLDiagData.MessageID = DB2_MESSAGE_ID,
:SQLDiagData.MessageID1 = DB2_MESSAGE_ID1;
// :SQLDiagData.MessageLength = MESSAGE_LENGTH,
// :SQLDiagData.MessageID = DB2_MESSAGE_ID;
RETURN;
P E
************************4*************************************************
P ReadSQLDiagnosticsAll...
P B
EXEC SQL GET DIAGNOSTICS :diagAll = ALL;
RETURN;
P E
**************************************************************************
P ReadSQLDiagnosticsAllCondition...
P B
D PI
D condition# 5I 0 VALUE OPTIONS(*NOPASS)
IF %parms = 0 OR condition# < 1;
condition# = 1;
ENDIF;
EXEC SQL GET DIAGNOSTICS :diagAll = ALL CONDITION;
RETURN;
P E
P DisplayTextWindow...
P B Export
D PI
D Text 8192 Const Varying
D MessageId 7 Const
D MessageFile 21 Const
D ErrCode DS
D BytesIn 10I 0 INZ(0)
D BytesOut 10I 0 INZ(0)
DQUILNGTX PR EXTPGM('QUILNGTX')
D MsgText 8192 CONST
D MsgLength 10I 0 CONST
D MessageId 7 CONST
D MessageFile 21 CONST
D dsErrCode LIKE(ErrCode)
QUILNGTX(Text : %Len(Text) :
MessageId : MessageFile : ErrCode);
P E
/如果定义(*CRTBNDRPG)
H DFTACTGRP(*否)ACTGRP('DUMMYUDTF'))
/恩迪夫
H调试
H ALWNULL(*USRCTL)选项(*NoDebugIO)EXTBININT(*是)
D DUMMYUDTF PI
*输入参数
D parm1 7S 0
D parm2 7A可变
D parm3 4A可变
*要返回的列
D输出17秒0
D输出2 13A变化
D输出3 4A变化
D输出4 7S 2
D输出5 5S 4
*所有输入和输出参数的空指示符
D parm1_n 5I 0
D parm2_n 5I 0
D parm3_n 5I 0
D输出1_n 5I 0
D输出2_n 5I 0
D输出3_n 5I 0
D输出4_n 5I 0
D输出5_n 5I 0
*SQL函数参数
D输出SQLSTATE 5A
D函数名517A可变常数
D SpecificName 128A可变常量
D消息文本1000A
D调用类型10I 0
*当地人
D CallTypeFirst C常量(-2)
D调用类型打开C常量(-1)
D CallTypeFetch C常量(0)
D调用类型关闭C常量(1)
D调用类型最终C常量(2)
D输出DS模板合格
D输出17秒0
D输出2 13A变化
D输出3 4A变化
D输出4 7S 2
D输出5 5S 4
D结果DS DIM(99)LIKEDS(out)
D指数s2s0
D计数S 2S 0
D var4 S 7S 2
D var5 S 5S 4
班长
OutputSQLState=*零;//初始化输出参数
文本清晰;
选择;
当CallType=CallTypeOpen时;
如果parm1_n=-1;
MessageText=BuildNullError('1');
返回;
ENDIF;
如果parm2_n=-1;
MessageText=BuildNullError('2');
返回;
ENDIF;
如果parm3_n=-1;
MessageText=BuildNullError('3');
返回;
ENDIF;
如果parm1<1;
OutputSQLState='90002';
MessageText='参数1必须是大于0的数字';
返回;
ENDIF;
EXSR BuildDummyData;
当CallType=CallTypeFetch时;
指数+=1;
如果索引>计数;
OutputSQLState='02000';
返回;
ENDIF;
out1=结果(指数)。out1;
out2=结果(指数)。out2;
out3=结果(指数)。out3;
out4=结果(指数)。out4;
out5=结果(指数)。out5;
当CallType=CallTypeClose时;
*INLR=*ON;
ENDSL;
在线误差;
转储;//此转储将在输出队列QUSRSYS\QEZDEBUG中结束
OutputSQLState='90001';
MessageText='RPG程序“DUMMYUDTF”中发生错误。'+
'有关其他详细信息,请参阅程序转储';
尾声;
返回;
********************************************************************
BEGSR BuildDummyData;
EXEC SQL SELECT 350.05、.65
进入:var4,:var5
来自SYSIBM.SYSDUMMY1;
保存结果(parm1:parm2:parm3:var4:var5);
保存结果(219:'ABCDEF':'ZYXW':20.1:.65);
保存结果(438:'GHIJKLMNOP':'ZYXW':2.95:0);
ENDSR;
********************************************************************
P BuildNullError。。。
P B
D PI 1000A可变
D参数名称20A值变化
OutputSQLState='90002';
返回“参数”+“参数名”+“不能为空”;
体育课
*******************************************************************
**free
ctl-opt actgrp(*NEW) main(mainline) cvtopt(*NOVARCHAR) debug(*yes);
dcl-pr mainline extpgm('TESTRPGLE');
end-pr;
dcl-proc mainline;
dcl-s diagAll varchar(32740);
dcl-ds dummyItem qualified;
out1 zoned(7);
out2 varchar(13);
out3 varchar(4);
out4 zoned(7:2);
out5 zoned(5:4);
end-ds;
dcl-s nullArr int(5) dim(5);
exec sql
declare C1 cursor for (
SELECT ITEMS.*
FROM TABLE (DummyUDTF(22, cast(null as varchar(7)), 'ZZ')) AS ITEMS
);
exec sql
open C1;
//I expected SQLSTATE to be 90002 here, but it's not
if sqlstate <> *ZEROS;
exec sql
get diagnostics :diagAll = ALL;
dump;
return;
endif;
exec sql
fetch C1 into :dummyItem :nullArr;
//here's where the SQLSTATE of 90002 is returned.
if sqlstate <> *ZEROS;
exec sql
get diagnostics :diagAll = ALL;
dump;
return;
endif;
return;
end-proc;