为什么 CREATE TABLE 看似成功,但在 DBX 下却失败?
我有一个连接到运行 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;
当我尝试创建表时,它似乎可以工作,我可以ALTER
和DROP
它很好,但是当我尝试打开一个对其运行 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
SQL
、SQL2
和SQL3
在一个(或多个)事务中执行。并且事务至少在SQL
之后保持活动状态。而New_TableDataset
是在不同的事务中操作的,这当然看不到第一个事务的未提交的更改。SQL
和/或SQL2
之后执行COMMIT
。TSQLQuery
而不是ExecuteDirect
。希望所有命令都在单个事务中运行。PS:最后考虑使用不同的dbExpress驱动程序甚至数据访问库。
SQL
,SQL2
andSQL3
are executing in one (or in many) transaction. And the transaction remains acive at least afterSQL
. AndNew_TableDataset
is operating in different transaction, which of course does not see uncommited changes of the first transaction.COMMIT
afterSQL
and/orSQL2
.TSQLQuery
instead ofExecuteDirect
. Hopefully all commands will run in a single transaction.PS: Finally consider to use different dbExpress driver or even data access library.
我在使用 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