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