简体   繁体   English

ADO组件CommandTimeout

[英]ADO components CommandTimeout

I have a problem with settings of the query execution timeout with TADOQuery, TADOCommand or TADODataSet (I've tried it with each one). 我在使用TADOQuery,TADOCommand或TADODataSet设置查询执行超时时遇到了问题(我已经尝试过每一个)。 I have a tiny application, which connects to the database and periodically executes stored procedures, which returns dataset as a result . 我有一个微型应用程序,该应用程序连接到数据库并定期执行存储过程,该过程将结果返回数据集 My aim is to keep this application always online, but my problem is that when the connection is lost, the timeout of just executed command (through the one of the mentioned components) takes the default 30 seconds. 我的目的是使该应用程序始终保持联机状态,但是我的问题是,当连接断开时,刚执行的命令(通过上述组件之一)的超时将默认为30秒。 I've been looking for the solution, but nothing works. 我一直在寻找解决方案,但是没有任何效果。 Could you give me an advice, how to set the CommandTimeout eg to 5 seconds or better to say how to modify ADODB.pas for respecting my own timeout, please ? 您能否给我一个建议,如何将CommandTimeout设置为5秒或更佳,比如说如何修改ADODB.pas以尊重我自己的超时时间?

There were many "solutions" for this, like set DataComponent.Connection.CommandTimeout := 1; 有很多“解决方案”,例如set DataComponent.Connection.CommandTimeout:= 1; but really, nothing works. 但实际上,没有任何效果。 I'm using D2009, MSSQL2005 and the connection along with the data component is created dynamically in the thread. 我正在使用D2009,MSSQL2005,并且连接和数据组件是在线程中动态创建的。

The last, what I've tried is this 最后,我尝试过的是

// protected variable owned and created in the thread with its own connection
var Query_Object: TADODataSet; 

// connection timeout is set to 3 seconds
Query_Object.Connection.ConnectionTimeout := 3;
...

// this piece of code I'm calling periodically in the only one existing thread
...
SQL_Query := 'EXEC my_procedure_which_returns_dataset'

with Query_Object do
  begin
    Close;    
    CommandType := cmdText;
    CommandText := SQL_Query;
    CommandTimeout := 5;             // doesn't affect the timeout
    CursorLocation := clUseServer;   // let the dataset retreives prepared data
    Open;
  end;

// and here I need to get faster than in the default 15 seconds to let the user
// know that the reading takes more than mentioned 5 seconds
...

Thanks a lot :) 非常感谢 :)

CommandTimeout is kicking in when you have long running queries. 当您长时间运行查询时, CommandTimeout会启动。 There is a CommandTimeout property of TADOConnection but that does not work. 没有TADOConnectionCommandTimeout属性,但是不起作用。 You have to use the CommandTimeout of the TADODataSet instead. 您必须改为使用TADODataSetCommandTimeout

If the server is unavailable, your question says "connection is lost", you need to specify ConnectionTimeout of the TADOConnection component. 如果服务器不可用,您的问题是“连接丢失”,则需要指定TADOConnection组件的ConnectionTimeout Default is 15 seconds before control is returned to your application. 默认值为将控制权返回到应用程序之前的15秒。

Edit 1 I think I have discovered a situation where CommandTimeout does not work. 编辑1我想我已经发现CommandTimeout不起作用的情况。 I have tested this against a really big table. 我已经在一个很大的桌子上测试了这个。 It takes several minutes to return all rows. 返回所有行需要几分钟。 If my stored procedure does select * from BigTable the query timeout never happens. 如果我的存储过程确实select * from BigTableselect * from BigTable则查询超时将永远不会发生。 At least I was not patient enough to wait it out. 至少我没有耐心等待它。 But if the query looks like this select * from BigTable order by Col1 and there is no index on Col1 , the CommandTimout works as expected. 但是,如果查询看起来像这样select * from BigTable order by Col1并且对没有索引Col1 ,按预期工作的CommandTimout。

