Почему CREATE TABLE, кажется, успешно, но затем терпит неудачу под DBX? - PullRequest
2 голосов
/ 14 ноября 2011

У меня есть соединение DBExpress, подключенное к базе данных Firebird, на котором работает Firebird Embedded. Пока все отлично работает, но происходит что-то очень странное.

У меня есть модуль данных, который содержит соединение и несколько TSimpleDataset объектов, представляющих разные таблицы. Но когда я пытаюсь добавить новую таблицу, она, кажется, работает, но затем терпит неудачу:

procedure Update(module: TdmDatabase);
const
   SQL = 'CREATE TABLE NEW_TABLE (blah blah blah)';
   SQL2 = 'ALTER TABLE NEW_TABLE ADD CONSTRAINT PK_NEW_TABLE PRIMARY KEY (blah)';
   SQL3 = 'DROP TABLE NEW_TABLE';
begin
   module.connection.ExecuteDirect(SQL);      //succeeds
   module.connection.ExecuteDirect(SQL2);     //succeeds
   try
     module.New_TableDataset.Active := true;  //fails
   except
     module.connection.ExecuteDirect(SQL3);   //succeeds
     raise;
   end;
end;

Когда я пытаюсь создать таблицу, она, кажется, работает, и я могу ALTER и DROP это нормально, но когда я пытаюсь открыть набор данных, который запускает SELECT, я получаю Ошибка «неверное имя таблицы». Если я запускаю его в отладчике и убиваю программу сразу после выполнения оператора CREATE TABLE, то проверяю базу данных, новой таблицы там нет.

Кто-нибудь знает, что может вызвать это, и как я могу это исправить?

Ответы [ 2 ]

4 голосов
/ 14 ноября 2011
  1. Это похоже на проблему чистой транзакции, где SQL, SQL2 и SQL3 выполняются в одной (или во многих) транзакции.И транзакция остается активной по крайней мере после SQLNew_TableDataset работает в другой транзакции, которая, конечно, не видит незафиксированных изменений первой транзакции.
  2. Проблема не в DataSnap / dbExpress, а в реализации драйвера.Итак, приятно знать, что такое водитель.И, возможно, обратитесь в службу технической поддержки поставщика драйверов.
  3. Что делать (чистое предположение):
    • Попытайтесь окружить выполнение команд явным управлением транзакциями.Это будет (может) гарантировать, что транзакция будет завершена после требуемого шага.
    • Попробуйте выполнить COMMIT после SQL и / или SQL2.
    • Попробуйте использовать TSQLQuery вместо ExecuteDirect.Надеемся, что все команды будут выполняться в одной транзакции.

PS: Наконец, рассмотрите возможность использования другого драйвера dbExpress или даже библиотеки доступа к данным.

0 голосов
/ 14 ноября 2011

У меня была похожая проблема с ADO, решение было:

1 / Как уже было сказано: выполните COMMIT после всех ваших DDL SQL.

2 / Когда первый CREATE в порядке, Сделать запрос SELECT (+ COMMIT) на созданную таблицу

...