![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с удалением таблиц (IB7, D7) [D7, IB7]
TheEd © (2006-02-08 07:08:00)Господа мастера, подскажите плиз, есть 2 трабла одного рода:
1. Создаю таблицу в IBExpert с помощью запроса:
CREATE TABLETMP12333452 (
QMID INTEGER
NOT NULL PRIMARY KEY,
QID INTEGER,
FOREIGN KEY (QID )
REFERENCESQUESTIONS (QID )
ON DELETE CASCADE
ON UPDATE CASCADE);
после commit не могу удалить таблицу до перегрузки IBExpert! :(
2. В D7 создаю ту же таблицу:
TmpTbl := 'TMP_' + IntToStr(Random(High(i))); // i : integer; TmpTbl : string;
// RunSQL - процедура, выполняющая SQL-запрос
RunSQL(Format('CREATE GENERATOR GEN_%s_ID', [TmpTbl]));
RunSQL(Format(
'CREATE TABLE %s ('
+ ' QMID INTEGER'
+ ' NOT NULL,'
+ ' PRIMARY KEY,'
+ ' QID INTEGER)', [TmpTbl])); // foreign key не использую - иначе таблицу не убьешь по той же причине что и в (1.)
RunSQL(Format(
'CREATE TRIGGER %s_BI FOR %s '
+ 'ACTIVE BEFORE INSERT POSITION 0 '
+ 'AS '
+ 'BEGIN '
+ ' IF (NEW.QMID IS NULL) THEN'
+ ' NEW.QMID = GEN_ID(GEN_%s_ID,1);'
+ 'END', [TmpTbl, TmpTbl, TmpTbl]));
RunSQL('commit'); // или так
// DM.ibTA.CommitRetaining; // или так, где DM.ibTA : TTransaction
...
// наполняем TmpTbl данными
...
// *
// в следующем запросе формирую набор данных, в котором
// участвует TmpTbl (join)
qu.Close; // qu : TIBQuery
quQuest.SQL.Clear;
quQuest.SQL.Add('SELECT * FROM Questions');
quQuest.SQL.Add(' JOIN ' + TmpTbl);
quQuest.SQL.Add(' ON Questions.QID = ' + TmpTbl + '.QID');
quQuest.SQL.Add(' ORDER BY QMID');
quQuest.Open;
quQuest.FetchAll;
// если от * до данной строки закомментировать, то проблемы не будет, однако даже если запрос закрыть:
// quQuest.Close;
// то это не поможет сделать это:
RunSQL('DROP TRIGGER ' + TmpTbl + '_BI'); // убиваем триггер
RunSQL('delete from RDB$GENERATORS where RDB$GENERATOR_NAME = ''GEN_' + TmpTbl + '_ID'''); // убиваем генератор
RunSQL('commit'); // на всякий случай подтверждаем
// DM.ibTA.CommitRetaining; // можно и так (DM.ibTA : TTransaction)
RunSQL('DROP TABLE ' + TmpTbl); // убиваем таблицу
RunSQL('commit'); // болт! не работает!
// DM.ibTA.CommitRetaining;
помогите разобраться, что "держит" таблицы и как их убить?
TheEd (2006-02-09 10:24:00) [1]
> >Мысль была такая - создать временную таблицу,
> Плохая мысль. Практически всегда можно без этого обойтись.
> >набить данными упорядоченными как необходимо,
> Зачем упорядочивать? Смысл?
нужно выбрать из M записей N штук в случайном порядке, напр. для проведения тестирования вопросы. Естественно M >= N. Изначально пошел по пути формирования именно набора данных уже готового, с порядком следования записей в не по ключевому полю, а "перемешанному", с последующим линейным продвижением по данному НД. Конечно, можно было бы скакать по НД случайным образом до перебора всех RecNo, но не хочется теперь огород городить.
> Частое применение DDL запросов требует регулярного backup/restore.
это типа мусор может оставаться?
> >возможно ли убить таблицу если она в join'е с другой таблицей?
> Это как???
напр. так:
SELECT * FROM Table1
JOIN Table2
ON Table1.KeyField = Table2.SomeField
ORDER BY Table2.KeyField
этот запрос назначаем TIBQuery, делаем Open, работаем, потом Close, после чего выполняем DROP Table2. Вот он и не работает, хотя соответствующий TIBQuery зактыт.
Johnmen (2006-02-08 14:13:00) [2]>Мысль была такая - создать временную таблицу,
Плохая мысль. Практически всегда можно без этого обойтись.
>набить данными упорядоченными как необходимо,
Зачем упорядочивать? Смысл?
Частое применение DDL запросов требует регулярного backup/restore.
>возможно ли убить таблицу если она в join'е с другой таблицей?
Это как???
ЗЫ
См. хранимые процедуры
Desdechado (2006-02-08 12:58:00) [3]Если таблица используется,то, естественно, нельзя ее убить!
TheEd (2006-02-08 12:45:00) [4]
> Johnmen © (08.02.06 09:26) [3]
> 1. DDL запросы тоже выполняются в рамках транзакций. Перезагрузка
> Эксперта это перестарт транзакции. *
> 2. >// болт! не работает!
> Это такое сообщение выдаётся? **
* - прикол в том, что я пытался делать реконнект из Эксперта, там есть пункты такие. Не проходит. Может он неполный, хотя странно... Эксперт вроде весьма продвинутое приложение, глюков не замечал.
** - нет, это выдаёт юзер, что бы не матерится (правила форума не нарушать :)
> Sergey13 © (08.02.06 09:27) [4]
> Если сервер не поддерживает нормальные временные таблицы,
> то не стоИт их так эмулировать. *Создай постоянную с идентифицирующим
> полем и используй ее нормально. **И нафига вообще временные
> таблицы с ссылочной целостностью.
* - уже думал так делать, но из принципа разобраться хочется.
** - в принципе можно без неё, более того, тогда она удаляется, но если только не выполняется этот кусок кода (см [0]):
> qu.Close; // qu : TIBQuery
> quQuest.SQL.Clear;
> quQuest.SQL.Add('SELECT * FROM Questions');
> quQuest.SQL.Add(' JOIN ' + TmpTbl);
> quQuest.SQL.Add(' ON Questions.QID = ' + TmpTbl + '.
> QID');
> quQuest.SQL.Add(' ORDER BY QMID');
> quQuest.Open;
> quQuest.FetchAll;
причём quQuest не для апдейтов.
Мысль была такая - создать временную таблицу, набить данными упорядоченными как необходимо, выполнить select из другой таблицы с join'ом по данной, убить временную, и работать с полученным в select'е набором данных (только чтение). Можно конечно сначало поработать а потом временную таблицу убить, но надо понять принцип - возможно ли убить таблицу если она в join'е с другой таблицей?
Desdechado (2006-02-08 11:24:00) [5]Все дело в том, что
1. метаданные кэшируются сервером при подключении
2. внешние ключи могут держать (именно ключи, а не данные).
Часто это требует переподключения, никуда то особенностей сервера не деться.
Sergey13 (2006-02-08 09:27:00) [6]Если сервер не поддерживает нормальные временные таблицы, то не стоИт их так эмулировать. Создай постоянную с идентифицирующим полем и используй ее нормально. И нафига вообще временные таблицы с ссылочной целостностью.
Johnmen (2006-02-08 09:26:00) [7]1. DDL запросы тоже выполняются в рамках транзакций. Перезагрузка Эксперта это перестарт транзакции.
2. >// болт! не работает!
Это такое сообщение выдаётся?
TheEd (2006-02-08 08:54:00) [8]
> ККВ (08.02.06 07:50) [1]
>
> Держит FOREIGN KEY
я понял это к пункту 1.
я пытался убить отдельно его:
ALTER TABLE TMP12333452 DROP CONSTRAINT INTEG_117
где INTEG_117 - имя целостности, соответствующей данному ключу,
но он неубиваем до перегрузки IBExpert :(
немного странно...
ККВ (2006-02-08 07:50:00) [9]Держит FOREIGN KEY.