gpt4 book ai didi

database - 为什么 qry.post 以异步方式执行?

转载 作者:搜寻专家 更新时间:2023-10-30 20:45:49 24 4
gpt4 key购买 nike

最近遇到一个奇怪的问题,代码截图如下:

var
sqlCommand: string;
connection: TADOConnection;
qry: TADOQuery;
begin
connection := TADOConnection.Create(nil);
try
connection.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Test.MDB;Persist Security Info=False';
connection.Open();
qry := TADOQuery.Create(nil);
try
qry.Connection := connection;
qry.SQL.Text := 'Select * from aaa';
qry.Open;

qry.Append;
qry.FieldByName('TestField1').AsString := 'test';

qry.Post;
beep;
finally
qry.Free;
end;
finally
connection.Free;
end;
end;

首先,新建一个access数据库test.mdb,放在本次测试项目的目录下,我们可以在其中新建一个表aaa,其中只有一个文本类型的字段,名称为TestField1。

我们在“beep”行设置断点,然后在ide Debug模式下启动测试应用程序,当ide停在断点行时(qry.post已经执行),此时我们使用microsoft access打开测试.mdb打开aaa表你会发现aaa表没有任何变化,如果你按f9让ide继续运行你会发现aaa表中插入了一条新记录,但是如果你按ctrl+f2终止在断点处的应用程序,你会发现aaa表还没有插入记录,但正常情况下,qry.post执行后应该会在aaa表中插入一条新记录。谁能解释一下这个问题,困扰我好久了。谢谢!!!

顺便说一下,ide是delphi 2010,access mdb文件是windows 7下microsoft access 2007创建的

最佳答案

Access 不会向您显示尚未提交的交易记录。在您暂停程序时,连接创建的隐式事务尚未提交。还没有试验过,但我的猜测是隐式事务将在您释放查询后提交。因此,如果您在那之后暂停,您应该会在 MS Access 中看到您的记录。


在从 Ryan 那里获得更多信息后(参见他对自己的回答),我做了更多的调查。

拥有主键(自动编号或其他)似乎不会影响行为。

以自动编号列为主键的表

  connection.Execute('insert into aaa (TestField1) values (''Test'')');
connection.Execute('select * from aaa');
connection.Execute('delete * from aaa');
beep;
finally
connection.Free;
end;

停在“选择”上不会显示新记录。停在“删除”上显示新记录。即使在重复刷新之后,停止“哔”声仍会显示表中的所有记录。在“connection.Free”上停止显示表中没有更多记录。嗯?在“删除”和“哔”之间插入的“选择”停止显示表中不再有记录。

同 table

  connection.Execute('insert into aaa (TestField1) values (''Test'')');
beep;
connection.Execute('delete * from aaa');
beep;
beep;

在每条语句上停止表明 Access 在至少执行了一条其他语句之前不会收到“命令”。换句话说:“执行”语句之后的蜂鸣声必须在 Access 处理该语句之前处理(可能需要几次刷新才能显示,第一次刷新并不总是足够)。如果您在“执行”语句后听到第一声蜂鸣声时停止,Access 中什么也没有发生,如果您在不执行任何其他语句的情况下重置程序,则不会发生这种情况。

进入连接。执行(使用调试 dcu 的开启):执行的 sql 语句的效果现在在 Access 中可见,返回蜂鸣声。实际上,它更早可见。例如进入“delete”语句,记录在 ADODB 代码中的某处被标记为#deleted。

事实上,当单步执行 adodb 代码时,记录在 OnExecuteComplete 处理程序中停止时在 Access 中可见。不是在“开始”时停止,而是在之后立即在“如果分配”时停止。这同样适用于 delete 语句。当在 AdoDb 的 OnExecuteComplete 处理程序中的 if 语句上停止时,效果在 Access 中变得可见。

Ado 确实有一个 ExecuteOption 来异步执行语句。它在所有这一切期间都没有生效(默认情况下不包括在内)。当我们处理进程外 COM 服务器和回调(例如 OnExecuteComplete 处理程序)时,该处理程序在返回到 AdoDb 的 TAdoConnection.Execute 方法中的 ConnectionObject.Execute 语句之后的语句之前执行。

总而言之我觉得与其说是同步执行还是异步执行的问题,更多的是什么时候释放引用的问题(我们在处理COM和接口(interface)引用计数),或者线程和进程的时序问题(在应用程序中、Access 中以及它们之间),或者它们的组合。

而且调试器可能只是把事情搞得一团糟,而不是澄清它们。看看 D2010 的单线程调试功能会发生什么很有趣,但我还没有得到它(现在和接下来的两周)。

关于database - 为什么 qry.post 以异步方式执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3029249/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com