Plsql DB2、PL/SQL和游标(IBM不遵循自己的帮助页面)

Plsql DB2、PL/SQL和游标(IBM不遵循自己的帮助页面),plsql,db2,db2-luw,cursors,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语句

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语句处理 有效的命令行处理器命令。在SQL处理过程中,它返回: SQL0104N仅在rst 10行之后找到的意外令牌; . 预期的令牌可能包括:。行号=9。 SQLSTATE=42601

因此,我尝试在循环中执行显式打开和获取,这是有效的-但它会一直持续下去,即如果我没有在循环中放入显式计数器,当它到达10条记录中的最后一条时不会出错和中止。显示数据中的字段证明它是循环1、2、3…9、10、10、10、10、10

所以我试着加上 如果找到统计% 在循环中,出现以下错误:

DB21034E由于该命令不是SQL语句,因此将其作为SQL语句处理 有效的命令行处理器命令。在SQL处理过程中,它返回: SQL0104N在ence_代码后发现意外的令牌%;如果统计。 预期的令牌可能包括:IS。行号=24。SQLSTATE=42601

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

case when stat%NOTFOUND then
    call dbms_output.put_line('In case');
end case;
DB21034E由于该命令不是SQL语句,因此将其作为SQL语句处理 有效的命令行处理器命令。在SQL处理过程中,它返回: SQL0104N在stat。 预期的令牌可能包括:IN。行号=30。SQLSTATE=42601

将其更改为stat.%NOTFOUND一个句点,就在%得到以下信息之前:

DB21034E由于该命令不是SQL语句,因此将其作为SQL语句处理 有效的命令行处理器命令。在SQL处理过程中,它返回: SQL0104N在以下情况下发现意外的令牌统计。%NOTFOUND 什么时候预期的令牌可能包括:。线 数字=30。SQLSTATE=42601

当stat%NOTFOUND是IBM支持页面上的逐字记录时,我尝试退出。这让我犯了类似的错误:

DB21034E由于该命令不是SQL语句,因此将其作为SQL语句处理 有效的命令行处理器命令。在SQL处理过程中,它返回: SQL0104N发现以下意外令牌退出。 预期的令牌可能包括:。行号=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@

DB2forLUW支持两种不同的PSM方言:原生DB2和Oracle兼容

因为SQLPL一直存在,所以文档中的常规SQL引用中包含了它的语句。PL/SQL支持是在2010年左右添加的,其语法在上面链接的单独一节中进行了描述。您需要注意不要混合使用这两种语言,因为程序块只能使用两种方言中的任何一种,但不能同时使用同一块中的两种。许多语句中存在某些语法差异,因此在选择要使用的方言后,应注意参考手册中的相应部分

语法检测或多或少是基于结构自动进行的。在DB2SQLPL中,DECLARE语句出现在块内,而在PL/SQL中,它们出现在块外。所以,如果你的积木以

BEGIN
DECLARE something;
...
END
假设它包含SQLPL语句,如果编译器遇到PL/SQL语句,则会抛出语法错误


当使用DB2命令行处理器运行程序时,可以使用命令集SQLCOMPAT{DB2 | PLSQL}显式指示方言。

在一个块中混合使用DB2SQLPL和PL/SQL语法;你必须从中选择一个并坚持下去。我认为你用这句话引导我走上了正确的道路——我没有意识到其中的差异,因为我来自Oracle PL/SQL的背景。一段精简的代码可以工作:将serveroutput设置在@begin for s上,作为mystat光标用于选择记录类型,序列代码从my|U状态获取前2行只调用dbms|U输出;结束于;end@I不得不说,IBM的文档并不好。for结构显示在它们的PL/SQL页面下;他们关于WHILE结构的文档是完全错误的,以此类推。再次感谢mustaccio-现在更有意义了。我仍然不知道为什么像%FOUND结构这样的东西失败了,因为我认为它是PL/SQL兼容的。这是当我把FOR的东西注释掉的时候,但是因为我让它朝着正确的方向工作,所以我不担心它。OPEN/FETCH变量和FOR变量都在IBM的PL/SQL页面中,这导致了很多混乱许多其他声明调用dbms_output.enable100000;STATLOOP:s作为select的mystat光标 记录类型、顺序代码和状态表中的其他字段-仅获取前1000行-大量逻辑,包括一些插入到另一个表端的数据;结束@