gpt4 book ai didi

Delphi FireDAC TFDQuery 事件 'AfterOpen' 从未执行

转载 作者:行者123 更新时间:2023-12-03 15:34:41 33 4
gpt4 key购买 nike

我正在尝试异步执行 SQL 查询。我已经检查了 http://docwiki.embarcadero.com/RADStudio/XE5/en/Asynchronous_Execution_(FireDAC) 中的示例代码

以及目录中的示例项目

..Samples\Object Pascal\Database\FireDAC\Samples\Comp Layer\TFDQuery\ExecSQL\Async

我想我已经明白了其中的逻辑。但有一个问题 - 事件 QueryAfterOpen 永远不会执行,而我的 TDataSource 始终保持 Nil (因为它得到 NilQueryBeforeOpen 内 - 此事件始终执行)。这是我单位的所有代码:

unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf,
FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf,
FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys,
FireDAC.VCLUI.Wait, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt,
Vcl.StdCtrls, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
FireDAC.Phys.MySQLDef, FireDAC.Phys.MySQL;

type
TForm1 = class(TForm)
Button1: TButton;
FDPhysMySQLDriverLink1: TFDPhysMySQLDriverLink;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Query1BeforeOpen(DataSet: TDataSet);
procedure Query1AfterOpen(DataSet: TDataSet);
procedure FormDestroy(Sender: TObject);

private
{ Private declarations }
Connection1: TFDConnection;
Query1: TFDQuery;
DataSource1: TDataSource;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
QueryFinished: Boolean;
begin
with Query1 do begin
SQL.Text := 'SELECT field1 FROM test_table WHERE idpk=1';
AfterOpen := Query1AfterOpen;
BeforeOpen := Query1BeforeOpen;
ResourceOptions.CmdExecMode := amAsync;
QueryFinished := False;
Open;
repeat
Sleep(100);
if Command.State = csPrepared then begin
// A command is prepared. A result set is not accessible.
// TmpInteger := Query1.FieldByName('field1').AsInteger;
end
else if Command.State = csOpen then begin // A command execution
// is finished. A result set is accessible and not yet fully fetched.
if DataSource1.DataSet <> Nil then begin
// this code never executes because Query1AfterOpen never executes and
// DataSource1.DataSet remains always Nil !!!
QueryFinished := True;
end;
end;
until ((QueryFinished) OR (DataSource1.DataSet <> Nil));
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
SQLConnParams: string;
begin
SQLConnParams := ''; // sql connection parameters removed from here from security
// issues, assume they are correct
Connection1 := TFDConnection.Create(Nil);
Connection1.Params.Text := SQLConnParams;
Query1 := TFDQuery.Create(Nil);
Query1.Connection := Connection1;
DataSource1 := TDataSource.Create(Nil);
DataSource1.DataSet := Query1;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
DataSource1.Free;
Query1.Free;
Connection1.Free;
end;

procedure TForm1.Query1AfterOpen(DataSet: TDataSet);
begin
DataSource1.DataSet := Query1;
Query1.AfterOpen := Nil;
//Query1.ResourceOptions.CmdExecMode := amBlocking;
end;

procedure TForm1.Query1BeforeOpen(DataSet: TDataSet);
begin
DataSource1.DataSet := Nil;
end;
end.

显然,repeat..until..循环内的代码是无限的,除非有人终止程序。为了执行 Query1AfterOpen 中的代码(或使用另一个事件)以便我可以在 TFDQuery 完成工作后访问结果集,我缺少什么?

最佳答案

这些异步事件通过消息循环与主线程同步。只要您停留在 Button1Click 事件中,就无法处理新消息。因此 AfterOpen 事件被困在消息循环内。

我不知道您想要实现什么目的,但您应该考虑将相关代码放在 AfterOpen 事件中。 Repeat-until 子句以某种方式伪造了异步执行的目的。

关于Delphi FireDAC TFDQuery 事件 'AfterOpen' 从未执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35558511/

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