Создание таблицы в скрипте Firebird вызывает неудачное обновление метаданных с тупиковой блокировкой

У меня есть следующий скрипт, который я запускаю, используя "isql -i scriptfile.sql":

CONNECT C:\Databasefile.fdb USER user PASSWORD password;

SET TERM !! ;
EXECUTE BLOCK AS BEGIN
IF (EXISTS(SELECT 1 FROM rdb$relations WHERE rdb$relation_name = 'MYTABLE')) THEN
EXECUTE STATEMENT 'DROP TABLE MYTABLE;';
END!!
SET TERM ; !!

CREATE TABLE MYTABLE 
(
  MYCOLUMN      VARCHAR(14) NOT NULL
);

В самый первый раз, когда я запускаю это (когда таблица еще не существует), таблица создается, как и ожидалось. Если я снова запускаю скрипт, я получаю следующую ошибку:

Statement failed, SQLCODE = -607
unsuccessful metadata update
-STORE RDB$RELATIONS failed
-deadlock
After line 8 in file d:\myscript.sql

Когда скрипт завершает работу, MYTABLE удаляется и больше не может быть найден в базе данных. Если я запускаю сценарий в третий раз, таблица снова создается, и никаких ошибок не возникает.

Почему скрипт не может одновременно удалить и заново создать таблицу?


person GTHvidsten    schedule 12.12.2014    source источник


Ответы (1)


DDL из PSQL не разрешен, использование EXECUTE STATEMENT прямо не запрещено, и обычно возможно, но все же неразумно именно из-за такого рода проблем. Я не совсем уверен в причинах, но частично это связано с тем, как изменения DDL применяются в Firebird; использование оператора execute добавляет дополнительные блокировки iirc, которые конфликтуют с последующим DDL для того же имени таблицы.

Вместо того, чтобы удалять и создавать таким образом, вы должны использовать оператор DDL RECREATE TABLE вместо этого.

Обратите внимание, что слово взаимоблокировка в этой ошибке на самом деле является неправильным (настоящей взаимоблокировки не существует).

person Mark Rotteveel    schedule 12.12.2014
comment
RECREATE, кажется, добился цели. Похоже, что ALTER TABLE, который у меня есть сразу после RECREATE, чтобы добавить некоторые ограничения внешнего ключа, тоже работает. Спасибо :) - person GTHvidsten; 12.12.2014
comment
@GTHvidsten Добро пожаловать. Обратите внимание, что на самом деле вам не нужно изменять таблицу для добавления ограничений: вы можете сделать это внутри (повторно) создать таблицу. - person Mark Rotteveel; 12.12.2014
comment
Да, я знаю, но так просто скопировать DDL из Database Workbench ;) - person GTHvidsten; 12.12.2014