Создание операторов динамического SQL
⇐ ПредыдущаяСтр 3 из 3 Операторы динамического SQL в отличие от операторов встроенного SQL формируются не на этапе компиляции, а на этапе выполнения приложения. Динамический SQL может применяться совместно с ODBC API или в рамках SQL/CLI, представляющего собой расширенный уровень соответствия стандарта SQL-99. Поддержка динамического SQL на начальном уровне соответствия стандарту SQL-92 не требуется. Операторы динамического SQL формируются как текстовые переменные. Например: Stmt1:='SELECT * FROM tbl1';Для динамического формирования оператора можно выполнять последовательное объединение строк. Операторы динамического SQL можно использовать:
Одношаговый интерфейс одношаговый интерфейс реализуется SQL-оператором EXECUTE IMMEDIATE, который имеет в стандарте SQL-92 следующее формальное описание: EXECUTE IMMEDIATE:variable;На оператор, указываемый переменной (variable), накладываются следующие ограничения:
Следующий пример иллюстрирует применение динамического SQL с одношаговым интерфейсом: stmt_str:= 'INSERT INTO ' || table_name || ' values (:f1,:f2,:f3)';EXEC SQL EXECUTE IMMEDIATE:stmt_str;Многошаговый интерфейс Оператор EXECUTE IMMEDIATE удобен для одноразового выполнения, но при необходимости неоднократного выполнения, например в цикле, одного и того же оператора, но с различными параметрами, более эффективно использовать многошаговый интерфейс, реализуемый операторами PREPARE и EXECUTE.
При выполнении оператора PREPARE, указываемый им SQL-оператор передается в СУБД. Далее выполняется синтаксический разбор оператора и строится план выполнения. После этого при каждом выполнении оператора EXECUTE используется уже "откомпилированный" SQL-оператор, что значительно повышает производительность. Дополнительно при выполнении оператора EXECUTE на сервер передаются значения переменных связи (если они есть), используемые, в частности, для вычисления предиката фразы WHERE. Оператор PREPARE имеет в стандарте SQL-92 следующее формальное описание: PREPARE [ GLOBAL | LOCAL ] operator_sql FROM string_variable;Параметр operator_sql определяет идентификатор SQL-оператора, указываемый далее для выполнения в операторе EXECUTE или для включения в курсор в операторах ALLOCATE CURSOR или DECLARE CURSOR. Параметр string_variable указывает строку, содержащую динамически сформированный текст SQL-оператора. Например: stmt_str:= 'INSERT INTO ' || table_name || ' values (:f1,:f2,:f3)';EXEC SQL PREPARE GLOBAL stmt1 FROM:stmt_str;Фразы GLOBAL и LOCAL определяют область видимости оператора: GLOBAL указывает, что оператор с данным идентификатором доступен всем процессам данного сеанса работы с СУБД, а LOCAL ограничивает доступ рамками данного выполняемого модуля (значение по умолчанию). Если, создаются два одноименных оператора, но один как GLOBAL, а другой как LOCAL, то СУБД создает два отдельных плана выполнения как для разных операторов. В противном случае при компиляции оператора с уже существующим именем просто строится новый план выполнения оператора. Для освобождения подготовленного SQL-оператора используется оператор DEALLOCATE PREPARE, который освобождает все ресурсы, занимаемые подготовленным SQL-оператором. Например: EXEC SQL DEALLOCATE PREPARE GLOBAL stmt1;Для выполнения откомпилированного SQL-оператора используется оператор EXECUTE, который в стандарте SQL-92 имеет следующее формальное описание:
Фраза INTO указывается в том случае, если выполняемый SQL-оператор представляет собой запрос, возвращающий одну строку. Динамические параметры Значения динамических параметров передаются на сервер каждый раз при выполнении откомпилированного SQL-оператора. Динамическими параметрами могут быть как переменные связи, так и INTO-переменные. динамические параметры можно использовать как во встроенном SQL, так и в динамическом SQL. динамические параметры задаются в тексте SQL-оператора символами знак вопроса (?). Стандарт не определяет максимально допустимое число динамических параметров. Как правило, СУБД могут иметь ограничения только на размер вводимого SQL-оператора. Например: stmt_str:='INSERT INTO tbl1 VALUES (?,?,?)';EXEC SQL PREPARE stmt2 FROM:stmt_str;При выполнении данного откомпилированного оператора вместо динамических параметров значения будут подставляться в порядке, указанном в SQL-операторе EXECUTE или в области SQL-дескриптора. Список значений для динамических параметров может быть указан:
Например: stmt_str1:='INSERT INTO tbl1 (f1,f2,f3) VALUES (?,?,?)';EXEC SQL PREPARE stmt2 FROM:stmt_str1;EXEC SQL EXECUTE stmt2 USING:f1,:f2,:f3;Значение переменных f1, f2 и f3 основного языка программирования будут переданы на сервер для выполнения откомпилированного оператора с идентификатором stmt2. Возможен вариант, когда откомпилированный оператор содержит динамические параметры и во фразе INTO оператора SELECT, и в предикате. Например: stmt_str2:='SELECT f1, f2, f3 FROM tbl1 INTO?,?,? WHERE f2=?';EXEC SQL PREPARE stmt3 FROM:stmt_str2;EXEC SQL EXECUTE stmt3 INTO:f1,:f2,:f3 USING:f4;Переменные f1, f2 и f3 основного языка программирования будут использованы как INTO-переменные, а значение переменной f4 будет передано на сервер для выполнения откомпилированного оператора с идентификатором stmt3. SQL-дескрипторы SQL-дескриптор - это область, которая временно создается СУБД для хранения информации о параметрах откомпилированного SQL-оператора. SQL-дескриптор используется для описания параметров как во фразе USING, так и во фразе INTO оператора EXECUTE.
Для каждого откомпилированного SQL-оператора создается своя область SQL-дескриптора. SQL-дескрипторы могут быть использованы для следующих целей:
SQL-дескриптор состоит из элементов. Каждый динамический параметр описывается одним элементом, который представляет собой структуру, состоящую из списка полей, причем некоторые из них могут отсутствовать или не использоваться (в зависимости от типа элемента и от реализации). Приведем описание наиболее существенных полей элемента SQL-дескриптора:
Работа с SQL-дескриптором состоит из следующих этапов:
Рассмотрим более подробно все этапы работы с SQL-дескриптором.
Создание SQL-дескриптора выполняется оператором ALLOCATE DESCRIPTOR, который в стандарте SQL-92 имеет следующее формальное описание: ALLOCATE DESCRIPTOR descriptor_name [ WITH MAX count_of_inctance ];Этот оператор создает область 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}.,…};Этот оператор может выполнять одно из следующих действий:
Значения полей 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;Динамические курсоры В динамическом SQL можно использовать не только курсоры встроенного SQL (создаваемые статически оператором DECLARE CURSOR), но и два дополнительных типа курсоров:
Объявляемые и размещаемые курсоры могут иметь динамические параметры. Для создания курсоров используются следующие операторы:
Например: str1:='INSERT INTO tbl1 VALUES (1,10) ';EXEC SQL ALLOCATE cur1 CURSOR FOR:str1;EXEC SQL PREPARE stmt1 FROM:str1;EXEC SQL DECLARE cur2 CURSOR FOR stmt1;Открываются и закрываются динамические курсоры, как и статически создаваемые, операторами OPEN и CLOSE. Но при открытии курсора, имеющего динамические параметры, должна быть указана фраза USING. Например: str1:='SELECT f2 FROM tbl1 WHERE f1=? ';EXEC SQL ALLOCATE cur1 CURSOR FOR:str1;EXEC SQL OPEN cur1 USING:f2;EXEC SQL FETCH cur1 INTO:f1;Во фразе INTO оператора FETCH может быть указан как список INTO-переменных, так и SQL-дескриптор.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|