Sqlserver Sql Agent Job 只能同时有一个实例运行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sqlserver Sql Agent Job 只能同时有一个实例运行相关的知识,希望对你有一定的参考价值。

Sqlserver Sql Agent中的Job默认情况下只能有一个实例在运行,也就是说假如你的Sql Agent里面有一个正在运行的Job叫"Test Job",如果你现在再去启动一次"Test Job"就会报错,因为Sqlserver规定在一个Sqlserver账号下,Sql Agent不能同时启动相同的Job两次,只有前一次启动执行完成后,才能够再次启动该Job。

 

那么随之而来的问题是如何用sql语句检测Job是否已经执行完毕了呢?下面有一个语句可以作为参考:

Declare @Job_ID as UNIQUEIDENTIFIER
select @Job_ID =Job_ID from msdb.dbo.sysjobs where name = James_Test--name就是Job的名字

Exec master..sp_MSget_jobstate @Job_ID  --返回值为 1 - 正在运行,4 - 表示完成(成功或失败)

以上语句的关键就是调用一个master库中的系统存储过程sp_MSget_jobstate,这个存储过程的结构可以从Sqlserver中查到如下,必要时可以建立一个自定义存储过程进行修改:

USE [master]
GO
/****** Object:  StoredProcedure [sys].[sp_MSget_jobstate]    Script Date: 2016/1/29 13:51:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- Procedure sp_MSget_jobstate
--
-- Descriptions: 
--    The proc takes a specific Job ID and returns the Job State of the job
--        Returns a row with one column job_state
--        Returns a row with NULL if job does not exist
-- 
-- Parameters: as defined in create statement
--
-- Returns: 0 - success
--          1 - Otherwise
--
-- Security: 
-- Requires Certificate signature for catalog access
--
ALTER procedure [sys].[sp_MSget_jobstate]
    @job_id             UNIQUEIDENTIFIER
AS
BEGIN
    DECLARE @is_sysadmin INT
    DECLARE @job_owner   sysname
    DECLARE @job_state   INT 
    DECLARE @job_id_as_char VARCHAR(36)

    SET NOCOUNT ON

    CREATE TABLE #xp_results (job_id                UNIQUEIDENTIFIER NOT NULL,
                            last_run_date         INT              NOT NULL,
                            last_run_time         INT              NOT NULL,
                            next_run_date         INT              NOT NULL,
                            next_run_time         INT              NOT NULL,
                            next_run_schedule_id  INT              NOT NULL,
                            requested_to_run      INT              NOT NULL, -- BOOL
                            request_source        INT              NOT NULL,
                            request_source_id     sysname          collate database_default null,
                            running               INT              NOT NULL, -- BOOL
                            current_step          INT              NOT NULL,
                            current_retry_attempt INT              NOT NULL,
                            job_state             INT              NOT NULL)

    -- Need a job_id
    if (@job_id IS NULL)
    BEGIN
        SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
        RAISERROR(14262, -1, -1, @job_id, @job_id_as_char)
        RETURN(1) -- Failure
    END

    -- Capture job execution information (for local jobs only since that‘s all SQLServerAgent caches)
    SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(Nsysadmin), 0)
    SELECT @job_owner = suser_sname(suser_sid())
    INSERT INTO #xp_results
    EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner

    -- Select the job state of the job in question
    SELECT @job_state = job_state FROM #xp_results WHERE @job_id = job_id

    -- Error if we have no rows selected
    if (@job_state IS NULL)
    BEGIN
        SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
        RAISERROR(14262, -1, -1, @job_id, @job_id_as_char)
        RETURN(1) -- Failure
    END
    ELSE
        SELECT @job_state
    
    -- All done
    DROP TABLE #xp_results
    RETURN(0)    -- Success
END


如果查询到Sql Agent中的Job正在执行,可以使用存储过程msdb.dbo.sp_stop_job强制停止Job,然后再使用存储过程msdb.dbo.sp_start_job来启动Job,需要注意的是如果在已经停止的Job上调用msdb.dbo.sp_stop_job或者在正在执行的Job上调用msdb.dbo.sp_start_job会报错,所以在调用存储过程msdb.dbo.sp_start_job和msdb.dbo.sp_stop_job前需要判断Job的当前执行状态,或者使用sql的Try Catch语句来捕获错误,msdb.dbo.sp_stop_job和msdb.dbo.sp_stop_job的使用方法如下所示:

EXEC msdb.dbo.sp_start_job @job_name=Job_name--Job_name就是Job的名字
EXEC msdb.dbo.sp_stop_job    @job_name=Job_name--Job_name就是Job的名字

 

以上是关于Sqlserver Sql Agent Job 只能同时有一个实例运行的主要内容,如果未能解决你的问题,请参考以下文章

SQLServer · BUG分析 · Agent 链接泄露分析(转载)

Security7:管理SQL Server Agent的权限

How to automatic process SSAS cube using SQL Server agent job

通往SQL Server代理的阶梯-二级:作业步骤和子系统

SQL Server Agent不能启动

SQL Server Agent 安装及配置使用