为什么CREATE TABLE显示成功,但在DBX下失败?
我有一个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;
当我试图创建表,它似乎工作,我可以ALTER
和DROP
它只是罚款,但是当我尝试打开一个对其运行SELECT
的数据集,我收到“无效的表名”错误。如果我在调试器下运行它,并在CREATE TABLE
语句运行后立即终止程序,那么检查数据库,新表不在那里。
任何人都知道可能会导致什么,以及我如何解决它?
- 这看起来像一个纯粹的交易问题,其中
SQL
,SQL2
和SQL3
在一个(或多个)事务正在执行。至少在SQL
之后交易仍然有效。并且正在不同的交易中操作,当然这并不会看到第一笔交易的未被改变的变化。 - 该问题不是DataSnap/dbExpress特定的,而是驱动程序实现特定的。所以,很高兴知道驱动程序是什么。并可以选择联系驱动程序供应商技术支持。
- 怎么办(纯粹推测):
- 尝试将命令执行包围为明确的事务控制。这将(可能)保证,交易在需要的步骤后完成。
- 尝试在
SQL
和/或SQL2
之后执行COMMIT
。请使用TSQLQuery
而不是ExecuteDirect
。希望所有命令都可以在单个事务中运行。
PS:最后考虑使用不同的dbExpress驱动程序,甚至数据访问库。
谢谢。将CREATE TABLE放入自己的显式事务中。 –
我曾与ADO类似的问题,解决办法是:
1 /作为又说道:执行所有DDL SQL后提交。
2 /当第一个CREATE是确定的,在创建表
除非这是一个驱动程序问题,否则建议“2”是无用的。如果司机不好,应该更换。至于“1”,应该增加指定COMMIT应该遵循DDL(数据定义语言)语句 - 因为它看起来像COMMIT应该遵循所有的SQL语句,这是明显错误的,因为它破坏了整个概念使用事务,以便多个操作成功或失败。 –
@CosminPrund我知道2 /似乎没用,但在我的情况下它是有效的,有时驱动程序不能被轻松替换,等等:它很容易测试。我对你的1 /评论还可以:我会编辑我的帖子。 – philnext
我不熟悉的DBX做一个SELECT查询(+ COMMIT),我使用IBX的火鸟,所以这是一个注释:确保你提交你用来创建表的事务。确保使用新事务激活了“New_TableDataset”,但未使用具有不同系统表视图的长时间运行的事务激活它。 –
其他提示:我会将大多数DDL操作运行到自己的事务中,在每个事务之后进行提交。事实上在某些工具中有一个选项来“自动提交DDL操作”。而且我绝对不会将DDL与常规操作混合使用。 –
也许使用TSqlQuery组件而不是已弃用的TSimpleDataset。 –