|
Программирование >> Sql: полное руководство
Коды классов ошибок, первый символ которых является цифрой от пяти до девяти (включительно) или буквой от I до Z (включительно), зарезервированы для нестандартных, специфических ошибок отдельных СУБД. То есть стандарт по-прежнему допускает различия между СУБД, однако большинство обычных ошибок, возникающих при выполнении инструкций SQL, охватывается стандартными кодами классов ошибок. По мере того как коммерческие СУБД переходят к использованию переменной SQLSTATE, один из самых неприятных факторов несовместимости между СУБД будет постепенно устраняться. Стандарт SQL2 позволяет получать дополнительную информацию диагностического характера с помощью инструкции get diagnostics (рис. 17.13). Благодаря этой инсгрукции программа, использующак встроенный SQL, может узнать, как завершилась последняя выполненная инструкция встроенного SQL, а также получить подробные сведения о возникшей ошибке. Поддержка инструкции get diagnostics требуется на уровнях Intermediate Level и Full Level совместимости со стандартом SQL2 и не требуется на уровне Entry На рис. 17.14 представлен текст той же программы на языке С, что и на рис. 17.12, но на этот раз в ней используется инструкция get diagnostics. Чтобы получить информацию о выполненной инструкции и о том, сколько произошло ошибок I- GET DIAGNOSTICS - базовая переменная = NUMBER- - MORE - COMMAND FUNCTION DYNAMIC FUNCTION --ROW COUNT- Чтобы получить информацию о конкретной ошибке GET DIAGNOSTICS EXCEPTION номер ошибки-1 базовая переменная = - -CONDITION NUMBER - - RETURNED SQLSTATE--CLASS ORIGIN- - SUBCLASS ORIGIN- -SERVER NAME- - CONNECTiON NAME- - CONSTRAINT CATALOG -CONSTRAINT SCHEMA - - CONSTRAINT NAME- - CATALOG NAME- SCHEMA NAME- - TABLE NAME- -COLUMN NAME- -CURSOR NAME- MESSAGE TEXT- MESSAGE LENGTH- -MESSAGE OCTET LENGTH Рис 17.13. Синтаксическа Ши GET DJJUSmSTXCS /* выполнить инструкцию DELETE и проверить наличие ошибок */ exec sql delete from salesreps where quota < 150000; if (strcmp(sqlca.sqlstate, 00000 )) goto error routine; /* инструкция DELETE выполнена успешно; проверить, сколько строк удалено */ exec sql get diagnostics :numrows = ROW COUNT; printf( Удалено строк: %ld\n , numrows); error routine: /* определить, сколько произошло ошибок */ exec sql get diagnostics :count = NUMBER; for (1 = 1;. 1 < count; i++) ( exec sql get diagnostics EXCEPTION :i :err = RETURNED SQLSTATE, :msg = MESSAGE TEXT; printf( Ошибка SQL № %d; код - %s сообщение - %s\n , 1, err, msg); exit (1); Рис. 17 14. Отрывок программы на яштС, в которой проверка ошибок осуществляется с использованием инструкции GET DIAGNOSTICS Инструкция WHENEVER Программисту быстро надоедает писать программы, в которых после каждой встроенной инструкции SQL приходится явно проверять значение переменной sqlcode. Для упрощения обработки ошибок во встроенном SQL имеется инструкция whenever (рис. 17.15). Она является не исполняемой инструкцией, а директивой для препроцессора SQL. Инструкция whenever дает препроцессору команду после каждой выполняемой инструкции SQL автоматически генерировать код, связанный с обработкой ошибок, и определяет, каким должен быть этот код. -WHENEVER SQLERROR -SQLWARNING-NOT FOUND - CONTINUE GOTO- GO TO- 1715. Синтаксическая диаграмма инструкции WHENEVER Имеется три формы инструкции whenever для трех различных ситуаций: Инструкция whenever sqlerror служит для обработки ситуаций, связанных с возникновением серьезных ошибок (отрицательные значения переменной sqlcode). Инструкция whenever sqlwarning служит для обработки ситуаций, связанных с юзникновением предупреждений (положительные значения переменной sqlcode). Инструкция whenever not found служит ДЛЯ обработки конкретного Предупреждения, генерируемого СУБД в случае, когда программа пытается извлечь результаты запроса, а их больше не осталось. Данная форма инструкции предназначена для одиночной инструкции select, а также для инструкции fetch и описывается ниже в настоящей главе. Следует отметить, что форма whenever SQLwarning отсутствует в стандарте SQL2, но имеется в большинстве коммерческих СУБД. Инструкция whenever (в любой из этих трех форм) может содержать одну из двух директив; директива goto указывает препроцессору осуществить переход к указанной метке; ш директива continue служит указанием не нарушать ход вьшолнения программы и осуществить переход к следующей ее инструкции (инструкции базового языка). Так как инструкция whenever является директивой препроцессора, ее действие может быть перекрыто другой инструкцией whenever, появляющейся в программе далее. На рис. 17.16 изображен отрывок программы, содержащий три инструкции whenever и четыре исполняемые инструкции SQL. Первая инструкция whenever вызывает переход к метке eirorl при возникновении ошибки в любой из двух инструкций delete. Ошибка в инструкции update приводит к передаче управления следующей инструкции программы. Ошибка в инструкции insert вызывает переход к лгетке еггог2. Как видно из этого примера, главным назначением инструкции whenever/continue является отмена действия предьвдущей инструкции whenever. ечес sql whenever sqlerror goto errorl; exec sql delete fron salesreps where quota < 150000; exec sql delete from customers where credit limit < 20000; exec sql whenever sqlerror continue; exec sql update salesreps set quota = quota * 1.05; exec sql whenever sqlerror goto error2; exec sql insert into salesreps fempl num, name, qjota) values (116, Jan Hamilton, 100000.00); errorl: printf( Ошибка инструкции DELETE: %ld\n , sqlca.sqlcode) , exit(l) ; error2. printf( Ошибка инструкции INSERT: %ld\n , sqlca.sqlcode) , exit (1); Рис /To i-. O-.JOb.> (i , J, fC , ,i 5
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |