То, что сказал Чарльз, а также я считаю, что в некоторых случаях вы можете даже создать бесконечный цикл с этим кодом! Возможно, вы не передаете весь код, но если выборка прошла успешно (SQLCOD = 0) и a <> b, то вы застряли в цикле.
Мне нравится помещать выборку в подпроцедуру, которая возвращает * On, если запись успешно прочитана. Тогда вы можете сделать что-то вроде этого:
dcl-proc MyProc;
dcl-pi *n;
... parameters ...
end-pi;
C1_OpenCursor(parameters);
dow C1_FetchCursor(record);
... do something with the record ...
enddo;
C1_CloseCursor();
end-proc;
// ------------------------
// SQL Open the cursor
dcl-proc C1_OpenCursor;
dcl-pi *n;
... parameters ...
end-pi;
exec sql
declare C1 cursor for ...
exec sql
open C1;
if SQLCOD < 0;
.. error processing ...
endif;
end-proc;
// ------------------------
// SQL Read the cursor
dcl-proc C1_FetchCursor;
dcl-pi *n Ind;
... parameters ...
end-pi;
exec sql
fetch C1 into ...
if SQLCOD = 100;
return *Off;
elseif SQLCOD < 0;
... error handling ...
return *Off;
endif;
return *On;
end-proc;
// ------------------------
// SQL Close the cursor
dcl-proc C1_CloseCursor;
exec sql close C1;
end-proc;
Это позволяет вам хранить весь код вашей базы данных в одном месте и просто вызывать его из вашей программы. Процедуры базы данных просто обращаются к базе данных и каким-то образом сообщают об ошибках. Логика вашей программы может оставаться загроможденной иногда многословной базой данных и кодом обработки ошибок.
Еще одна вещь, я не проверяю ошибки при закрытии курсора, потому что единственная ошибка (кроме ошибок синтаксиса), которая может быть возвращена здесь, состоит в том, что курсор не открыт. Мне все равно, потому что это то, чего я хочу в любом случае.