【问题标题】:Why does CREATE TABLE appear to succeed but then fail under DBX?为什么 CREATE TABLE 看起来成功,但在 DBX 下却失败了?
【发布时间】:2011-11-14 05:45:27
【问题描述】:

我有一个连接到 Firebird 数据库的 DBExpress 连接,运行 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;

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

有谁知道是什么原因造成的,我该如何解决?

【问题讨论】:

  • 我不熟悉 DBX,我使用 IBX for Firebird,所以这是一条评论:确保提交用于创建表的事务。确保您的“New_TableDataset”是使用新事务激活的,而不是使用具有不同系统表视图的长期运行事务激活的。
  • 其他提示:我会将大多数 DDL 操作运行到自己的事务中,并在每个事务之后提交。事实上,某些工具中有一个选项可以“自动提交 DDL 操作”。而且我绝对不会将 DDL 与常规操作混为一谈。
  • 可能使用 TSqlQuery 组件而不是已弃用的 TSimpleDataset。
  • @No'am:已弃用?在哪个版本?因为它肯定不在 Delphi XE 中,而且 TSqlQuery 不是它的合适替代品。

标签: delphi firebird delphi-xe dbexpress


【解决方案1】:
  1. 这看起来像是一个纯粹的事务问题,SQLSQL2SQL3 在一个(或多个)事务中执行。并且交易至少在SQL 之后仍然有效。而New_TableDataset是在不同的事务中操作的,当然不会看到第一个事务的未提交的变化。
  2. 问题不是特定于 DataSnap / dbExpress,而是特定于驱动程序实现。所以,很高兴知道什么是驱动程序。并可选择联系驱动程序供应商技术支持。
  3. 做什么(纯属猜测):
    • 尝试将命令执行包含在显式事务控制中。这将(可能)保证交易在所需步骤后完成。
    • 尝试在SQL 和/或SQL2 之后执行COMMIT
    • 尝试使用TSQLQuery 而不是ExecuteDirect。希望所有命令都在一个事务中运行。

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

【讨论】:

  • 谢谢。将CREATE TABLE 放在它自己的显式事务中是可行的。
【解决方案2】:

ADO 也遇到过类似的问题,解决方法是:

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

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

【讨论】:

  • 除非这是驱动程序问题,否则建议“2”毫无用处。如果驱动程序那么糟糕,则应该更换它。至于“1”,应该增加它以指定 COMMIT 应该遵循 DDL(数据定义语言)语句 - 就目前而言,看起来 COMMIT 应该遵循所有 SQL 语句,这是完全错误的,因为它破坏了整个概念使用事务使多个操作成功或失败作为一个组。
  • @CosminPrund 我知道 2/ 似乎没用,但在我的情况下它是有效的,有时驱动程序不能那么容易更换,而且:它很容易测试。我同意你的 1/ 评论:我会编辑我的帖子。
猜你喜欢
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多