The difference between the two queries is obvious when running them in SSMS. 在SSMS中运行它们时,两个查询之间的区别显而易见。 The first starts to immediately return rows and the second needs to "think" about it before it returns rows. 第一个开始立即返回行,第二个需要在返回行之前对其进行“思考”。 When SQL Server have found the rows it needs and start to return them, CommandTimeout does not work. 当SQL Server找到所需的行并开始返回它们时,CommandTimeout将不起作用。

If you set CursorLocation to clUseServer the CommandTimeout will work as expected for both queries. 如果将CursorLocation设置为clUseServerCommandTimeout将对两个查询都按预期工作。

Following is what we use to set the timeout to 300 for our long running reports. 以下是我们将长时间运行的报告的超时设置为300的方法。

  //***** Fix setting CommandTimeOut. 
  //      CommandTimeOut "should" get the timeout value from its connection. 
  //      This is not supported in ADODB (using Delphi5)
  TADODataSet(qryReport).CommandTimeout := ADOConnection.CommandTimeout;

Edit 编辑

Executing following piece of code on my Development Machine times out after 1 second. 在我的开发机上执行以下代码段1秒后超时。

  • The query has a connectionstring to our SQLServer production database. 该查询具有到我们的SQLServer生产数据库的连接字符串。
  • The script (tries to) runs for 10 seconds 脚本(尝试运行)运行10秒钟
  • After one second, I get a TimeOut exception 一秒钟后,我收到一个超时异常

Test 测试

procedure TForm1.btn1Click(Sender: TObject);
const
  SSQL: string =
    'DECLARE    @intLoop int '#13#10
    + 'SET @intLoop = 10 '#13#10
    + 'WHILE @intLoop > 1 '#13#10
    + 'BEGIN '#13#10
    + ' SELECT  @intLoop, GetDate() '#13#10
    + ' WAITFOR DELAY ''00:00:01'' '#13#10
    + ' SELECT  @intLoop = @intLoop -1 '#13#10
    + 'END ';
begin
  qry1.SQL.Text := SSQL;
  TADODataSet(qry1).CommandTimeout := 1;
  qry1.ExecSQL;
end;

I've always used the following code to set the CommandTimeout value on a TADOQuery. 我一直使用以下代码在TADOQuery上设置CommandTimeout值。 If you adjust the class name it should also work with the others as well. 如果您调整类别名称,它也应该与其他名称一起使用。

type 
TADOQueryHack = class(TADOQuery);

...

TADOQueryHack(Qry).CommandTimeout := COMM_TIMEOUT;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 delphi 中的 ADO 组件 - ADO components in delphi Delphi 2009 专业版中是否存在 ADO 组件? - ADO components are present in the Delphi 2009 Professional Version? Delphi/ADO:哪些组件? TADODataSet 和 TADOCommand 还是 TADOQuery? - Delphi / ADO : Which components? TADODataSet and TADOCommand or TADOQuery? 在某些情况下,ADO组件(尤其是TADOCommand)是否可以更加可靠地使用未命名或命名的参数? - Do ADO components, especially TADOCommand, work more reliably with un-named, or named parameters, in some cases? 在SQLOLEDB.1提供程序中使用Delphi XE2 ADO组件是否存在已知问题? - Is there a known issue using Delphi XE2 ADO components with the SQLOLEDB.1 provider? 我们可以使用Delphi 7 ADO组件来连接和访问Oracle 12.X数据库吗? - Can we use Delphi 7 ADO components to connect and access Oracle 12.X database? ADOConnection ADOQuery CommandTimeout ,覆盖顺序(如果有的话) - ADOConnection ADOQuery CommandTimeout , Override Order ( if at all ) ADO应用程序。 Windows 7下会生成“错误创建对象”。 请验证Microsoft数据访问组件2.1…” - ADO app. under Windows 7 generates “error creating object. please verify that the microsoft data access components 2.1…” 执行后设置 CommandTimeout 导致错误(列出现多次) - Setting CommandTimeout after Execution causes error (column appears multiple times) ADO连接超时问题 - ADO Connection Timeout problem
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM