Страница 1 из 1
Удаление внешних ключей
Добавлено: 17 мар 2005, 18:28
RhinoFC
Есть скрипт на удаление объектов базы данных вида:
Код: Выделить всё
/* удаление хранимок */
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. В чем тут дело? Как лечить?
Добавлено: 17 мар 2005, 19:23
Merlin
Ва-первых, таблицы распрекрасно дропаются вместе со всеми своими констрайнтами включая FK.
Ва-втарых, они же распрекрасно дропаются вместе со всеми своми триггерами.
В-третих, для удаления FK нужен монопольный доступ к базе и единственная активная в этом соединении транзакция.
В-паследних, когда-нибудь. Кто-нибудь. Из вопрощающих. НАУЧИТСЯ, НАКОНЕЦ, МЛИН, ГОВОРИТЬ, КАКУЮ ВЕРСИЮ СЕРВЕРА ОНИ ИСПОЛЬЗУЮТ? В FB1.5 достаточно коммит перед удаленим FK сделать, на более ранних дело действительно порой доходило до реконнекта. Причина вкратце - кеш метаданных и корректность работы сервера с ним.
Добавлено: 17 мар 2005, 21:41
Лысый
>Merlin
Развернутый ответ - пример для подражания!

Добавлено: 18 мар 2005, 08:18
RhinoFC
>Merlin
Ответ действительно развернутый. Но не все так просто.
Начну с конца:
4) Версия - IB7.0. Действительно надо было написать, сорри. Но вообще, это у меня IB7.0. А у клиентов разные, начиная с 5-й и выше. И скрипт этот должен работать везде.
3) Монопольный доступ и единственная транзакция - выполняется. Так и есть.
2) Да, с триггерами удаляются, если только нет какой-нибудь перекрестной зависимости (кстати, в предыдущем примере я сначала удаляю триггеры, а потом хранимки, а не так, как я написал). Например есть две таблицы T1 и T2. T1 имеет триггер, который зависит от некой хранимки SP1. Хранимка в свою очередь зависит от таблицы T2. А таблица T2, в свою очередь, зависит от T1 (например через внешний ключ или через триггер - не важно). Вот и получается, что сначала нужно удалить триггер таблицы T1, потом хранимку, потом можно будет удалить таблицу Т2 ну и Т1 после этого. Ну а для того, чтобы все эти зависимости не отслеживать при написании скрипта, просто дропаются все триггеры скопом, потом хранимки и т.д.
1) Вот ни хрена они не удаляются. Должны, но не хотят. Как только дело доходит до удаления первой таблицы, вылетает ошибка (используется таблица и все тут). Дисконнект, коннект - пошло. Пара таблиц удаляется, потом опять вылетает. До следующего реконнекта. И т.д. Ни какие commit'ы не помогают. Имя базы заранее неизвестно, поэтому делать реконнект непосредственно в скрипте не могу. Да и не хочу.
Ну и что делать?
Добавлено: 18 мар 2005, 09:36
Ivan_Pisarevsky
насчет пункта 2:
А если начать с alter procedure и сделать процедуру с одним единственным оператором exit, потом дропнуть таблицы, и напоследок дропнуть уже пустую процедуру?
Добавлено: 18 мар 2005, 09:49
RhinoFC
> Ivan_Pisarevsky
А смысл? Что от этого изменится? Вылетает именно удаление таблиц, у которых есть внешние ключи. Есть у таблицы триггеры или нет их, это роли не играет. Именно внешние ключи, черт бы их побрал. Я уже пытался удалять внешние ключи отдельно - вылетает там.
Неужели ни у кого такого не возникало? Может у меня сервер кривой какой-нибудь? Ну ведь лажа какая-то, не должно такого быть! Сел в лужу на фигне какой-то.

Добавлено: 18 мар 2005, 12:51
Merlin
Павтаряю: рация - на бронепоезде. In Use gри удалении таблицы с FK - это при попытке автоматического удаления её FK. В линии FB проблемы с удалением FK сведены к указанным условиям Самофатовым в FB1.5. Когда исправлено в IB и исправлено ли вообще, понятия не имею, им теперь трудно тянуть оперативно сложные модификации с FB, кодовые базы слишком разошлись. С перекрёстными зависимостями - да, случается и поколдовать, и не обязательно этим способом.
Добавлено: 18 мар 2005, 14:23
kdv
to RinoFC: не плюй в колодец, как говорится. Тем более что Merlin не замечен (как минимум, в силу его возраста) в ошибках с русским языком. Описки у нас у всех бывают.
моя рекомендация - прогонять не сам скрипт, а использовать команды в скрипте для их поштучного выполнения программой. каждый оператор обрамлять StartTransaction/Commit. Ошибки обрабатывать.
Добавлено: 18 мар 2005, 14:29
Ivan_Pisarevsky
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
Что я не так говорю?
Добавлено: 18 мар 2005, 14:30
Merlin
На самом деле я в последнее время действительно специально пошаливаю с орфографией, будучи в хорошем настроении. Может и зря, конечно, когда не со своими.
Добавлено: 18 мар 2005, 15:00
kdv
Что я не так говорю?
commit после каждого оператора надо.
Добавлено: 18 мар 2005, 15:23
RhinoFC
не плюй в колодец, как говорится. Тем более что Merlin не замечен (как минимум, в силу его возраста) в ошибках с русским языком
Да шут с ней, с орфографией. Я не про орфографию, а про бронепоезд. Мне просто это неуважительным показалось (я там рация или бронепоезд?), я ответил тем же. Прошу прощения, но я тоже не маленький мальчик. Но, мне кажется, в итоге мы с Мерлином поняли друг друга и больше ругаться не будем

.
моя рекомендация - прогонять не сам скрипт, а использовать команды в скрипте для их поштучного выполнения программой. каждый оператор обрамлять StartTransaction/Commit. Ошибки обрабатывать
Т.е. написать модернизированный и улучшенный скриптер, который бы выкупал и исправлял ошибки IB. Нет, это конечно можно попробовать, только времени жалко. Я просто думал, что я не знаю чего, хитрости какой-нибудь.
alter procedure sp1 as begin exit; end
drop table t1
drop table t2
drop procedure sp1
Что я не так говорю?
Все так. Только в моем случае скрипт вылетит на второй строчке. По причине присутствия там внешних ключей. А в остальном все нормально.
Вообще я рассчитывал получить ответ в виде:
Это лечится так...
или
Это глюк IB. Не лечится ни как. Ищи обходные пути.
Но если это глюк, который не исправляется в течение семи! версий, то надо действительно сваливать на FB. Уж таких глюков в нормальном сервере БД быть не должно.
Добавлено: 18 мар 2005, 15:34
kdv
Прошу прощения, но я тоже не маленький мальчик.
только без обид, ладно? это например я имею право возмутиться, когда мне начинают на что-то указывать не по делу. потому что то, что я сделал - видно (
www.ibase.ru и т.п.). И Merlin-а тоже видно, потому что он не спрашивает, а отвечает, причем количество его полезных ответов здесь огромно. А пока ты только спрашиваешь, причем отвечаешь "полупрочитав" ответ - ты остаешься вопрошающим, с совершенно непонятной квалификацией. И фраза "рация на бронепоезде" общеизвестна, и нисколько не оскорбительна.
При виртуальном общении невозможно передать эмоции в тексте письма (даже смайликами). Так что, be patient.
Добавлено: 18 мар 2005, 15:41
Merlin
kdv писал(а):
только без обид, ладно?
Харош засорять форум, а то модеру пожалуюсь

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

Добавлено: 18 мар 2005, 15:47
RhinoFC
только без обид, ладно?
Понял, отстал. Сдаюсь, получил по шее.

А анекдота такого я действительно не знаю.
Добавлено: 18 мар 2005, 16:09
kdv
мистика. почему я написал "на бронепоизде"? это заразно?

Добавлено: 18 мар 2005, 16:20
Merlin
kdv писал(а):мистика. почему я написал "на бронепоизде"? это заразно?

Похоже на то

При твоей-то абсолютной врождённой грамотности

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