C# 中的“即发即忘”Sql Server 存储过程
我正在做一个排队的作业,在每个作业结束时我想触发一个 SP,它将对数据进行大量处理。所以我不想等待SP完成,我只想在触发SP后立即转移到下一个工作。存储过程将从触发代码获取输入。
问题:-
这是我创建工作的脚本。请注意,我没有向其中添加任何时间表。
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'job_JobName',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'No description available.',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'UserName', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'StepName',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec dbo.SpToExecute',
@database_name=N'DataBaseName',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
现在,当我通过执行 EXEC msdb.dbo.job_JobName' 启动此作业时,它不会执行 dbo.SpToExecute
。我只需要在作业中运行 dbo.SpToExecute 一次,然后作业就应该停止。再次,当我执行 EXEC msdb.dbo.job_JobName'
时,它应该再次运行 exec dbo.SpToExecute
一次。您能告诉我如何实现这一目标或者我在这里缺少什么吗?
I'm doing a queued jobs and at the end of each job I want to fire an SP which will do a lot of processing on data. So I don't want to wait for completion of the SP and I just want to move to next job immediately after triggering the SP. Stored procedure will take an input from the triggering code.
Problem:-
This is my script to create job. Notice that I've not added any schedule to it.
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'job_JobName',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'No description available.',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'UserName', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'StepName',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec dbo.SpToExecute',
@database_name=N'DataBaseName',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
Now when I start this job by executing EXEC msdb.dbo.job_JobName'
, it is not executing dbo.SpToExecute
. I need to run dbo.SpToExecute
only once within the job and then job should stop. Again when I execute EXEC msdb.dbo.job_JobName'
it should again run exec dbo.SpToExecute
only once. Can you please tell me how to achieve this or what I'm missing here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 BeginExecuteNonQuery 或其他异步方法,或者您可以创建一个将运行 SP 的 SQL 作业,然后调用常规同步 ExecuteNonQuery 来启动该作业。它会立即返回,因为开始工作很快。然后作业就会运行,您就可以“忘记”它了。
下面是 SQL 代理作业方法的一些即发即忘代码。
string sql = "EXEC dbo.sp_start_job 'THE NAME OF YOUR JOB'";
然后在数据库上执行它。它应该立即返回。如果成功则返回 0,如果不成功则返回 1。请参阅此处。
您无法将参数传递给作业。因此,如果需要,您可以创建一个表来保存要传递的参数。然后,您需要在调用 sp_start_job SP 之前使用您希望 SP 使用的参数来更新表。然后,您还需要 SP 查看该表并查看要使用哪些参数。这很容易。
就是这样。火并忘记。
You could use the BeginExecuteNonQuery or other asynchronous methods or you could create a SQL job that will run your SP(s) and then just call the regular synchronous ExecuteNonQuery to fire off the job. It will return immediately, since starting a job is quick. Then the job runs and you can "forget" about it.
Here's some fire and forget code for the SQL agent job approach.
string sql = "EXEC dbo.sp_start_job 'THE NAME OF YOUR JOB'";
And then just execute that on the database. It should return immediately. It will return a 0 if it was successful, and a 1 if unsuccessful. See here.
You can't pass a parameter to the job. So if you need to, you could create a table that would hold the parameters you want to pass. Then you would need to update the table with the parameters you want your SP to use before you call the sp_start_job SP. Then you would also need your SP to look in that table and see what parameters to use. It's pretty easy.
That's about it. Fire and forget.
您似乎希望使用 SQL Server T-SQL 而不是通过 .NET 代码来处理所有这些问题。
如果是这样,您可以研究此实现
It seems like you are looking to handle all of this with SQL Server T-SQL and not through .NET code.
If so you might study this implementation