DB2中如何将传入存储过程的字符串形式SQL传递给游标并返回结果集
核心报错根因
原代码存在3个违反DB2 SQL存储过程语法规则的问题,直接触发SQL0104N报错:
- 语句顺序违规:所有
DECLARE类声明(变量、游标)必须放在BEGIN块的最起始位置,原代码把游标声明夹在PREPARE、EXECUTE等可执行语句中间,解析器遇到可执行语句后又碰到声明语句,直接判定语法异常。 - 变量类型错误:
PREPARE语句绑定的目标句柄必须是STATEMENT类型,原代码把用于接收预处理语句的Instmt声明成了VARCHAR(500)字符串类型,类型完全不匹配。 - 逻辑错误:提前对入参传入的SELECT语句执行
EXECUTE,而SELECT类语句没有配套的INTO子句接收返回值,且这个操作会割裂语句和后续游标的关联,根本无法实现结果集返回的目标。
修正后的可运行实现
按照DB2动态游标+返回结果集的标准写法调整后,代码如下:
CREATE PROCEDURE abc(IN stmt VARCHAR(500)) SPECIFIC abc LANGUAGE SQL DYNAMIC RESULT SETS 1 Re: BEGIN -- 所有声明语句放在块最顶部 DECLARE Instmt STATEMENT; DECLARE v_cur CURSOR WITH RETURN TO CALLER FOR Instmt; -- 对入参传入的SQL字符串做预处理 PREPARE Instmt FROM stmt; -- 打开游标,自动关联预处理的SQL,把结果集通过游标返回给调用方 OPEN v_cur; END Re
调用方式和原需求完全一致:CALL abc('select ename,sal from emp')
实现注意点
- 不要对传入的SELECT类SQL执行
EXECUTE:EXECUTE仅适用于无结果集返回的DML/DDL语句(增、删、改、建表等),如果用EXECUTE运行SELECT语句,既无法把结果关联到游标,还会触发“缺少INTO子句”的额外报错。 DYNAMIC RESULT SETS的数值要和存储过程实际返回的游标数量匹配,这里返回1个结果集所以配置为1。- 如果需要把结果集返回给最外层客户端(而非中间嵌套调用的存储过程),可以把游标声明里的
WITH RETURN TO CALLER改成WITH RETURN TO CLIENT。
内容的提问来源于stack exchange,提问作者Kuntal
相关产品推荐
相关产品推荐

