Добрый день.
Есть БД на Firebird 3.
Задача: выполнить SQL-скрипт с DDL операторами внутри и в случае ошибки, полностью откатиться.
Внимательно изучив
документацию, пришел к выводу, что реализация подобной затеи вполне возможна.
Установка скрипта производится с помощью процедуры:
create or alter procedure EXECUTE_SCRIPT (
I_SCRIPT blob sub_type 1 segment size 80 not null)
returns (
ERR smallint)
as
declare variable V_COMMAND blob sub_type 1 segment size 80;
begin
ERR = 0;
begin
for
select COMMAND
from SPLIT_SCRIPT(:I_SCRIPT)
into :V_COMMAND
do
execute statement(V_COMMAND);
when any do
ERR = 1;
end
end
В данном случае
SPLIT_SCRIPT
разбивает исходный скрипт на отдельные команды, удаляет смену терминатора в начале, коммит в конце и удаляет сам терминатор в конце команд.
Вот скрипт, который хочу выполнить:
Полный текст скриптаset term ^;
create table test_table1 (
id integer,
name varchar(30)
)^
create or alter procedure test_proc1 (
I_ID integer,
I_NAME varchar(30) character set UTF8)
returns (
O_MSG varchar(30) character set UTF8)
as
begin
insert into test1 (id, name)
values(:i_id, :i_name);
o_msg = 'Запись №' || i_id || ' с именем ' || i_name || ' вставлена!';
suspend;
end^
commit^
Результат выполнения процедуры SPLIT_SCRIPTcreate table test_table1 (
id integer,
name varchar(30)
)
create or alter procedure test_proc1 (
I_ID integer,
I_NAME varchar(30))
returns (
O_MSG varchar(30))
as
begin
insert into test1 (id, name)
values(:i_id, :i_name);
o_msg = 'Запись №' || i_id || ' с именем ' || i_name || ' вставлена!';
suspend;
end
Как видите, во второй команде (создание процедуры) намеренно допущена ошибка в названии таблицы при вставке, чтобы вызвать исключение.
Далее несколько цитат из документации (стр. 495):
Внутренне автоматические точки сохранения используется для:
• отмены всех действий внутри блока BEGIN ... END, где происходит исключение;
Сами по себе блок BEGIN..END не создаёт автоматическую точку сохранения. Она создаётся
только в блоках, которых присутствует блок WHEN для обработки исключений или ошибок.
На первый взгляд условия соблюдены, ничего криминального, однако при выполнении процедуры
EXECUTE_SCRIPT
и последующем коммите, таблица все-таки создается, чего быть не должно.
Или я что-то упустил?