如何在SQL Server Express Edition中每天运行一个存储过程?

25

这篇文章看起来很有趣(在相关问题的一个答案中引用): http://www.sqlteam.com/article/scheduling-jobs-in-sql-server-express - Thomas Bratt
11个回答

25

11

我发现以下机制适用于我。

USE Master
GO

IF  EXISTS( SELECT *
            FROM sys.objects
            WHERE object_id = OBJECT_ID(N'[dbo].[MyBackgroundTask]')
            AND type in (N'P', N'PC'))
    DROP PROCEDURE [dbo].[MyBackgroundTask]
GO

CREATE PROCEDURE MyBackgroundTask
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- The interval between cleanup attempts
    declare @timeToRun nvarchar(50)
    set @timeToRun = '03:33:33'

    while 1 = 1
    begin
        waitfor time @timeToRun
        begin
            execute [MyDatabaseName].[dbo].[MyDatabaseStoredProcedure];
        end
    end
END
GO

-- Run the procedure when the master database starts.
sp_procoption    @ProcName = 'MyBackgroundTask',
                @OptionName = 'startup',
                @OptionValue = 'on'
GO

一些注意事项:

  • 值得写入审核条目以便您可以查看查询是否确实运行。
  • 服务器需要重新启动一次,以确保脚本第一次运行。

结合您的审计跟踪,我会在存储过程中添加一个进程历史记录检查,以便如果它在24小时内或其他时间段内没有运行 - 就在启动时运行该进程。这将处理机器在夜间关闭或偶尔关闭或类似情况(按需启动的VM)的情况。 - Cade Roux
好主意!对于我们的情况,数据库会持续运行,因为它是一个24x7运行的客户系统。我想知道在等待之前运行'MyDatabaseStoredProcedure'脚本是否是最简单的方法?对于我们的情况,这将很好地工作,但对于不同的应用要求可能不适用。 - Thomas Bratt
在后台持续运行一个过程是否存在任何缺点? - tufelkinder
缺点:
  1. 每次需要安排作业时都必须创建一个新的存储过程
  2. 每次计划更改都需要重新启动
- Raj More
您可以通过为每个计划任务创建一个运行标志的表来避免重新启动。在存储过程的顶部设置标志,并在while条件中使用它。清除标志将导致在当前迭代完成后停止。我还建议您拥有一个表,以便可以存储最后的开始时间和持续时间,以进行诊断。 - VoteCoffee
存储过程 sp_procoption, 语句“CONFIG”在此版本的SQL Server中不受支持。 - Eng Soon Cheah

5
创建一个定时任务,在启动时调用"C:\YourDirNameHere\TaskScript.vbs"。VBScript应该执行重复的任务执行(在这个例子中,它是一个15分钟的循环)。
通过命令行(必须以管理员身份运行cmd.exe):
schtasks.exe /create /tn "TaskNameHere" /tr "\"C:\YourDirNameHere\TaskScript.vbs\" " /sc ONSTARTUP

示例TaskScript.vbs:使用RunSQLScript.bat静默执行您的自定义SQL脚本

Do While 1
    WScript.Sleep(60000*15)
    Set WshShell = CreateObject("WScript.Shell")
    WshShell.RUN "cmd /c C:\YourDirNameHere\RunSQLScript.bat C:\YourDirNameHere\Some_TSQL_Script.sql", 0
Loop

RunSQLScript.bat:这个脚本使用sqlcmd调用数据库实例并执行SQL脚本。

@echo off
sqlcmd -S .\SQLEXPRESS -i %1

我需要修复任务计划命令(通过命令行)。事实证明,它在下一次启动时不会自动重启,我必须手动纠正它。我稍后会编辑和修复代码,只是想让大家知道。执行代码非常好用。 - VoteCoffee
还在忙吗?或者你有时间修复这个命令,让这个答案完整吗? - Hugo Delsing
我发现我需要的设置是高级的,而且 schtask.exe 不支持。我选择让 vbs 执行重复功能,并将其设置为在启动时运行。现在很好。 - VoteCoffee

4
如果您使用的是Express版本,您需要使用Windows计划任务程序或以某种方式连接到服务器的应用程序。您可以使用计划任务程序来运行sqlcmd。这里有一些说明,可以帮助您在Express版本中使sqlcmd正常工作。

2

SQL Scheduler 来自 http://www.lazycoding.com/products.aspx

  • 免费且简单易用
  • 支持所有版本的 SQL Server 2000、2005 和 2008
  • 支持无限数量的 SQL Server 实例和作业
  • 可轻松安排 SQL Server 维护任务,如备份、索引重建、完整性检查等
  • 作为 Windows 服务运行
  • 在作业成功或失败时发送电子邮件通知

1
这个链接已经失效了。 - done_merson

1

我发现解决这个问题最简单的方法是创建一个查询来执行存储过程,然后保存它。查询应该类似于下面的示例。

     use [database name]
     exec storedproc.sql

然后创建一个批处理文件,其中包含类似下面代码的内容。
sqlcmd -S servername\SQLExpress -i c:\expressmaint.sql

然后让任务计划程序按照您的喜好执行批处理。

1

由于已经有一个类似的问题被问到了,而且很可能会被关闭作为这个问题的重复,并且在已经存在的答案中没有提到许多选项...

由于您正在使用SQL Express,因此无法使用SQL Server Agent。但是有许多替代方案,所有这些方案都可以使用 AT Windows任务计划程序进行调度,具体取决于您的操作系统:

所有这些语言/工具(以及许多其他工具)都可以连接到SQL Server并执行存储过程。您还可以尝试这些代理程序替代品:

SQLScheduleer链接已失效。 - done_merson

1

0
您可以使用任务计划程序调用一个简单的控制台应用程序来执行SQL语句。

0

正如您所指出的,如果没有代理进程,您将需要其他外部服务来执行此操作,例如编写和安装服务或使用Windows计划任务。

请注意,在本地应用程序的Express安装中,可能会出现这样的情况:在您想要截断表格的时间(比如每晚午夜),机器可能没有开启(用户从未开启机器)。

因此,您的定时任务永远不会运行,您的审计日志也会失控(这也是SQL Server代理的问题,但人们会认为真正的服务器应该是不间断运行的)。如果这种情况适合您,请采用更好的策略,即当应用程序检测到自上次截断以来已经过了X天或者进行了其他操作时,按需执行。

另一个需要考虑的问题是,如果您正在谈论Web应用程序,可能会有应用程序加载的时间,并且可以在该事件触发时执行操作。

如评论中所提到的,有sp_procoption - 这可能允许您的SP在每次启动引擎时运行 - 此方法的缺点是对于长时间运行的实例,可能会在调用之间花费很长时间,并且如果在需要执行操作的时间引擎没有运行,则仍然存在问题。


sp_procoption允许存储过程自动运行。 - Thomas Bratt

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