SQL执行长时间任务的可选方案

本文介绍了如何在SQL Server中利用作业来管理长时间运行的任务。包括如何创建和调用作业、检查作业状态、停止作业等关键步骤。此外还讨论了权限管理和相关存储过程的使用。
在有些应用程序中,程序的执行可能需要很长的时间,针对这种情况我们在做前后应用时可能会比较棘手,比如建立一个普通的连接对象,然后执行一个长时间的任务,比如数据的同步操作,一般单线程的程序在后台程序执行期间即出现假死现象,对于一些希望在后台执行的长时间任务,在SQL中可以考虑用作业的方式进行解决,建立完成作业后,我们在前台只要调用指定任务就可以了,这里需要注意下面几个问题

1) 在SQL中任务数据库的任务是放在msdb库中统一进行管理的,所以前台应用若要调用任务,则需要建立一个到msdb数据库的连接,另外要保证建立的连接有足够执行任务的权限.
       执行权限默认授予 msdb 数据库中的 public 角色。可执行此存储过程而且是 sysadmin 固定角色成员的用户可以启动任何作业。不是 sysadmin 角色成员的用户使用 sp_start_job 只能启动他/她所拥有的作业。
当 sysadmin 固定服务器角色成员的用户唤醒调用 sp_start_job 时,sp_start_job 将在 SQL Server 服务正在其中运行的安全上下文中执行。当用户不是 sysadmin 固定服务器角色的成员时,sp_start_job 将模拟 SQL Server 代理代理帐户,而该帐户是通过 xp_sqlagent_proxy_account 指定的。如果代理帐户不可用,则 sp_start_job 将失败。只有 Microsoft? Windows NT? 4.0 和 Windows 2000 有上述情况。在 Windows 9.x 上没有模拟,而且 sp_start_job 总是在启动 SQL Server 的 Windows 9.x 用户的安全上下文中执行。

2) 调用具体任务时需要用到扩展的存储过程sp_start_job ,比如要执行一个作业名称为"同步数据"的作业,其语法为
USE msdb
EXEC sp_start_job @job_name = '同步数据'

程序调用时,比如存在一个到msdb数据库的连接对象Connection为cn
cn.execute " EXEC sp_start_job @job_name = '同步数据' "

3)在任务执行期间,如果你试图再次执行同一个任务,程序会报错,所以非常有必要适时知道某一具体作业的执行状态,此时需要用到另外一个存储过程即sp_help_job
关于此过程的详细使用可以查看联机帮助,注意current_execution_status会返回任务的执行状态,
0   只返回那些空闲的或挂起的作业,执行完成后即返回状态0。
1   正在执行。
2   正在等待线程。
3   在两次重试之间。
4   空闲。
5   挂起。
7   正在执行完成操作。
在任务有多步的情况下current_execution_step会返回当前正在执行第几步任务 ,last_run_outcomeint返回作业上一次运行时所得到的结果:
0 = 失败
1 = 成功
3 = 取消
5 = 未知

4)停止作业的执行可以用sp_stop_job存储过程

5)另外如 sp_add_job、sp_delete_job、sp_update_job也有必要对其了解

6)扩展:执行 sp_helptext 'sp_start_job'看看SQL到底都做了些什么

知道上面这些内容对执行长时间的SQL任务就很有帮助了    
<think>好的,我现在需要帮助用户解决如何在SQLServer中设置自动执行函数的问题。首先,我需要回忆一下SQLServer中自动执行任务的方法。用户提到的是“自动执行函数”,可能是指定期或在特定事件触发时运行自定义函数。不过,根据我所知,SQL Server中的函数(如标量函数或表值函数)不能直接被设置为自动执行,因为它们通常需要在查询中被调用。接下来,用户可能想要的是让某个函数在特定时间或事件发生时自动运行。这时候,可能需要考虑使用SQLServer代理作业来定期执行存储过程,而存储过程内部可以调用所需的函数。或者,使用触发器在特定数据操作(如INSERT、UPDATE、DELETE)后触发执行包含函数的逻辑。 我需要检查用户的引用内容,看看是否有相关的信息。引用1提到了GETUTCDATE()、@@IDENTITY等系统函数,可能与默认值或触发器有关。引用2和3讨论了NEWID()和聚合函数,但可能不直接相关。不过,用户提供的引用中有提到系统函数和存储过程的例子,这可能帮助我构建答案。 可能的解决方案包括:1.使用SQLServer代理创建定时作业执行存储过程,存储过程中调用函数。2.使用DML触发器在数据变更时触发执行包含函数的逻辑。 3.使用DDL触发器响应结构变化,但这种情况较少用于执行函数。4.使用CLR集成创建更复杂的自动化任务,但需要额外配置。需要确认函数的类型,如果是标量或表值函数,它们需要在SELECT语句或存储过程中被调用。因此,自动执行可能需要封装在存储过程中,然后通过代理作业或触发器来调用该存储过程。 另外,要提醒用户权限问题,比如代理作业需要适当的权限,触发器可能会影响性能,需谨慎使用。还要注意函数的确定性,是否适合在自动执行的上下文中使用。总结步骤:1.创建存储过程封装函数调用。 2.使用SQLServer代理设置定时作业执行存储过程。 3.或者创建触发器在数据操作时执行存储过程。 4.提供具体的代码示例和配置步骤。需要确保回答结构清晰,分点说明不同方法,并给出示例代码,如创建存储过程和作业SQL语句。同时,生成相关问题,帮助用户进一步了解相关主题。</think>在 SQL Server 中实现函数自动执行需要通过封装调用逻辑并结合任务调度机制。以下是两种主要实现方式: ### 一、通过 SQL Server 代理定时执行 1. **创建存储过程封装函数调用** ```sql CREATE PROCEDURE dbo.AutoExecuteFunction AS BEGIN -- 调用函数示例:假设函数名为 dbo.CalculateStatistics SELECT dbo.CalculateStatistics(column_name) FROM target_table; END ``` 函数需满足可被调用的条件(如确定性或权限)[^3] 2. **配置定时作业** - 在 SSMS 中展开 **SQL Server 代理** -> 新建作业 - 添加步骤:类型选 `Transact-SQL`,命令填 `EXEC dbo.AutoExecuteFunction` - 设置计划:配置执行频率(如每天/每小时) $$JOB_{schedule} = \{ frequency: \text{DAILY}, interval: 1 \}$$ ### 二、通过触发器实现事件驱动 当需要响应数据变更时,可创建 DML 触发器: ```sql CREATE TRIGGER trg_AutoCalculate ON dbo.target_table AFTER INSERT,UPDATE AS BEGIN -- 调用函数处理新数据 INSERT INTO result_table SELECT dbo.ProcessNewData(inserted.id) FROM inserted; END ``` 注意触发器内无法直接调用返回结果集的表值函数[^3] ### 性能建议 1. 高频触发器场景建议使用内存优化表 2. 长时间运行的作业应设置超时限制 3. 通过 `sys.dm_exec_trigger_stats` 监控触发器性能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值