Читать «Язык PL/SQL» онлайн - страница 88

Иван Сергеевич Задворьев

Динамический SQL в PL/SQL в основном применяется для решения следующих задач:

выполнение DDL-команд (CREATE, ALTER, DROP);

поддержка нерегламентированных SQL-запросов (SQL ad hoc queries).

«Создать табличку» в программе PL/SQL нельзя:

SQL> BEGIN

2 CREATE TABLE tab1(at1 INTEGER);

3 END;

4 /

CREATE TABLE tab1(at1 INTEGER);

*

ERROR at line 2:

ORA-06550: line 2, column 3:

PLS-00103: Encountered the symbol "CREATE" when expecting

one of the following: (begin case declare exit for goto if loop pragma …

По префиксу PLS видно, что ошибку выдал компилятор PL/SQL, а из текста сообщения следует, что она произошла на этапе синтаксического анализа кода программы. Даже в грамматике языка PL/SQL не предусмотрено наличие в коде PL/SQL команд, похожих на DDL-команды CREATE.

«…, но если очень хочется, то можно» – для это следует использовать динамический SQL, передавая DDL-команду как символьную строку:

SQL> BEGIN

2 EXECUTE IMMEDIATE 'CREATE TABLE tab1(at1 INTEGER)';

3 END;

4 /

PL/SQL procedure successfully completed.

SQL> SELECT * FROM tab1;

no rows selected

Выборка из tab1 проходит без ошибок, значит, таблица существует.

Нерегламентированные запросы SQL

Нерегламентированным является SQL-запрос, у которого до этапа выполнения могут быть не определены следующие три составляющие:

текст SQL-запроса, включая список таблиц во фразе FROM, критерий отбора данных во фразе WHERE, фразы группировки и сортировки;

перечень возвращаемых столбцов;

список параметров.

Примером выполнения нерегламентированных SQL-запросов может быть подбор моделей телефонов по параметрам, похожий на соответствующий сервис на «Яндекс.Маркете».

Пусть таблица моделей телефонов имеет следующий вид:

CREATE TABLE phone_models (model VARCHAR2(100),

LTE INTEGER,

dual_sim INTEGER,

price INTEGER,

color VARCHAR2(100));

INSERT INTO phone_models VALUES('Xiaomi Redmi Note 2',1,1,12500,'black');

INSERT INTO phone_models VALUES('Meizu M2 mini',1,1,11400,'white');

Один человек может подбирать себе телефон по двум параметрам «вид – смартфон, цена – в пределах 10 000 – 15 000 рублей», другой человек может подбирать модель не по двум, а по трем параметрам «LTE – да, две SIM-карты – да, цвет – черный». Приложению потребуется сформировать и выполнить в базе данных два разных SQL-запроса. Для первого поиска это будет SQL-запрос с тремя связываемыми переменными:

SELECT * FROM phone_models

WHERE type=:p_1

AND price BETWEEN :p2 AND :p3

со значениями переменных :p1='smartphone', :p2=10000, :p3=15000.

Для второго поиска это будет SQL-запрос тоже с тремя связываемыми переменными, но для других ограничений:

SELECT * FROM phone_models

WHERE LTE=:p_1

AND dual_sim=:p2 AND color=:p3

со значениями переменных :p1=1, :p2=1, :p3='black'

Механизмы выполнения динамического SQL в PL/SQL

Для выполнения динамического SQL в PL/SQL есть два механизма:

встроенный динамический SQL (Native Dynamic SQL, NDS);