Какой правильный способ проверить состояние SQL найден в ILE RPG?
При работе со встроенным SQL в RPG вы часто получаете курсор и dow
цикл для обработки всех строк в вашем результате. Условие в цикле как-то зависит от SQLCOD
и / или SQLSTT
какие глобально доступные переменные в SQLRPGLE-программе?
Но как правильно проверить эти значения? Некоторые предлагают SQLCOD = 0
другие not (SQLCOD = +100 or SQLSTT = '02000')
, Один не на всех предупреждениях, другой не на некоторых ошибках, так что я не доволен.
Чтобы проиллюстрировать, что я делаю с некоторым кодом:
Pmain B
D PI
Dmy_ds E DS extname(SOME_TABLE)
D qualified
/free
exec sql
DECLARE cur CURSOR FOR
SELECT *
FROM some_table;
exec sql
OPEN cur;
exec sql
FETCH cur
INTO :my_ds;
dow sql_found();
exec sql
FETCH cur
INTO :my_ds;
enddo;
exec sql
CLOSE cur;
/end-free
Pmain E
Psql_found B
D PI N
/free
// insert return statement here...
/end-free
Psql_found E
Здесь я ищу правильный оператор возврата, который заставит меня пройти по всем строкам, если не возникнет ошибка, и позволит мне уйти, когда возникнет ошибка. Бонусные баллы за какой-то достойный способ проверки на ошибки.
3 ответа
SQLSTATE лучше и рекомендуется IBM.
Справочник IBM по сообщениям и кодам SQL InfoCenter : концепции SQLCODE и SQLSTATE
SQLSTATE является предпочтительным стандартным кодом возврата.
SQLSTATE состоит из 5 символов, причем первые два байта идентифицируют класс условий.
- '00' = Безусловное успешное завершение
- '01' = Предупреждение
- '02' = нет данных
Все остальное является ошибкой. Я обычно проверяю только на "00".
Просто. Легко. Более портативный.
Использование SQLCODE часто включает списки кодов, которые, IMHO, менее удобны для разработчиков.
Пример:
Лично я обычно включаю определения и код вроде этого:
D xSQLState@ s * inz( %addr(SQLState) )
D xSQLState ds 5 based(xSQLState@)
D xSQLState2 2a
D
D Success_On_SQL C const('00')
D Warning_On_SQL C const('01')
D NoData_On_SQL C const('02')
Затем после любой операции SQL я вообще проверяю
if xSQLState2 <> Success_On_Sql;
someflag = true;
endif;
Рекомендуется обрабатывать ожидаемые SQLCODE (как часть ожидаемой обработки) и добавлять код исключения для обработки тех, которые вы не делаете. Одна реализация:
dow 1=1; // forever
exec sql
FETCH cur
INTO :my_ds;
// normal exit
if sqlstt = SQL_NODATA;
SFLEND = *on;
leave;
endif;
// can't CAST a value
if sqlstt = SQL_CAST; // CAST error
... tell user there's an error and read another
iter;
endif;
// decimal data error
if sqlstt = SQL_DDE;
tell user to call IT and stop reading
leave;
endif;
// whoops! not expected at all. Dump for post-mortem
if sqlstt <> SQL_NORMAL;
... tell user to call IT and stop reading
dump(a);
leave;
endif;
// test for end of loop
// filled subfile page?
enddo; // forever
При таком типе реализации вы должны намеренно выйти из цикла; заполнили ли вы страницу подфайла, загрузили самый высокий элемент в массиве или обнаружили ошибку. Я не уверен, что есть одна, общая реализация, которая будет обрабатывать все обстоятельства. Иногда вам может потребоваться выйти из цикла чтения, если у вас есть блокировка записи, а иногда вы хотите отправить сообщение и повторить попытку (например).
Я сделал еще несколько поисков по этой теме и нашел что-то на сайте IBM (цитата):
The SQLCODE is also set by the database manager after each SQL statement is executed as follows: - If SQLCODE = 0 and SQLWARN0 is blank, execution was successful. - If SQLCODE = 100, no data was found. For example, a FETCH statement returned no data, because the cursor was positioned after the last row of the result table. - If SQLCODE > 0 and not = 100, execution was successful with a warning. - If SQLCODE = 0 and SQLWARN0 = 'W', execution was successful with a warning. - If SQLCODE < 0, execution was not successful.
Что привело бы меня к sql_found()
как это:
Pfound_sql B
D PI N
/free
return (SQLCOD >= 0) and (SQLCOD<>100);
/end-free
Pfound_sql E
Это должно позаботиться о состоянии "Конец данных" и завершиться ошибкой при всех ошибках. Я не уверен, есть ли какие-то предупреждения, о которых я должен позаботиться (не хочу зацикливаться на бесконечном цикле, если есть предупреждение, которое приводит к тому, что он не читается).