Книга: Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
EXECUTE STATEMENT
Разделы на этой странице:
EXECUTE STATEMENT
Firebird 1.5 вводит расширение PSQL, поддерживающее выполняемые строки. Приложение или процедура могут передать оператор DSQL (DDL или DML) в виде строки входного аргумента (либо процедура может сконструировать эту строку как локальную переменную) для выполнения с использованием EXECUTE STATEMENT.
EXECUTE STATEMENT добавляет гибкости хранимым процедурам и триггерам, но с высоким риском ошибок. Возвращаемые значения жестко проверяются на типы данных, чтобы избежать непредсказуемых исключений преобразования данных. Например, строка '1234' может быть преобразована в целое, a 'abc' вызовет ошибку преобразования. Во время компиляции такая строка не может быть проанализирована и проверена.
Синтаксис:
[FOR] EXECUTE STATEMENT <строка>
[INTO :переменная1 [, :переменная2 [, :переменнаяN ] ] DO
<составной-оператор>];
<составной-оператор> = {оператор блок-операторов}
Конструирование выражения или строковой переменной для создания оператора DSQL в строке аргумента должно быть завершено к моменту выполнения EXECUTE STATEMENT. Выполняемый оператор DSQL в строке аргумента не может содержать никаких заменяемых параметров.
В своей простейшей форме EXECUTE STATEMENT выполняет оператор SQL, запрашивающий операцию, которая не возвращает строк данных, а именно:
* INSERT, UPDATE, DELETE;
* EXECUTE PROCEDURE;
* любой оператор DDL за исключением CREATE/DROP DATABASE. Например:
CREATE PROCEDURE EXEC_PROC (PROC_NAME VARCHAR (31))
AS
DECLARE VARIABLE SQL VARCHAR(1024);
DECLARE VARIABLE . . .
BEGIN
. . .
SQL = 'EXECUTE PROCEDURE ' || PROC_NAME;
EXECUTE STATEMENT SQL;
END ^
Процедура вызывает следующее:
EXECUTE PROCEDURE EXEC_PROC ( ' PROJECT_MEMBERS ' ) ;
Переменные значения в одиночном SELECT
Следующий фрагмент кода показывает, как выполнять строку оператора SELECT, который возвращает одну строку в набор переменных. Как и любой другой оператор SELECT в модуле PSQL, он вызовет исключение, если оператор вернет множество строк. Здесь мы также можем выполнить нечто невозможное в обычном PSQL: выполнить операцию, включающую таблицу или столбец, чье имя неизвестно во время компиляции:
CREATE PROCEDURE SOME_PROC
(TABLE_NAME VARCHAR (31), COL_NAME VARCHAR (31))
AS
DECLARE VARIABLE PARAM DATE;
BEGIN
EXECUTE STATEMENT 'SELECT MAX ( ' || COL_NAME || ') FROM ' || TABLE_NAME
INTO : PARAM;
. . .
FOR SELECT . . . . FROM . . . .
WHERE END_DATE = : PARAM
INTO ... DO
. . .
END ^
Переменные значения в многострочном SELECT
Синтаксис EXECUTE STATEMENT также поддерживает выполнение оператора SELECT внутри цикла FOR для возвращения по одной строки за раз в список переменных. Не существует ограничений на используемый оператор SELECT, однако помните, что во время компиляции синтаксический анализатор не может проверить содержимое строки.
CREATE PROCEDURE DYNAMIC_SAMPLE (
TEXT_COL VARCHAR(31),
TABLE_NAME VARCHAR (31))
RETURNS (LINE VARCHAR(32000))
AS
DECLARE VARIABLE ONE_LINE VARCHAR (100);
DECLARE VARIABLE STOP_ME SMALLINT;
BEGIN
LINE = ' ' ;
STOP_ME = 1;
FOR EXECUTE STATEMENT
'SELECT ' || TEXTCOL || ' FROM ' || TABLE_NAME
INTO :ONE_LINE DO
BEGIN
IF (STOP_ME > 320) THEN
EXIT;
IF (ONE_LINE IS NOT NULL) THEN
LINE = LINE || ONE_LINE || ' '
STOP_ME = STOP_ME + 1;
END
SUSPEND;
END ^
Предостережения
Средство EXECUTE STATEMENT предназначено только для очень осторожного использования и должно применяться с учетом всех факторов. Используемые в нем операции медленны и рискованны. Возьмите за правило применять его только в случае невозможности получить нужные результаты другими средствами или (что маловероятно) когда это действительно улучшает выполнение оператора. Будьте в курсе, что есть риск:
* не существует способа проверить синтаксис оператора в строке аргумента;
* не проверяются зависимости или существование защиты для предотвращения удаления или изменения таблиц или столбцов;
* операции выполняются медленно, потому что встроенный оператор должен подготавливаться на сервере каждый раз перед выполнением;
* если хранимая процедура имеет специальные привилегии к некоторым объектам, то динамический оператор, выдаваемый в строке EXECUTE STATEMENT, не наследует их. Используются те привилегии, которые имеет пользователь, выполняющий процедуру.