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

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

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

Сообщение WildSery » 22 июн 2006, 14:46

После очередного изменения структуры базы исчезла необходимость в одной из таблиц. Но таблицу удалить я не могу сразу, т.к. на неё ссылается 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.
Подскажите, куда смотреть?

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 22 июн 2006, 15:25

Если работаешь в IB Expert, в окне таблицы есть закладка "Зависимости". Посмотри там.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 июн 2006, 15:31

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;

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 22 июн 2006, 15:33

Ты ПРОВЕРЯЛ зависимости на соответствующей закладке?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 июн 2006, 15:35

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 22 июн 2006, 15:36

значит, что-то окривело в системных таблицах. я бы покопался в relation_constraints.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 июн 2006, 15:50

В relation_constraints всего три записи на SERTREG:
constraint_name constraint_type
INTEG_34 NOT NULL
FK_SERTREG FOREIGN KEY
PK_SERTREG PRIMARY KEY

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 22 июн 2006, 15:54

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

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 июн 2006, 16:03

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 22 июн 2006, 16:16

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

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

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 22 июн 2006, 17:47

В общем, починил, но судя по всему, вернуться к идее пересоздания базы придётся. Что-то внутри определённо сломано.
Я в ступоре. Описываю процесс.
Разбирательство показало, что на одну и ту же пару системных триггеров с именем 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?
Последний раз редактировалось WildSery 23 июн 2006, 10:50, всего редактировалось 1 раз.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 22 июн 2006, 18:26

Несвоевременный коммит какого-то DDL?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 23 июн 2006, 10:49

Merlin писал(а):Несвоевременный коммит какого-то DDL?
Теперь уже не выяснишь.

Ответить