Удаление внешних ключей

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

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

Ответить
RhinoFC
Сообщения: 11
Зарегистрирован: 17 ноя 2004, 09:36

Удаление внешних ключей

Сообщение RhinoFC » 17 мар 2005, 18:28

Есть скрипт на удаление объектов базы данных вида:

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

/* удаление хранимок */
drop stored procedure sp1
drop stored procedure sp2;
...

/* удаление триггеров */
drop trigger tr1;
drop trigger tr2;
...

/* Удаление внешних ключей */
alter table t1 drop constraint fk_t1;
alter table t2 drop constraint fk_t2;
...

/* Удаление таблиц */
drop table t1;
drop table t2;
...
Как только выполнение доходит до удаление внешних ключей, возникают ошибки. Выдает, что внешний ключ используется, хотя это не так, естественно. Если отключиться от базы и подключиться снова, то первый ключ удаляется, а дальше опять ошибка. Т.е. получается, что перед удалением каждого внешнего ключа нужно делать reconnect. В чем тут дело? Как лечить?

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

Сообщение Merlin » 17 мар 2005, 19:23

Ва-первых, таблицы распрекрасно дропаются вместе со всеми своими констрайнтами включая FK.
Ва-втарых, они же распрекрасно дропаются вместе со всеми своми триггерами.
В-третих, для удаления FK нужен монопольный доступ к базе и единственная активная в этом соединении транзакция.
В-паследних, когда-нибудь. Кто-нибудь. Из вопрощающих. НАУЧИТСЯ, НАКОНЕЦ, МЛИН, ГОВОРИТЬ, КАКУЮ ВЕРСИЮ СЕРВЕРА ОНИ ИСПОЛЬЗУЮТ? В FB1.5 достаточно коммит перед удаленим FK сделать, на более ранних дело действительно порой доходило до реконнекта. Причина вкратце - кеш метаданных и корректность работы сервера с ним.

Лысый
Сообщения: 177
Зарегистрирован: 08 ноя 2004, 08:20

Сообщение Лысый » 17 мар 2005, 21:41

>Merlin
Развернутый ответ - пример для подражания! :)

RhinoFC
Сообщения: 11
Зарегистрирован: 17 ноя 2004, 09:36

Сообщение RhinoFC » 18 мар 2005, 08:18

>Merlin

Ответ действительно развернутый. Но не все так просто.
Начну с конца:
4) Версия - IB7.0. Действительно надо было написать, сорри. Но вообще, это у меня IB7.0. А у клиентов разные, начиная с 5-й и выше. И скрипт этот должен работать везде.
3) Монопольный доступ и единственная транзакция - выполняется. Так и есть.
2) Да, с триггерами удаляются, если только нет какой-нибудь перекрестной зависимости (кстати, в предыдущем примере я сначала удаляю триггеры, а потом хранимки, а не так, как я написал). Например есть две таблицы T1 и T2. T1 имеет триггер, который зависит от некой хранимки SP1. Хранимка в свою очередь зависит от таблицы T2. А таблица T2, в свою очередь, зависит от T1 (например через внешний ключ или через триггер - не важно). Вот и получается, что сначала нужно удалить триггер таблицы T1, потом хранимку, потом можно будет удалить таблицу Т2 ну и Т1 после этого. Ну а для того, чтобы все эти зависимости не отслеживать при написании скрипта, просто дропаются все триггеры скопом, потом хранимки и т.д.
1) Вот ни хрена они не удаляются. Должны, но не хотят. Как только дело доходит до удаления первой таблицы, вылетает ошибка (используется таблица и все тут). Дисконнект, коннект - пошло. Пара таблиц удаляется, потом опять вылетает. До следующего реконнекта. И т.д. Ни какие commit'ы не помогают. Имя базы заранее неизвестно, поэтому делать реконнект непосредственно в скрипте не могу. Да и не хочу.

Ну и что делать?

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 18 мар 2005, 09:36

насчет пункта 2:
А если начать с alter procedure и сделать процедуру с одним единственным оператором exit, потом дропнуть таблицы, и напоследок дропнуть уже пустую процедуру?

RhinoFC
Сообщения: 11
Зарегистрирован: 17 ноя 2004, 09:36

Сообщение RhinoFC » 18 мар 2005, 09:49

> Ivan_Pisarevsky
А смысл? Что от этого изменится? Вылетает именно удаление таблиц, у которых есть внешние ключи. Есть у таблицы триггеры или нет их, это роли не играет. Именно внешние ключи, черт бы их побрал. Я уже пытался удалять внешние ключи отдельно - вылетает там.
Неужели ни у кого такого не возникало? Может у меня сервер кривой какой-нибудь? Ну ведь лажа какая-то, не должно такого быть! Сел в лужу на фигне какой-то. :cry:

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

Сообщение Merlin » 18 мар 2005, 12:51

Павтаряю: рация - на бронепоезде. In Use gри удалении таблицы с FK - это при попытке автоматического удаления её FK. В линии FB проблемы с удалением FK сведены к указанным условиям Самофатовым в FB1.5. Когда исправлено в IB и исправлено ли вообще, понятия не имею, им теперь трудно тянуть оперативно сложные модификации с FB, кодовые базы слишком разошлись. С перекрёстными зависимостями - да, случается и поколдовать, и не обязательно этим способом.

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

Сообщение kdv » 18 мар 2005, 14:23

to RinoFC: не плюй в колодец, как говорится. Тем более что Merlin не замечен (как минимум, в силу его возраста) в ошибках с русским языком. Описки у нас у всех бывают.

