为什么 CREATE TABLE 看似成功,但在 DBX 下却失败?

发布于 2024-12-15 18:32:05 字数 893 浏览 3 评论 0原文

我有一个连接到运行 Firebird Embedded 的 Firebird 数据库的 DBExpress 连接。到目前为止一切正常,但发生了一些非常奇怪的事情。

我有一个数据模块,其中包含连接和一些代表不同表的 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;

当我尝试创建表时,它似乎可以工作,我可以ALTERDROP 它很好,但是当我尝试打开一个对其运行 SELECT 的数据集时,我收到“无效的表名称”错误。如果我在调试器下运行它并在 CREATE TABLE 语句运行后立即终止程序,然后检查数据库,则新表不存在。

任何人都知道可能导致此问题的原因以及我该如何解决它?

I've got a DBExpress connection connected to a Firebird database, running Firebird Embedded. Everything works fine so far, but something very strange is going on.

I've got a data module that contains the connection and a handful of TSimpleDataset objects representing different tables. But when I try to add a new table, it appears to work but then fails:

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;

When I try to create the table, it appears to work, and I can ALTER and DROP it just fine, but when I try to open a dataset that runs a SELECT against it, I get an "invalid table name" error. If I run it under the debugger and kill the program immediately after the CREATE TABLE statement runs, then inspect the database, the new table isn't there.

Anyone know what could cause that, and how I can fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅冕 2024-12-22 18:32:05
  1. 这看起来像是一个纯粹的事务问题,其中 SQLSQL2SQL3 在一个(或多个)事务中执行。并且事务至少在 SQL 之后保持活动状态。而New_TableDataset是在不同的事务中操作的,这当然看不到第一个事务的未提交的更改。
  2. 该问题不是特定于 DataSnap / dbExpress 的,而是特定于驱动程序实现的。所以,很高兴知道驱动程序是什么。并可选择联系驱动程序供应商技术支持。
  3. 该怎么做(纯粹猜测):
    • 尝试将命令执行置于显式事务控制中。这将(可能)保证交易在所需步骤后完成。
    • 尝试在 SQL 和/或 SQL2 之后执行 COMMIT
    • 尝试使用TSQLQuery而不是ExecuteDirect。希望所有命令都在单个事务中运行。

PS:最后考虑使用不同的dbExpress驱动程序甚至数据访问库。

  1. That looks like a pure transaction issue, where SQL, SQL2 and SQL3 are executing in one (or in many) transaction. And the transaction remains acive at least after SQL. And New_TableDataset is operating in different transaction, which of course does not see uncommited changes of the first transaction.
  2. The issue is not a DataSnap / dbExpress specific, but rather the driver implementation specific. So, good to know what is the driver. And optionally to contact the driver vendor technical support.
  3. What to do (pure speculation):
    • Try to surround the command executions into explicit transaction control. That will (may) guarantee, that the transaction is finished after required step.
    • Try to execute COMMIT after SQL and/or SQL2.
    • Try to use TSQLQuery instead of ExecuteDirect. Hopefully all commands will run in a single transaction.

PS: Finally consider to use different dbExpress driver or even data access library.

情域 2024-12-22 18:32:05

我在使用 ADO 时遇到了类似的问题,解决方案是:

1/ 如上所述:在所有 DDL SQL 之后执行 COMMIT。

2/ 当第一次CREATE OK后,对创建的表进行SELECT查询(+COMMIT)

I have had a similar problem with ADO, the solution was :

1/ As yet said : execute COMMIT after all your DDL SQL.

2/ When the first CREATE is OK, Make a SELECT query (+COMMIT) on the created table

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文