2012-05-18 15 views
8

मैं SQL सर्वर 2005 का उपयोग करने के साथ नमूना कोड खोजने की कोशिश कर रहा हूं, मुझे एजेंट नौकरी शुरू करने की आवश्यकता है और प्रक्रिया समाप्त होने तक प्रतीक्षा करें और फिर सफलता प्राप्त करें या विफलता।एजेंट नौकरी शुरू करने और पूर्ण होने तक प्रतीक्षा करें और सफलता या विफलता प्राप्त करें

मुझे पता है कि मैं

EXEC MSDB.dbo.sp_start_job @Job_Name = 'JobName' 

उपयोग कर सकते हैं काम शुरू करने के लिए लेकिन अगर यह सफल या असफल था मैं msdb.dbo.sp_help_job पोल पता करने के लिए जब यह पूरा हो गया है और फिर पता लगाने के लिए किसी भी नमूना कोड नहीं मिल सकता है ।

उत्तर

1

आप sysjobhistory तालिका में run_status कॉलम से परामर्श ले सकते हैं। 0 विफलता इंगित करता है।

0

शायद एक भयानक विश्वसनीय विधि नहीं है, लेकिन मैं शुरुआत में और प्रक्रिया के अंत में एक निश्चित तालिका में नौकरी लिखने की कोशिश कर सकता हूं, और अपने क्लाइंट एप्लिकेशन में उस तालिका को मतदान करने के लिए (या एडीओ का उपयोग करने के लिए) संबंधित घटना हैंडलर ट्रिगर करने के लिए घटनाओं)।

0

यहां कोड है जिसे मैंने इस उद्देश्य के लिए लिखा था। एक चेतावनी यह है कि यह उस मामले को संभाल नहीं लेता है जहां इस प्रक्रिया को निष्पादित करते समय नौकरी पहले से चल रही है।

CREATE PROCEDURE [admin].[StartAgentJobAndWaitForCompletion] 
    @JobName SYSNAME, 
    @TimeLimit INT   = 60, --  Stop waiting after this number of minutes 
    @Debug  BIT   = 0 
AS 
SET NOCOUNT ON; 

DECLARE @JobId   UNIQUEIDENTIFIER, 
     @Current  DATETIME, 
     @Message  NVARCHAR(MAX), 
     @SessionId  INT; 

SELECT @JobId = job_id 
    FROM msdb.dbo.sysjobs 
WHERE name = @JobName; 

IF @JobId IS NULL BEGIN 
    RAISERROR ('No job named "%s"', 16, 1, @JobName) WITH NOWAIT; 
    RETURN 1; 
END; 

EXEC msdb.dbo.sp_start_job @job_id = @JobId; 

IF @Debug =1 BEGIN 
    SET @Message = CONVERT(VARCHAR(19), CURRENT_TIMESTAMP, 120) + ' ' + @JobName  + ' started'; 
    RAISERROR (@Message, 0, 1) WITH NOWAIT; 
END; 

SET @Current = CURRENT_TIMESTAMP; 
WAITFOR DELAY '00:00:02'; -- Allow time for the system views to be populated 

WHILE DATEADD(mi, @TimeLimit, @Current) > CURRENT_TIMESTAMP BEGIN 
    SET @SessionId = NULL; 

    SELECT TOP(1) @SessionId = session_id 
     FROM msdb.dbo.sysjobactivity sja 
    WHERE sja.job_id = @JobId 
     AND sja.start_execution_date IS NOT NULL 
     AND sja.stop_execution_date IS NULL 
    ORDER BY sja.start_execution_date DESC; 

    IF @SessionId IS NULL 
     BREAK; 

    IF @Debug =1 BEGIN 
      SET @Message = CONVERT(VARCHAR(19), CURRENT_TIMESTAMP, 120) + ' ' + @JobName  + ', Session: ' + CONVERT(VARCHAR(38), @SessionId); 
     RAISERROR (@Message, 0, 1) WITH NOWAIT; 
    END; 

    WAITFOR DELAY '00:00:05'; 
                          END; 

IF @Debug = 1 BEGIN 
    SET @Message = CONVERT(VARCHAR(19), CURRENT_TIMESTAMP, 120) + ' ' + @JobName  + ' completed'; 
    RAISERROR (@Message, 0, 1) WITH NOWAIT; 
