Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с удалением таблиц (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 )
     REFERENCES
QUESTIONS (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.


Наверх

Титульная страница Поиск, карта сайта Написать письмо