DB2, PL/SQL и курсоры (у IBM нет собственных страниц справки)

DB2, версия 10.5.

Мой курсор такой:

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

Любая попытка обойти его с помощью структуры FOR, как описано на веб-страницах IBM, например

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

DB21034E Команда была обработана как оператор SQL, поскольку она не была допустимой командой процессора командной строки. Во время обработки SQL он вернул: SQL0104N Обнаружен неожиданный токен "для" rst 10 rows only; ". Ожидаемые токены могут включать: "". NINE NUMBER=9. SQLSTATE=42601.

Поэтому я попытался сделать явное открытие и выборку в цикле, и это сработало - но это продолжалось бы вечно (то есть не приводило к ошибкам и прерываниям, когда доходило до последней из 10 записей), если бы я не вставил в явный счетчик в цикле. Отображение полей из данных доказало, что это циклы 1, 2, 3....9, 10, 10, 10, 10, 10.

Поэтому я попытался добавить "if stat%FOUND" в цикл и получил эту ошибку:

DB21034E Команда была обработана как оператор SQL, поскольку она не была допустимой командой процессора командной строки. Во время обработки SQL он вернул: SQL0104N Обнаружен неожиданный токен "%" после "ence_code; if stat". Ожидаемые токены могут включать: "IS". НОМЕР ЛИНИИ = 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 когда stat". Ожидаемые токены могут включать в себя: "IN". НОМЕР ЛИНИИ = 30. SQLSTATE = 42601

Меняя его на stat.%NOTFOUND (период как раз перед%) получил меня это:

DB21034E Команда была обработана как оператор SQL, поскольку она не была допустимой командой процессора командной строки. Во время обработки SQL он вернул: SQL0104N Неожиданный токен "stat.%NOTFOUND" был найден после "case when". Ожидаемые токены могут включать: "". НОМЕР ЛИНИИ = 30. SQLSTATE = 42601

И я попробовал exit when stat%NOTFOUND "дословно со страницы поддержки IBM. Это вызвало у меня похожую ошибку:

DB21034E Команда была обработана как оператор SQL, поскольку она не была допустимой командой процессора командной строки. Во время обработки SQL он вернул: SQL0104N Обнаружен неожиданный токен "EXIT" после "". Ожидаемые токены могут включать: "". НОМЕР ЛИНИИ = 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 ответ

Решение

DB2 для 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} явно указать диалект.

Другие вопросы по тегам