DB2,PL / SQL和游标(IBM没有关注自己的帮助页面)

时间:2017-05-03 02:27:23

标签: plsql db2 db2-luw cursors

DB2,版本10.5。

我的光标是这样的:

declare stat cursor for select record_type, sequence_code from my_status fetch first 10 rows only;

尝试使用IBM网页上记录的FOR结构遍历它,例如,

for s in stat do
    call dbms_output.put_line ('In the cursor loop');
end for;

DB21034E该命令作为SQL语句处理,因为它不是 有效的命令行处理器命令。在SQL处理期间,它返回: SQL0104N在“rst 10 rows only;后面找到意外的令牌”for“ “。预期的代币可能包括:”“。行数= 9。 SQLSTATE = 42601。

所以我尝试在一个循环中做一个显式的open和一个fetch,并且这个工作 - 但它会永远持续下去(即没有错误并且当它到达10个记录的最后一个时中止)如果我没有t在循环中放入一个显式计数器。显示数据中的字段证明它正在循环1,2,3 ...... 9,10,10,10,10,10。

所以我尝试添加      “如果stat%FOUND” 在循环中得到这个错误:

DB21034E该命令作为SQL语句处理,因为它不是 有效的命令行处理器命令。在SQL处理期间,它返回: SQL0104N在“ence_code; if stat”之后找到意外的标记“%”。 预期的代币可能包括:“IS”。 LINE NUMBER = 24。 SQLSTATE = 42601

我甚至尝试了一个CASE语句来检查FOUND / NOTFOUND状态并得到类似的错误:

case when stat%NOTFOUND then
    call dbms_output.put_line('In case');
end case;

DB21034E该命令作为SQL语句处理,因为它不是 有效的命令行处理器命令。在SQL处理期间,它返回: SQL0104N在“case when stat”之后发现了一个意外的标记“%”。 预期的代币可能包括:“IN”。 LINE NUMBER = 30。 SQLSTATE = 42601

将其更改为stat.%NOTFOUND(%之前的一段时间)让我知道了这一点:

DB21034E该命令作为SQL语句处理,因为它不是 有效的命令行处理器命令。在SQL处理期间,它返回: SQL0104N在“case”后面发现了一个意外的令牌“stat。%NOTFOUND” 当“。预期的代币可能包括:”“。LINE NUMBER = 30。 SQLSTATE = 42601

我尝试了“exit when stat%NOTFOUND”,这是IBM支持页面的逐字记录。这让我有类似的错误:

DB21034E该命令作为SQL语句处理,因为它不是 有效的命令行处理器命令。在SQL处理期间,它返回: SQL0104N在“”后面发现了一个意外的令牌“EXIT”。 预期的代币可能包括:“”。 LINE NUMBER = 23。 SQLSTATE = 42601

除了在数据耗尽时无法终止之外,那些注释掉各个位的完整代码块工作正常:

set serveroutput on@

begin
    declare v_counter int default 0;
    declare v_record_type char(1);
    declare v_sequence_code int;

    declare stat cursor for select record_type, sequence_code from my_status fetch first 10 rows only;

    -- for s in stat do
    --     call dbms_output.put_line ('In the cursor loop');
    -- end for;

    open stat;

    fetch from stat into v_record_type, v_Sequence_code;

    set v_counter = 0;
    while v_counter < 12 do
        call dbms_output.put_line('in loop');
        call dbms_output.put_line('Record: '||v_record_type||' '||v_sequence_code);
        set v_counter = v_counter + 1;
        call dbms_output.put_line ('Counter: '||v_counter);
        fetch from stat into v_record_type, v_sequence_code;
        --if stat%FOUND then
        -- call dbms_output.put_line ('Yay, found!');
        --end if;
    --if stat%NOTFOUND then
    --      exit;
    --end if;
    --case when stat%NOTFOUND then
    --    call dbms_output.put_line('In case');
    --end case;
    --EXIT WHEN stat%NOTFOUND;
    end while;
    close stat;
END -- end procedure
@
set serveroutput off@

1 个答案:

答案 0 :(得分:1)

DB2 for LUW支持两种不同的PSM方言:本机DB2 SQL PL和Oracle兼容PL/SQL

由于SQL PL一直存在,所以它的语句在文档中的常规SQL引用中有所介绍。 PL / SQL支持在2010年左右添加,其语法在单独的部分(上面链接)中描述。您需要注意不要混淆两者,因为程序块只能使用两种方言中的任何一种,但不能同时使用两种方言。许多陈述中存在某些语法差异,因此一旦您选择了要使用的方言,就应该注意参考手册中的相应部分。

根据结构,语法检测或多或少是自动的。在DB2 SQL PL中,DECLARE语句出现在块内,而在PL / SQL中,它们在块外。所以,如果您的块以

开头
BEGIN
DECLARE something;
...
END

假设它包含SQL PL语句,如果编译器遇到PL / SQL语句,则会引发语法错误。

使用DB2命令行处理器运行程序时,可以使用命令SET SQLCOMPAT {DB2|PLSQL}明确指出方言。