如何延长SQL查询的超时时间

42

这不是连接超时,因为和数据库的连接是正常的。问题在于我调用的存储过程需要比如30秒以上的时间,导致了超时。

这个函数的代码大概长这样:

SqlDatabase db = new SqlDatabase(connectionManager.SqlConnection.ConnectionString);
return db.ExecuteScalar(Enum.GetName(typeof(StoredProcs), storedProc), parameterValues);

ExecuteScalar调用超时了。我该如何延长这个函数的超时时间?

对于快速存储过程,它可以正常工作。但是,其中一个函数需要一些时间,因此调用失败。当以这种方式调用ExecuteScalar函数时,似乎找不到任何延长超时期限的方法。


6
好的,给我的问题点踩是很不礼貌的。我的问题已经清晰地定义了,并且(希望)有一个答案。 - BoltBait
6个回答

38

如果你正在使用EnterpriseLibrary(似乎是这样),尝试这样做:

 Microsoft.Practices.EnterpriseLibrary.Data.Database db = Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase("ConnectionString");
 System.Data.Common.DbCommand cmd = db.GetStoredProcCommand("StoredProcedureName");
 cmd.CommandTimeout = 600;
 db.AddInParameter(cmd, "ParameterName", DbType.String, "Value");

 // Added to handle paramValues array conversion
 foreach (System.Data.SqlClient.SqlParameter param in parameterValues) 
 {
     db.AddInParameter(cmd, param.ParameterName, param.SqlDbType, param.Value);
 }

 return cmd.ExecuteScalar();

根据评论,编辑以直接处理paramValues数组。我还包括了您的ConnectionString值:

Microsoft.Practices.EnterpriseLibrary.Data.Database db = Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase(connectionManager.SqlConnection.ConnectionString);
System.Data.Common.DbCommand cmd = db.GetStoredProcCommand("StoredProcedureName", parameterValues);
cmd.CommandTimeout = 600;
return cmd.ExecuteScalar();

嗯...我没有访问ParameterNames的权限。在我的示例代码中,parameterValues变量被定义为"object[] parameterValues"。如果只知道参数的顺序,我是否仍然可以添加参数? - BoltBait
搞定了。谢谢。我的代码现在看起来像你帖子中的第二个代码块。 - BoltBait
我添加了d.commandTimeout = 600;但我的存储过程抛出异常。请问能帮忙吗? - user3217843
@user3217843,设置命令超时不会导致存储过程抛出异常。如果没有关于您的存储过程、如何调用它、它正在执行什么或其他任何相关信息,我将无法帮助您解决问题。我建议您研究一下被抛出的异常,并在StackOverlow上发布一个新问题,如果您找不到答案的话。 - Chris Porter
查看我的存储过程从数据库中获取所有记录。我在其中使用了一个连接。当我在SQL中运行我的存储过程时,它返回了值列表,但是当我尝试通过服务检索时,它抛出了超时异常。 - user3217843
显示剩余4条评论

26

3
如果我正在使用 SqlCommand,那么这将非常有效... 但是,我没有。 - BoltBait
3
没错,SqlDatabase并不是标准的数据提供程序的一部分;它是某个人编写的包装类,其内部将使用一个SqlCommand对象。 - Joel Coehoorn
3
“someone” 可能是Microsoft,不过这个SQLDatabase类来自于Microsoft.Practices.EnterpriseLibrary吗? - Richard Dunlap
@Joel,那个函数定义在一个名为Microsoft.Practices.EnterpriseLibrary.Data.dll的文件中。嗯...我不确定我是否有它的源代码。正在搜索... - BoltBait
重写它以使用db.CreateConnection(); 这样你将会有4-5行额外的代码,但可以轻松访问SqlCommand对象。 - nos

7
我认为这可能是更好的方法(截至企业库6.0):
SqlDatabase db = new SqlDatabase(connectionManager.SqlConnection.ConnectionString);
System.Data.Common.DbCommand cmd = db.GetStoredProcCommand(storedProc, parameterValues);
cmd.CommandTimeout = 600;
return db.ExecuteScalar(cmd);

谢谢伙计,这节省了我很多时间。非常感激。 - user5308950

4

试试这个

SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(connection.ConnectionString);
connectionStringBuilder.ConnectTimeout = 180;
connection.ConnectionString = connectionStringBuilder.ConnectionString;

connection.Open();
SqlCommand command = new SqlCommand("sp_ProcedureName", connection);
command.CommandType = CommandType.StoredProcedure;
command.CommandTimeout = connection.ConnectionTimeout;
command.ExecuteNonQuery();
connection.Close();

0

0
Mladen 是对的,但如果你必须这样做,那么你可能在 proc 本身上有更大的问题。在负载下,它可能比你的新超时时间长得多。花一些时间优化 proc 可能是值得的。

1
谢谢你告诉我去优化我的应用程序。叹气。从长远来看可能会发生,但对于今天,我只需要让这个东西运行。 - BoltBait
我绝对没有冒犯的意思。只是如果 SQL 超时,很难找到适用于每种情况的超时时间。在许多情况下,您希望 SQL 超时,而默认值仍然相当长。 - n8wrl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接