END; 

WAITFOR DELAY '00:00:02'; -- Allow time for the system views to be populated 

RETURN 0; 
0
CREATE PROCEDURE dbo.usp_RunJobWithOutcome 
@JobName sysname 
, @RunTimeout int 
, @RunStatus int output 
AS 
SET NOCOUNT ON 

--Verify that this job exists 
IF NOT EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE [name] = @JobName) 
BEGIN 
    SET @RunStatus = 5 --Unknown 
    RAISERROR('Invalid job name ''%s''', 16, 245, @JobName); 
    RETURN 1 
END; 

--Start the job 
DECLARE @retval int; 
exec @retval = msdb.dbo.sp_start_job @[email protected]; 

--If start succeeded, poll for completion 
IF @retval = 0 
BEGIN 
    PRINT N'Job started successfully'; 
    WAITFOR DELAY '00:00:05'; 

    DECLARE @JobRunTime int; 
    SET @JobRunTime = 0; 
    SET @RunStatus = 5; --Unknown -> default return 

    WHILE @JobRunTime < @RunTimeout 
    BEGIN 
     WAITFOR DELAY '00:00:05'; 

     --SELECT statement below give the same result as 'sp_help_jobactivity' sys-proc 
     SELECT @JobRunTime = CASE WHEN stop_execution_date IS NULL THEN DATEDIFF(SECOND, start_execution_date, GETDATE()) ELSE @RunTimeout END 
     FROM ( 
      SELECT ja.session_id, ja.job_id, j.[name] job_name, ja.run_requested_date, ja.run_requested_source, ja.queued_date, ja.start_execution_date 
       , ja.last_executed_step_id, ja.last_executed_step_date, ja.stop_execution_date, ja.next_scheduled_run_date, ja.job_history_id 
       , jh.[message], jh.run_status, jh.operator_id_emailed, jh.operator_id_netsent, jh.operator_id_paged 
      FROM msdb.dbo.sysjobactivity ja 
      JOIN msdb.dbo.sysjobs j ON ja.job_id = j.job_id 
      LEFT JOIN msdb.dbo.sysjobhistory jh ON ja.job_history_id = jh.instance_id 
      WHERE ja.session_id = (SELECT MAX(session_id) FROM msdb.dbo.sysjobactivity ja1 WHERE ja1.job_id = ja.job_id AND ja1.run_requested_date IS NOT NULL) 
       AND j.[name] = @JobName 
     ) JobActivity; 
    END; 

    --Get the final stats 
    SELECT @RunStatus=run_status, @JobRunTime=DATEDIFF(SECOND, start_execution_date, stop_execution_date) 
    FROM (
     SELECT ja.session_id, ja.job_id, j.[name] job_name, ja.run_requested_date, ja.run_requested_source, ja.queued_date, ja.start_execution_date 
      , ja.last_executed_step_id, ja.last_executed_step_date, ja.stop_execution_date, ja.next_scheduled_run_date, ja.job_history_id 
      , jh.[message], jh.run_status, jh.operator_id_emailed, jh.operator_id_netsent, jh.operator_id_paged 
     FROM msdb.dbo.sysjobactivity ja 
     JOIN msdb.dbo.sysjobs j ON ja.job_id = j.job_id 
     LEFT JOIN msdb.dbo.sysjobhistory jh ON ja.job_history_id = jh.instance_id 
     WHERE ja.session_id = (SELECT MAX(session_id) FROM msdb.dbo.sysjobactivity ja1 WHERE ja1.job_id = ja.job_id AND ja1.run_requested_date IS NOT NULL) 
      AND j.[name] = @JobName 
    ) JobActivity; 

    PRINT N'Job completed in ' + CONVERT(nvarchar, @JobRunTime) + ' seconds.' 
    IF @RunStatus = 1 RETURN 0; --Success 
    ELSE RETURN 1; --Failed 
END; 
ELSE 
BEGIN 
    PRINT N'Job could not start'; 
    SET @RunStatus = 5 --Unknown 
    RETURN 1; --failed 
END; 

GO 
DECLARE @RunStatus int, @retval int 
--Run for max 60 minutes 
exec @retval=dbo.usp_RunJobWithOutcome @JobName='*<your job name here>*', @RunTimeout=3600, @[email protected] output 

