ADOConnection ADOQuery CommandTimeout,覆盖顺序(如果有的话)
ADOConnection ADOQuery CommandTimeout , Override Order ( if at all )
到达此处 Delphi 10.4.2。一个 ADOConnection 和一个 ADOQuery .
ADOConnection 使用 OleDB (UDL) 连接到 MSSQL。我已经离开了 CommandTimeout 30 。
现在我将 ADOQuery 放在这个表单上,将它的 Connection 属性 设置为 ADOConnection 。所有其他值均为默认值,CommandTimeout 为 30。
现在假设我们有一个非常大的 table 超时。使用默认的 30 秒。
我的问题是:
如果我将 ADOQuery CommandTimeout 设置为 600,它就可以工作
但如果我只将 ADOConnection CommandTimeout 设置为 600,它仍然会超时
如果 ADOConnection 上的 CommandTimeout 不简单地将它的值传播到它的关联组件(当然直到我覆盖它们),它有什么目的?
谢谢。
编辑 1:
ADOConnection CommandTimeout 是否实际用于 ADOConnection 为建立连接而必须执行的某些后台任务?
例如,如果我在 IDE 中激活它,然后有一个 ADOStoredProcedure 并且我想列出服务器上所有可用的存储过程,它会使用此超时吗?
根据 Microsoft 每个 ADO 对象尊重它自己的 CommandTimeout
:
The CommandTimeout setting on a Connection object has no effect on the
CommandTimeout setting on a Command object on the same Connection;
that is, the Command object's CommandTimeout property does not inherit
the value of the Connection object's CommandTimeout value.
我做了一个小MRE(使用Delphi10.3)来证明这一点:
program SO69733529;
{$APPTYPE CONSOLE}
{$R *.res}
uses
ActiveX,
AdoDb,
System.SysUtils;
procedure TestADOCommandTimeout;
var
Conn : TADOConnection;
Qry : TADOQuery;
SQLDelay : Integer;
begin
Conn := TADOConnection.Create(nil);
Qry := TADOQuery.Create(nil);
try
Conn.LoginPrompt := False;
Conn.ConnectionString := 'Provider=SQLOLEDB.1;Data Source=localhost\sqlexpress;Initial Catalog=TestCustomer;Integrated Security = SSPI;';
Conn.Connected := True;
Qry.Connection := Conn;
Writeln('Connected to DB');
SQLDelay := 10;
Conn.CommandTimeout := 5;
try
Writeln(Format('Waiting for %d seconds, connection timeout is %d seconds', [SQLDelay, Conn.CommandTimeout]));
Conn.Execute(Format('WAITFOR DELAY ''00:00:%.2d''', [SQLDelay]));
Writeln('No Timeout');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Qry.CommandTimeout := 30;
try
Writeln(Format('Waiting for %d seconds, query timeout is %d seconds, connection timeout is %d seconds', [SQLDelay, Qry.CommandTimeout, Conn.CommandTimeout]));
Qry.SQL.Text := Format('WAITFOR DELAY ''00:00:%.2d''', [SQLDelay]);
Qry.ExecSQL;
Writeln('No Timeout');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
// now redo the same test but with connection commandtimeout same as qry timeout
Qry.CommandTimeout := 15;
Conn.CommandTimeout := Qry.CommandTimeout;
try
Writeln(Format('Waiting for %d seconds, query timeout is %d seconds, connection timeout is %d seconds', [SQLDelay, Qry.CommandTimeout, Conn.CommandTimeout]));
Qry.SQL.Text := Format('WAITFOR DELAY ''00:00:%.2d''', [SQLDelay]);
Qry.ExecSQL;
Writeln('No Timeout');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
finally
Qry.Free;
Conn.Free;
end;
end;
begin
try
try
CoInitialize(nil);
TestADOCommandTimeout;
finally
CoUninitialize;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
输出:
Connected to DB Waiting for 10 seconds, connection timeout is 5 seconds
EOleException: Query timeout expired
Waiting for 10 seconds, query timeout is 30 seconds, connection timeout is 5 seconds
No Timeout
Waiting for 10 seconds, query timeout is 15 seconds, connection timeout is 15 seconds
No Timeout
到达此处 Delphi 10.4.2。一个 ADOConnection 和一个 ADOQuery .
ADOConnection 使用 OleDB (UDL) 连接到 MSSQL。我已经离开了 CommandTimeout 30 。 现在我将 ADOQuery 放在这个表单上,将它的 Connection 属性 设置为 ADOConnection 。所有其他值均为默认值,CommandTimeout 为 30。
现在假设我们有一个非常大的 table 超时。使用默认的 30 秒。
我的问题是:
如果我将 ADOQuery CommandTimeout 设置为 600,它就可以工作 但如果我只将 ADOConnection CommandTimeout 设置为 600,它仍然会超时
如果 ADOConnection 上的 CommandTimeout 不简单地将它的值传播到它的关联组件(当然直到我覆盖它们),它有什么目的?
谢谢。
编辑 1:
ADOConnection CommandTimeout 是否实际用于 ADOConnection 为建立连接而必须执行的某些后台任务? 例如,如果我在 IDE 中激活它,然后有一个 ADOStoredProcedure 并且我想列出服务器上所有可用的存储过程,它会使用此超时吗?
根据 Microsoft 每个 ADO 对象尊重它自己的 CommandTimeout
:
The CommandTimeout setting on a Connection object has no effect on the CommandTimeout setting on a Command object on the same Connection; that is, the Command object's CommandTimeout property does not inherit the value of the Connection object's CommandTimeout value.
我做了一个小MRE(使用Delphi10.3)来证明这一点:
program SO69733529;
{$APPTYPE CONSOLE}
{$R *.res}
uses
ActiveX,
AdoDb,
System.SysUtils;
procedure TestADOCommandTimeout;
var
Conn : TADOConnection;
Qry : TADOQuery;
SQLDelay : Integer;
begin
Conn := TADOConnection.Create(nil);
Qry := TADOQuery.Create(nil);
try
Conn.LoginPrompt := False;
Conn.ConnectionString := 'Provider=SQLOLEDB.1;Data Source=localhost\sqlexpress;Initial Catalog=TestCustomer;Integrated Security = SSPI;';
Conn.Connected := True;
Qry.Connection := Conn;
Writeln('Connected to DB');
SQLDelay := 10;
Conn.CommandTimeout := 5;
try
Writeln(Format('Waiting for %d seconds, connection timeout is %d seconds', [SQLDelay, Conn.CommandTimeout]));
Conn.Execute(Format('WAITFOR DELAY ''00:00:%.2d''', [SQLDelay]));
Writeln('No Timeout');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Qry.CommandTimeout := 30;
try
Writeln(Format('Waiting for %d seconds, query timeout is %d seconds, connection timeout is %d seconds', [SQLDelay, Qry.CommandTimeout, Conn.CommandTimeout]));
Qry.SQL.Text := Format('WAITFOR DELAY ''00:00:%.2d''', [SQLDelay]);
Qry.ExecSQL;
Writeln('No Timeout');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
// now redo the same test but with connection commandtimeout same as qry timeout
Qry.CommandTimeout := 15;
Conn.CommandTimeout := Qry.CommandTimeout;
try
Writeln(Format('Waiting for %d seconds, query timeout is %d seconds, connection timeout is %d seconds', [SQLDelay, Qry.CommandTimeout, Conn.CommandTimeout]));
Qry.SQL.Text := Format('WAITFOR DELAY ''00:00:%.2d''', [SQLDelay]);
Qry.ExecSQL;
Writeln('No Timeout');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
finally
Qry.Free;
Conn.Free;
end;
end;
begin
try
try
CoInitialize(nil);
TestADOCommandTimeout;
finally
CoUninitialize;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
输出:
Connected to DB Waiting for 10 seconds, connection timeout is 5 seconds
EOleException: Query timeout expired
Waiting for 10 seconds, query timeout is 30 seconds, connection timeout is 5 seconds
No Timeout
Waiting for 10 seconds, query timeout is 15 seconds, connection timeout is 15 seconds
No Timeout