Динамический SQL
SQL-дескрипторы
SQL-дескриптор - это область, которая временно создается СУБД для хранения информации о параметрах откомпилированного SQL-оператора.
SQL-дескриптор используется для описания параметров как во фразе USING, так и во фразе INTO оператора EXECUTE.
Для каждого откомпилированного SQL-оператора создается своя область SQL-дескриптора.
SQL-дескрипторы могут быть использованы для следующих целей:
- определения параметров при выполнении SQL-оператора;
- получения информации об INTO-переменных;
- применения в динамических курсорах.
SQL-дескриптор состоит из элементов. Каждый динамический параметр описывается одним элементом, который представляет собой структуру, состоящую из списка полей, причем некоторые из них могут отсутствовать или не использоваться (в зависимости от типа элемента и от реализации). Приведем описание наиболее существенных полей элемента SQL-дескриптора:
Работа с SQL-дескриптором состоит из следующих этапов:
- Создание SQL-дескриптора оператором ALLOCATE DESCRIPTOR ;
- Задание значений для SQL-дескриптора может выполняться:
- Использование значений динамических параметров:
- Освобождение SQL-дескриптора оператором DEALLOCATE DESCRIPTOR.
Рассмотрим более подробно все этапы работы с SQL-дескриптором.
Создание SQL-дескриптора выполняется оператором ALLOCATE DESCRIPTOR , который в стандарте SQL-92 имеет следующее формальное описание:
ALLOCATE DESCRIPTOR descriptor_name [ WITH MAX count_of_inctances ];
Этот оператор создает область SQL-дескриптора для хранения информации о динамических параметрах.
Фраза WITH MAX позволяет установить максимально допустимое число элементов SQL-дескриптора.
Например:
EXEC SQL ALLOCATE DESCRIPTOR descr1 WITH MAX 4;
Этот оператор создает SQL-дескриптор descr1, который может применяться для откомпилированного оператора, использующего не более четырех динамических параметров.
Инициализация SQL-дескриптора выполняется одним из следующих SQL-операторов:
Начальную инициализацию возможно выполнить посредством оператора DESCRIBE , что значительно проще, а затем изменить требуемые поля с помощью оператора SET DESCRIPTOR .
Оператор DESCRIBE имеет в стандарте SQL-92 следующее формальное описание:
DESCRIBE [ INPUT | OUTPUT ] operator_sql USING SQL DESCRIPTOR descriptor_name;
Этот оператор сохраняет в предварительно созданном SQL-дескрипторе информацию о динамических параметрах откомпилированного SQL-оператора.
Фраза INPUT указывает, что инициируется SQL-дескриптором для динамических переменных связи (входные параметры для сервера).
Фраза OUTPUT указывает, что инициируется SQL-дескриптором для динамических INTO-переменных (выходные параметры от сервера). По умолчанию используется опция OUTPUT.
При выполнении оператора DESCRIBE для каждого элемента устанавливаются значения полей TYPE, NAME, UNNAMED и NULLABLE, а также полей, более точно специфицирующих конкретный тип данных ( LENGTH, PRECISION и т.п.).
Например:
stmt1 :='SELECT f1, f2 FROM tbl1 INTO ?, ? WHERE f2= 1'; EXEC SQL ALLOCATE DESCRIPTOR descr1 WITH MAX 2; EXEC SQL DESCRIBE OUTPUT :stmt1 USING SQL DESCRIPTOR descr1;
В результате таких действий при инициализации SQL-дескриптора descr1 будет создано два элемента со значениями полей NAME f1 и f2.
Хотя SQL-дескриптор для динамических переменных связи также можно инициировать оператором DESCRIBE , но сами значения этих переменных, хранимые в полях DATA, оператором DESCRIBE установить нельзя. Для этой цели можно использовать оператор SET DESCRIPTOR , который имеет в стандарте SQL-92 следующее формальное описание:
SET DESCRIPTOR [ GLOBAL | LOCAL ] descriptor_name { COUNT = integer_value } | { VALUE number_of_element field_of_element = value} .,:};
Этот оператор может выполнять одно из следующих действий:
- изменять количество элементов, описываемых SQL-дескриптором, для чего используется фраза COUNT ;
- изменять значение полей конкретного элемента, указываемого его номером ( number_of_element ).
Значения полей NAME, RETURNED_LENGHT, NULLABLE, RETURNED_OCTET_LENGHT, COLLATION_CATALOG, COLLATION_SCHEMA и COLLATION_NAME нельзя изменить с помощью оператора SET DESCRIPTOR .
Например:
stmt1 :='SELECT f1, f2, f3 FROM tbl1 INTO ?, ?, ? WHERE f2= 1'; EXEC SQL ALLOCATE DESCRIPTOR descr1 WITH MAX 2; EXEC SQL DESCRIBE OUTPUT :stmt1 USING SQL DESCRIPTOR descr1; EXEC SQL SET DESCRIPTOR descr1 VALUE 3 TYPE=1, LENGTH=15;
Таким образом, третий динамический параметр будет иметь тип CHARACTER и длину 15 символов.
Если при создании SQL-дескриптора для откомпилированного оператора не используется оператор DESCRIBE , то перед установкой значений полей каждого элемента следует задать количество элементов дескриптора (фраза COUNT ). Иногда для этого может потребоваться выполнение синтаксического разбора динамически сформированного SQL-оператора, чего можно избежать, применяя оператор DESCRIBE .
Значения любых полей элементов SQL-дескриптора выполняются оператором GET DESCRIPTOR , который имеет в стандарте SQL-92 следующее формальное описание:
GET DESCRIPTOR [ GLOBAL | LOCAL ] descriptor_name { integer_variable= COUNT } | { VALUE number_of_element variable = field_ of_element } .,:};
Например:
EXEC SQL SET DESCRIPTOR descr1 VALUE 3 TYPE=1, LENGTH=15; EXEC SQL GET DESCRIPTOR descr1 VALUE 3 :var_type = TYPE, :var_lenght = LENGTH;
При выполнении такого SQL-оператора в переменную var_type будет занесено значение 1, а в переменную var_lenght - значение 15.
Значения полей DATA SQL-дескриптора можно получить только после выполнения оператора EXECUTE.
Например:
str1:='SELECT f3 FROM tbl1 INTO ? WHERE f2 = 1'; EXEC SQL PREPARE stmt1 FROM :str1; EXEC SQL ALLOCATE DESCRIPTOR descr1 WITH MAX 1; EXEC SQL DESCRIBE OUTPUT stmt1 USING SQL DESCRIPTOR descr1; EXEC SQL EXECUTE stmt1 INTO SQL DESCRIPTOR descr1; GET DESCRIPTOR descr1 VALUE 1 :f1=DATA :fnull=NULLABLE;