Опубликован: 05.01.2004 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 9:

Встроенный SQL

< Лекция 8 || Лекция 9: 123 || Лекция 10 >

Переменные связи

Переменные связи (bind-переменные) служат для передачи значений в СУБД. Эти переменные могут использоваться во фразе WHERE для вычисления условия, в операторах INSERT и DELETE для определения устанавливаемых значений.

Переменные связи, так же как и INTO-переменные, перед применением должны быть предварительно объявлены. Переменные связи при указании их в SQL-операторе предваряются символом "двоеточие".

Например:

EXEC SQL INSERT INTO tbl2 (f1,f2,f3) 
         VALUES (:f1,:f2,:f3);

Курсоры

Под курсором, как правило, понимают получаемый при выполнении запроса результирующий набор и связанный с ним указатель текущей записи. Курсор - это объект, связанный с определенной областью памяти. Существуют явные и неявные курсоры.

Явный курсор имеет имя и перед использованием должен быть объявлен. Неявный курсор создается автоматически и его нельзя повторно открыть без перекомпиляции оператора запроса.

Объявление курсора выполняется оператором DECLARE CURSOR, в котором фраза FOR определяет запрос, ассоциируемый с данным курсором.

Например, оператор

EXEC SQL DECLARE c1 CURSOR FOR 
     SELECT f1,f2,f3 FROM tbl1 WHERE f2>100;

создает курсор c1 на базе таблицы tbl1. При объявлении курсора выполнения запроса не происходит. Выполнение запроса и создание курсора инициируется оператором OPEN CURSOR.

Например, оператор

EXEC SQL OPEN CURSOR с1;

создаст курсор, выполнив определенный в нем оператор SELECT.

Приложение получает доступ к данным курсора при последовательном извлечении строк результирующего набора в переменные приложения.

Для извлечения данных из курсора используется оператор FETCH

Например, оператор

EXEC SQL FETCH c1 INTO :f1,:f2,:f3;

извлекает значения текущей строки курсора в INTO-переменные.

Для освобождения памяти, выделенной под курсор, его следует закрыть, выполнив оператор CLOSE CURSOR.

Например:

EXEC SQL CLOSE CURSOR с1;
Обработка NULL-значений

Для работы с NULL-значениями предусмотрены индикаторные переменные, которые могут использоваться для:

  • определения извлекаемого NULL-значения;
  • внесения NULL-значения в таблицу;
  • фиксирования усекаемых строк.

Если в результате выполнения оператора FETCH или оператора SELECT (возвращающего одну строку) извлекаемые данные принимают значение NULL, то, во-первых, считается, что SQL-оператор выполнен с ошибкой, а во-вторых, в INTO-переменную будет записано значение, отличное от NULL (зависит от типа переменной). Для предотвращения таких ситуаций применяются индикаторные переменные, указываемые после INTO-переменной через символ двоеточия (или INDICATOR:). Если индикаторная переменная принимает отрицательное значение, значит, столбец содержит значение NULL. По умолчанию до выполнения оператора индикаторной переменной присваивается значение 0.

Например:

Если в операторе INSERT или UPDATE требуется указать, что используемая переменная связи может содержать значение NULL, то после этой переменной через двоеточие следует записать индикаторную переменную. В этом случае при отрицательном значении индикаторной переменной в базу данных будет занесено значение NULL.

При фиксировании усекаемых строк в индикаторную переменную записывается первоначальная длина строки, а сама строка записывается в переменную основного языка с усечением.

Позиционированные операторы

Для обновления курсора в операторах DELETE и UPDATE может использоваться фраза WHERE CURRENT OF, определяющая, что действие относится к текущей строке курсора. Такой оператор называется позиционированным , и к нему предъявляются следующие требования:

  • и курсор, и оператор должны использовать только одну и ту же таблицу;
  • в запросе, используемом для создания курсора, не должно быть фраз UNION и ORDER BY ;
  • курсор должен удовлетворять критериям обновляемого курсора (например, не применять агрегирующие функции).

Например:

EXEC SQL DECLARE c1 CURSOR FOR SELECT f1,f2 FROM tbl1;
EXEC SQL OPEN CURSOR c1;
EXEC SQL FETCH c1 INTO :f1,:f2;
EXEC SQL UPDATE tbl1 SET f2=f2*1.3 
         WHERE CURRENT OF c1;

Позиционированный оператор DELETE удобно использовать для удаления из таблицы группы строк, предварительно выбранных в курсор.

Обработка ошибок

Стандартом SQL-92 определено две переменных, которые позволяют получать информацию о выполняемом SQL-операторе:

  • переменная SQLSTATE имеет тип char(5) и содержит информацию о классе (два старших символа) и подклассе (3 младших символа), описывающих состояние выполненного SQL-оператора;
  • переменная SQLCODE имеет целочисленный тип и содержит код завершения последнего выполненного SQL-оператора.

Как и другие переменные, используемые во встроенном SQL, переменные SQLSTATE и SQLCODE предварительно должны быть объявлены. Однако переменная SQLCODE может быть создана по умолчанию, если нет объявления другой переменной, получающей информацию о завершении выполнения SQL-оператора.

После выполнения SQL-оператора данные о статусе и коде выполнения автоматически записываются СУБД в эти переменные.

Статус выполнения SQL-оператора может быть определен как:

  • успешное завершение. Соответствует в SQLSTATE коду '00000' (класс '00' ). SQLCODE в этом случае тоже равна 0;
  • успешное завершение с предупреждением. Класс состояния '02' в SQLSTATE определяет предупреждение 'NOT FOUND' ; класс состояния '01' указывает предупреждение, более точно специфицируемое подклассом;
  • завершение с ошибкой. Классы '03' и последующие в SQLSTATE описывают различные ошибочные ситуации (подклассы специфицируют как стандартные ситуации, так и определяемые приложением).

Предупреждение 'NOT FOUND' указывает, что SQL-оператор не содержал ошибки, но не вернул ожидаемого результата. Например, сформированный результирующий набор не содержит ни одной строки, или оператор UPDATE не изменил ни одной строки.

Переменные SQLCODE и SQLSTATE очень часто используются в операторе while для завершения цикла и для выхода из него в случае возникновения ошибки.

Встроенный SQL поддерживает оператор WHENEVER, определяющий действия, которые будут выполнены при возникновении описанной ситуации. Этот оператор следует указывать до выполнения того SQL-оператора, чья обработка ошибок будет "перехватываться".

Оператор WHENEVER влияет на все выполняемые SQL-операторы.

Например:

EXEC SQL WHENEVER SQLERROR GOTO Err_1;
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL WHENEVER SQLWARNING CONTINUE;
EXEC SQL OPEN CURSOR c1;
EXEC SQL FETCH c1 INTO :f1,:f2,:f3;
:
err_1: std::cout<<'' SQLERROR'';
:
EXEC SQL CLOSE CURSOR c1;

Оператор WHENEVER определяет или метку, на которую будет выполнен переход при возникновении ошибки, или действие типа CONTINUE (продолжение выполнения), или процедуру обработки ошибок.

< Лекция 8 || Лекция 9: 123 || Лекция 10 >
Азамат Айтказин
Азамат Айтказин
Казахстан
Евгений Резниченко
Евгений Резниченко
Россия