моя рекомендация - прогонять не сам скрипт, а использовать команды в скрипте для их поштучного выполнения программой. каждый оператор обрамлять StartTransaction/Commit. Ошибки обрабатывать.

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 18 мар 2005, 14:29

2) Да, с триггерами удаляются, если только нет какой-нибудь перекрестной зависимости (кстати, в предыдущем примере я сначала удаляю триггеры, а потом хранимки, а не так, как я написал). Например есть две таблицы T1 и T2. T1 имеет триггер, который зависит от некой хранимки SP1. Хранимка в свою очередь зависит от таблицы T2. А таблица T2, в свою очередь, зависит от T1 (например через внешний ключ или через триггер - не важно). Вот и получается, что сначала нужно удалить триггер таблицы T1, потом хранимку, потом можно будет удалить таблицу Т2 ну и Т1 после этого. Ну а для того, чтобы все эти зависимости не отслеживать при написании скрипта, просто дропаются все триггеры скопом, потом хранимки и т.д.
alter procedure sp1 as begin exit; end
drop table t1
drop table t2
drop procedure sp1

Что я не так говорю?

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

Сообщение Merlin » 18 мар 2005, 14:30

На самом деле я в последнее время действительно специально пошаливаю с орфографией, будучи в хорошем настроении. Может и зря, конечно, когда не со своими.

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

Сообщение kdv » 18 мар 2005, 15:00

Что я не так говорю?
commit после каждого оператора надо.

RhinoFC
Сообщения: 11
Зарегистрирован: 17 ноя 2004, 09:36

Сообщение RhinoFC » 18 мар 2005, 15:23

не плюй в колодец, как говорится. Тем более что Merlin не замечен (как минимум, в силу его возраста) в ошибках с русским языком
Да шут с ней, с орфографией. Я не про орфографию, а про бронепоезд. Мне просто это неуважительным показалось (я там рация или бронепоезд?), я ответил тем же. Прошу прощения, но я тоже не маленький мальчик. Но, мне кажется, в итоге мы с Мерлином поняли друг друга и больше ругаться не будем :wink: .
моя рекомендация - прогонять не сам скрипт, а использовать команды в скрипте для их поштучного выполнения программой. каждый оператор обрамлять StartTransaction/Commit. Ошибки обрабатывать
Т.е. написать модернизированный и улучшенный скриптер, который бы выкупал и исправлял ошибки IB. Нет, это конечно можно попробовать, только времени жалко. Я просто думал, что я не знаю чего, хитрости какой-нибудь.
alter procedure sp1 as begin exit; end
drop table t1
drop table t2
drop procedure sp1

Что я не так говорю?
Все так. Только в моем случае скрипт вылетит на второй строчке. По причине присутствия там внешних ключей. А в остальном все нормально.


Вообще я рассчитывал получить ответ в виде:
Это лечится так...
или
Это глюк IB. Не лечится ни как. Ищи обходные пути.

Но если это глюк, который не исправляется в течение семи! версий, то надо действительно сваливать на FB. Уж таких глюков в нормальном сервере БД быть не должно.

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

Сообщение kdv » 18 мар 2005, 15:34

Прошу прощения, но я тоже не маленький мальчик.
только без обид, ладно? это например я имею право возмутиться, когда мне начинают на что-то указывать не по делу. потому что то, что я сделал - видно (www.ibase.ru и т.п.). И Merlin-а тоже видно, потому что он не спрашивает, а отвечает, причем количество его полезных ответов здесь огромно. А пока ты только спрашиваешь, причем отвечаешь "полупрочитав" ответ - ты остаешься вопрошающим, с совершенно непонятной квалификацией. И фраза "рация на бронепоезде" общеизвестна, и нисколько не оскорбительна.
При виртуальном общении невозможно передать эмоции в тексте письма (даже смайликами). Так что, be patient.
Последний раз редактировалось kdv 18 мар 2005, 16:12, всего редактировалось 1 раз.

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

Сообщение Merlin » 18 мар 2005, 15:41

kdv писал(а): только без обид, ладно?
Харош засорять форум, а то модеру пожалуюсь :lol: На самом деле мне пофиг, что вопрошающий обо мне думает. Не в состоянии понять ответ - его проблема. Отстутствие чувства юмора, незнание классических анекдотов, повышенная чувствительность - тоже его проблема :lol:

RhinoFC
Сообщения: 11
Зарегистрирован: 17 ноя 2004, 09:36

Сообщение RhinoFC » 18 мар 2005, 15:47

только без обид, ладно?
Понял, отстал. Сдаюсь, получил по шее. :) А анекдота такого я действительно не знаю.

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

Сообщение kdv » 18 мар 2005, 16:09

мистика. почему я написал "на бронепоизде"? это заразно? :)

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

Сообщение Merlin » 18 мар 2005, 16:20

kdv писал(а):мистика. почему я написал "на бронепоизде"? это заразно? :)
Похоже на то :) При твоей-то абсолютной врождённой грамотности :) Я-то буквы стал местами переставлять и лишние продавливать после того, как на левой два пальца парализовало, она, стерва, отстаёт при стучании по клаве. Можно я ему этот анек сокращённо расскажу, жалко ведь человека, признанный фольклор IB/FB сообщества :lol:

Прапор проводит курс молодого бойца.

- А вот здесь на бронепоезде установлена рация.
- Товарищ прапорщик, а рация на лампах или на транзисторах?
- Повторяю: рация - на бронепоезде

Ответить