2011-11-14 49 views
2

我有一个DBExpress连接连接到Firebird数据库,运行Firebird Embedded。目前为止一切正常,但有些奇怪的事情正在发生。为什么CREATE TABLE显示成功,但在DBX下失败?

我有一个数据模块,其中包含连接和一些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语句运行后立即终止程序,那么检查数据库,新表不在那里。

任何人都知道可能会导致什么,以及我如何解决它?

+0

我不熟悉的DBX做一个SELECT查询(+ COMMIT),我使用IBX的火鸟,所以这是一个注释:确保你提交你用来创建表的事务。确保使用新事务激活了“New_TableDataset”,但未使用具有不同系统表视图的长时间运行的事务激活它。 –

+0

其他提示:我会将大多数DDL操作运行到自己的事务中,在每个事务之后进行提交。事实上在某些工具中有一个选项来“自动提交DDL操作”。而且我绝对不会将DDL与常规操作混合使用。 –

+0

也许使用TSqlQuery组件而不是已弃用的TSimpleDataset。 –

回答

4
  1. 这看起来像一个纯粹的交易问题,其中SQLSQL2SQL3在一个(或多个)事务正在执行。至少在SQL之后交易仍然有效。并且正在不同的交易中操作,当然这并不会看到第一笔交易的未被改变的变化。
  2. 该问题不是DataSnap/dbExpress特定的,而是驱动程序实现特定的。所以,很高兴知道驱动程序是什么。并可以选择联系驱动程序供应商技术支持。
  3. 怎么办(纯粹推测):
    • 尝试将命令执行包围为明确的事务控制。这将(可能)保证,交易在需要的步骤后完成。
    • 尝试在SQL和/或SQL2之后执行COMMIT。请使用TSQLQuery而不是ExecuteDirect。希望所有命令都可以在单个事务中运行。

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

+0

谢谢。将CREATE TABLE放入自己的显式事务中。 –

0

我曾与ADO类似的问题,解决办法是:

1 /作为又说道:执行所有DDL SQL后提交。

2 /当第一个CREATE是确定的,在创建表

+1

除非这是一个驱动程序问题,否则建议“2”是无用的。如果司机不好,应该更换。至于“1”,应该增加指定COMMIT应该遵循DDL(数据定义语言)语句 - 因为它看起来像COMMIT应该遵循所有的SQL语句,这是明显错误的,因为它破坏了整个概念使用事务,以便多个操作成功或失败。 –

+0

@CosminPrund我知道2 /似乎没用,但在我的情况下它是有效的,有时驱动程序不能被轻松替换,等等:它很容易测试。我对你的1 /评论还可以:我会编辑我的帖子。 – philnext

相关问题