虽然围绕这个主题有很多问题,但这些建议似乎都没有用。 我有几个应该每天运行的存储过程——其中一些存储过程非常简单,另一些则有点棘手。但即使是最简单的过程在使用 SqlClient 从 C# 程序(控制台)调用时也会无限期地运行。 此客户端在服务器上运行,在实际运行时应提升为 Windows 服务。
到目前为止我尝试了什么。
- 添加 ARITHABORT ON(或 OFF)作为连接初始化后的首次执行。
- 将 ARITHABORT ON(或 OFF)添加为存储过程中的第一个命令
- 使用
WITH RECOMPILE
- 将 ARITHABORT 添加为全局配置项。
(EXEC sys.sp_configure N'用户选项', N'64'
去
重新配置覆盖
去
)
存储过程(所有这些)没有输入参数,最简单的(我目前唯一使用的)是这样的:
CREATE PROCEDURE [dbo].[_clean_messageLog]
WITH RECOMPILE
AS
BEGIN
SET NOCOUNT ON;
set arithabort on;
DELETE FROM MessageLog WHERE Moment < GETDATE() - 60;
DELETE FROM MessageLog WHERE Moment < GETDATE() - 30 AND [Status] = 200;
END
实际上没有要删除的消息,并且在 SSMS 中,存储过程在几毫秒内执行(如预期的那样)。 然而,从 C# 控制台应用程序,它需要永远(字面意思)。
主要方法:
const int TIME_OUT = 900000; // 15 minutes
timer.Stop();
foreach (var command in commands.Where(command => !string.IsNullOrWhiteSpace(command)))
{
var start = DateTime.Now;
WriteEvent(string.Format("Starting: {0}", command), EventLogEntryType.Information);
using (var sql = new Lib.Data.SqlServerHelper(connectionString))
{
sql.newCommand(command.Trim());
sql.execute(TIME_OUT);
}
WriteEvent(string.Format("Done in {0} seconds", DateTime.Now.Subtract(start).TotalSeconds), EventLogEntryType.Information);
}
有人有什么建议吗?
编辑
sqlHelper 只是一个基本(非常简单)的包装器。但即使我将上面的代码更改为:
foreach (var command in commands.Where(command => !string.IsNullOrWhiteSpace(command)))
{
var start = DateTime.Now;
WriteEvent(string.Format("Starting: {0}", command), EventLogEntryType.Information);
using (var sql = new SqlConnection(connectionString))
{
sql.Open();
var sqlCommand = new SqlCommand(command.Trim(), sql) {CommandType = CommandType.StoredProcedure};
sqlCommand.ExecuteNonQuery();
}
WriteEvent(string.Format("Done in {0} seconds", DateTime.Now.Subtract(start).TotalSeconds), EventLogEntryType.Information);
}
完全一样。
编辑 #2
是否有一个选项可以安排这些存储过程由 SQL Server 本身在一定时间间隔或特定时间运行?
已解决
有点,虽然我从来没有找到真正的 C# 解决方案来解决我的问题,但使用 SQL Server 代理就可以了。由于死锁问题,C# 进程被锁定 - 有时作业也会发生这种情况(不像控制台程序那么多),但我们正在努力解决这个问题。
最佳答案
Is there an option I can schedule these stored procedures to be run by
SQL Server itself on an interval or specific time?
是的,SQL Server Agent 可以根据特定时间或间隔运行作业。
SSMS -> SQL Server 代理 -> 右键单击 -> 新建作业 -> 选择名称、数据库、代码和计划
完成后,您可以单击Script
按钮并获取创建作业的脚本(如果需要)。
您还可以使用 T-SQL 启 Action 业(例如从应用程序/另一个存储过程或触发器):
EXEC msdb.dbo.sp_start_job N'JobName';
关于c# - 非常慢的 ExecuteNonQuery(存储过程)与使用 SQL Server Management Studio 的快速执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32311130/