SELECT @retval, @RunStatus 
GO 
3
-- ============================================= 
-- Description: Starts a SQLAgent Job and waits for it to finish or until a specified wait period elapsed 
-- @result: 1 -> OK 
--   0 -> still running after maxwaitmins 
-- ============================================= 
CREATE procedure [dbo].[StartAgentJobAndWait](@job nvarchar(128), @maxwaitmins int = 5) --, @result int output) 
AS 
BEGIN 

set NOCOUNT ON; 
set XACT_ABORT ON; 

    BEGIN TRY 

    declare @running as int 
    declare @seccount as int 
    declare @maxseccount as int 
    declare @start_job as bigint 
    declare @run_status as int 

    set @start_job = cast(convert(varchar, getdate(), 112) as bigint) * 1000000 + datepart(hour, getdate()) * 10000 + datepart(minute, getdate()) * 100 + datepart(second, getdate()) 

    set @maxseccount = 60*@maxwaitmins 
    set @seccount = 0 
    set @running = 0 

    declare @job_owner sysname 
    declare @job_id UNIQUEIDENTIFIER 

    set @job_owner = SUSER_SNAME() 

    -- get job id 
    select @job_id=job_id 
    from msdb.dbo.sysjobs sj 
    where [email protected] 

    -- invalid job name then exit with an error 
    if @job_id is null 
     RAISERROR (N'Unknown job: %s.', 16, 1, @job) 

    -- output from stored procedure xp_sqlagent_enum_jobs is captured in the following table 
    declare @xp_results TABLE (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) 

    -- start the job 
    declare @r as int 
    exec @r = msdb..sp_start_job @job 

    -- quit if unable to start 
    if @r<>0 
     RAISERROR (N'Could not start job: %s.', 16, 2, @job) 

    -- start with an initial delay to allow the job to appear in the job list (maybe I am missing something ?) 
    WAITFOR DELAY '0:0:01'; 
    set @seccount = 1 

    -- check job run state 
    insert into @xp_results 
    execute master.dbo.xp_sqlagent_enum_jobs 1, @job_owner, @job_id 

    set @running= (SELECT top 1 running from @xp_results) 

    while @running<>0 and @seccount < @maxseccount 
    begin 
     WAITFOR DELAY '0:0:01'; 
     set @seccount = @seccount + 1 

     delete from @xp_results 

     insert into @xp_results 
     execute master.dbo.xp_sqlagent_enum_jobs 1, @job_owner, @job_id 

     set @running= (SELECT top 1 running from @xp_results) 
    end 

    -- result: not ok (=1) if still running 

    if @running <> 0 begin 
     -- still running 
     return 0 
    end 
    else begin 

     -- did it finish ok ? 
     set @run_status = 0 

     select @run_status=run_status 
     from msdb.dbo.sysjobhistory 
     where [email protected]_id 
      and cast(run_date as bigint) * 1000000 + run_time >= @start_job 

     if @run_status=1 
      return 1 --finished ok 
     else --error 
      RAISERROR (N'job %s did not finish successfully.', 16, 2, @job) 

    end 

    END TRY 
    BEGIN CATCH 

    DECLARE 
     @ErrorMessage NVARCHAR(4000), 
     @ErrorNumber  INT, 
     @ErrorSeverity INT, 
     @ErrorState  INT, 
     @ErrorLine  INT, 
     @ErrorProcedure NVARCHAR(200); 

    SELECT 
     @ErrorNumber = ERROR_NUMBER(), 
     @ErrorSeverity = ERROR_SEVERITY(), 
     @ErrorState = ERROR_STATE(), 
     @ErrorLine = ERROR_LINE(), 
     @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-'); 

    SELECT @ErrorMessage = 
     N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 
      'Message: '+ ERROR_MESSAGE(); 

    RAISERROR 
     (
     @ErrorMessage, 
     @ErrorSeverity, 
     1, 
     @ErrorNumber, -- original error number. 
     @ErrorSeverity, -- original error severity. 
     @ErrorState,  -- original error state. 
     @ErrorProcedure, -- original error procedure name. 
     @ErrorLine  -- original error line number. 
     ); 

    END CATCH 
END 
संबंधित मुद्दे