Страница 1 из 1

Помогите удалить Foreign Key

Добавлено: 22 июн 2006, 14:46
WildSery
После очередного изменения структуры базы исчезла необходимость в одной из таблиц. Но таблицу удалить я не могу сразу, т.к. на неё ссылается FK на другой, рабочей, таблице.
FK каскадного типа, firebird 1.0.3
При попытке удаления FK

Код: Выделить всё

ALTER TABLE SERTREG DROP CONSTRAINT FK_SERTREG;
возникает ошибка

Код: Выделить всё

This operation is not defined for system tables.
unsuccessful metadata update.
ERASE RDB$RELATION_CONSTRAINTS failed.
action cancelled by trigger (1) to preserve data integrity.
Cannot delete trigger used by a CHECK Constraint.
Подскажите, куда смотреть?

Добавлено: 22 июн 2006, 15:25
CyberMax
Если работаешь в IB Expert, в окне таблицы есть закладка "Зависимости". Посмотри там.

Добавлено: 22 июн 2006, 15:31
WildSery
IBExpert - мой любимый инструмент.
Т.к. таблица под удаление, то у неё нет никаких зависимостей.
Сама таблица и FK объявлены так

Код: Выделить всё

CREATE TABLE SERTREG (
    SGID       INTEGER DEFAULT 0 NOT NULL,
    SFID       INTEGER
);
ALTER TABLE SERTREG ADD CONSTRAINT PK_SERTREG PRIMARY KEY (SGID);
ALTER TABLE SERTREG ADD CONSTRAINT FK_SERTREG FOREIGN KEY (SFID) REFERENCES SERTIF (SFID) ON DELETE CASCADE ON UPDATE CASCADE;

Добавлено: 22 июн 2006, 15:33
CyberMax
Ты ПРОВЕРЯЛ зависимости на соответствующей закладке?

Добавлено: 22 июн 2006, 15:35
WildSery
Я думал, из моего ответа это очевидно. Да, проверял.
Кстати, добавлю к вышесказанному, что точно такая же ошибка возникает, если удалять не сам FK, а собственно таблицу SERTREG.

Добавлено: 22 июн 2006, 15:36
kdv
значит, что-то окривело в системных таблицах. я бы покопался в relation_constraints.

Добавлено: 22 июн 2006, 15:50
WildSery
В relation_constraints всего три записи на SERTREG:
constraint_name constraint_type
INTEG_34 NOT NULL
FK_SERTREG FOREIGN KEY
PK_SERTREG PRIMARY KEY

Ничего необычного не вижу.
Уважаемый kdv, искать нужно что-то конкретное?

Добавлено: 22 июн 2006, 15:54
kdv
Уважаемый kdv, искать нужно что-то конкретное?
фиг знает. это же случайная ошибка, а не "регулярная". Что там куда затесалось - можно только воочию увидеть. индекс на FK/PK целый? в rdb$triggers эти check (на каскадное обновление-удаление) целые?

Добавлено: 22 июн 2006, 16:03
WildSery
Ага. Вижу хвост собаки. Chek'а то и нет. На эту таблицу вообще никаких записей в rdb$triggers нет.
Теперь у меня два вопроса:
1. Как его всё же удалить? Руками из rdb$ вычистить?
2. Как перенести тему в "Ремонт БД"?

Добавлено: 22 июн 2006, 16:16
kdv
1. Как его всё же удалить? Руками из rdb$ вычистить?
попробуй сначала в rdb$ref_constraints для этого FK поставить update_rule и delete_rule в RESTRICT. Потом попробуй удалить FK.

хотя, редактировать ref_constraints сервер не дает....
короче, как бы не пришлось создавать новую БД из скрипта и переносить туда данные.
Как перенести тему в "Ремонт БД"?
это я могу, но как бы, не совсем это "ремонт БД" :-)

Добавлено: 22 июн 2006, 17:47
WildSery
В общем, починил, но судя по всему, вернуться к идее пересоздания базы придётся. Что-то внутри определённо сломано.
Я в ступоре. Описываю процесс.
Разбирательство показало, что на одну и ту же пару системных триггеров с именем CHECK_9 и CHECK_10, которые должны обеспечивать ссылочную целостность, ссылаются как FK_SERTREG, так и check с именем INTEG_236 с другой таблицы (!) LININV, причём тела триггеров определённо для check, а не FK.

Теперь, как я "лечил".
В rdb$triggers создал копию CHECK_9 и CHECK_10 (на всякий случай, с другими именами, 109 и 110).
Создал второй FK2 такой же структуры на SERTREG (FK_SERTREG2), к нему создались системные триггеры CHECK_33 и CHECK_34.
Затем попробовал проапдейтить rdb$triggers CHECK_9 и CHECK_10 значениями из новых триггеров - получил отлуп, сервер не даёт редактировать системные триггеры.
Убил копии CHECK_109 и CHECK_110.
Далее, зашёл в LININV и попробовал убить check INTEG_236. Убился, причём триггера CHECK_9 и CHECK_10 остались.
После этого попробовал убить FK_SERTREG и о чудо! у меня получилось. Радостный, я сразу попробовал прибить и второй, созданный мной в начале "лечения". Облом! Та же ошибка.
Уже зная, куда смотреть, нашёл, что на триггеры CHECK_33 и CHECK_34 теперь ссылается другой check, INTEG_164 из третьей таблицы, который к тому же виден на закладке Checks :?
Уже прибив его руками в rdb$check_constraints (сервер дал это сделать, хотя на свежей базе, без моих манипуляций, не даёт его же грохнуть) мне удалось прибить и FK_SERTREG2.

Исходя из всей эпопеи, у меня сложилось впечатление, что сбился какой-то внутренний генератор для нумерации триггеров CHECK_n.
Кто-нибудь прокомментирует?
Как можно посмотреть (и изменить, возможно) значение системного генератора, например, RDB$CONSTRAINT_NAME?

Добавлено: 22 июн 2006, 18:26
Merlin
Несвоевременный коммит какого-то DDL?

Добавлено: 23 июн 2006, 10:49
WildSery
Merlin писал(а):Несвоевременный коммит какого-то DDL?
Теперь уже не выяснишь.