我有一个SSIS ETL,因为它一直期待着新文件的到来,所以我需要它在完成后自动重新启动。但是,我不希望实例连续循环运行。
我的想法是在最后一个程序包完成之前使用Execute SQL Agent任务,但我已经对此进行了测试,但我收到一条错误消息,指出无法由拥有活动作业的同一用户启动SQL Agent作业运行。
我正在寻找有关重新触发SQL代理作业的最佳方法的一些建议。我当时在考虑创建一个单独的工作,然后执行该工作以开始所需的工作-我想尽管这样做必须有更好的方法。
欢迎任何建议或指点。
谢谢
答案 0 :(得分:2)
由于您不希望SSIS包连续不断地运行,因此可以安排SQL Agent作业每10秒运行一次。那是我最常能安排工作的时间。如果作业的上一次运行仍在10秒后进行,则它将不会启动该程序包的另一个实例。完成后,它将在10秒后再次启动。
答案 1 :(得分:0)
我在Polling in SQL Agent上整理了一条帖子,该查询每5秒检查一次文件,最长不超过60秒(所有时间均可配置)
SET NOCOUNT ON;
-- http://www.patrickkeisler.com/2012/11/how-to-use-xpdirtree-to-list-all-files.html
DECLARE
-- Don't do stupid things like adding spaces into folder names
@sourceFolder varchar(260) = 'C:\ssisdata\Input'
-- Have to use SQL matching rules, not DOS/SSIS
, @fileMask sysname = 'SourceData%.txt'
-- how long to wait between polling
, @SleepInSeconds int = 5
-- Don't exceed 24 hours aka 86400 seconds
, @MaxTimerDurationInSeconds int = (3600 * 0) + (60 * 1) + 0
-- parameter for xp_dirtree 0 => top folder only; 1 => subfolders
, @depth int = 1
-- parameter for xp_dirtree 0 => directory only; 1 => directory and files
, @collectFile int = 1
, @RC bigint = 0;
-- Create a table variable to capture the results of our directory command
DECLARE
@DirectoryTree table
(
id int IDENTITY(1, 1)
, subdirectory nvarchar(512)
, depth int
, isFile bit
);
-- Use our sleep in seconds time to generate a delay time string
DECLARE
@delayTime char(10) = CONVERT(char(10), TIMEFROMPARTS(@SleepInSeconds/60 /60, @SleepInSeconds/60, @SleepInSeconds%60, 0, 0), 108)
, @stopDateTime datetime2(0) = DATEADD(SECOND, @MaxTimerDurationInSeconds, CURRENT_TIMESTAMP);
-- Force creation of the folder
EXECUTE dbo.xp_create_subdir @sourceFolder;
-- Load the results of our directory
INSERT INTO
@DirectoryTree
(
subdirectory
, depth
, isFile
)
EXECUTE dbo.xp_dirtree
@sourceFolder
, @depth
, @collectFile;
-- Prime the pump
SELECT
@RC = COUNT_BIG(1)
FROM
@DirectoryTree AS DT
WHERE
DT.isFile = 1
AND DT.subdirectory LIKE @fileMask;
WHILE @rc = 0 AND @stopDateTime > CURRENT_TIMESTAMP
BEGIN
-- Load the results of our directory
INSERT INTO
@DirectoryTree
(
subdirectory
, depth
, isFile
)
EXECUTE dbo.xp_dirtree
@sourceFolder
, @depth
, @collectFile;
-- Test for file existence
SELECT
@RC = COUNT_BIG(1)
FROM
@DirectoryTree AS DT
WHERE
DT.isFile = 1
AND DT.subdirectory LIKE @fileMask;
IF @RC = 0
BEGIN
-- Put our process to sleep for a period of time
WAITFOR DELAY @delayTime;
END
END
-- at this point, we have either exited due to file found or time expired
IF @RC > 0
BEGIN
-- Take action when file was found
PRINT 'Go run SSIS or something';
END
ELSE
BEGIN
-- Take action for file not delivered in expected timeframe
PRINT 'Naughty, naughty';
END
要满足您的特定需求,可以像这样设置作业。
在这一点上,我们在这里有皮带,背带和吊带。作业每2分钟启动一次。如果作业已经在运行,则不会发生任何不良情况。一旦工作开始,它就会四处寻找文件。如果超时,则会引发异常(您的TODO),该异常会使代理作业等待2分钟,然后重试30次。
EXEC msdb.dbo.sp_add_job
@job_name = N'SQL Agent 2 minutes max'
, @enabled = 1
, @notify_level_eventlog = 0
, @notify_level_email = 2
, @notify_level_page = 2
, @delete_level = 0
, @category_name = N'[Uncategorized (Local)]'
, @job_id = @jobId OUTPUT;
SELECT
@jobId;
GO
EXEC msdb.dbo.sp_add_jobserver
@job_name = N'SQL Agent 2 minutes max'
, @server_name = N'.\DEV2014';
GO
USE msdb;
GO
EXEC msdb.dbo.sp_add_jobstep
@job_name = N'SQL Agent 2 minutes max'
, @step_name = N'Polling'
, @step_id = 1
, @cmdexec_success_code = 0
, @on_success_action = 3
, @on_fail_action = 2
, @retry_attempts = 30
, @retry_interval = 2
, @os_run_priority = 0
, @subsystem = N'TSQL'
, @command = N'SELECT 1 AS PasteInTheFullQuery'
, @database_name = N'master'
, @flags = 0;
GO
USE msdb;
GO
EXEC msdb.dbo.sp_add_jobstep
@job_name = N'SQL Agent 2 minutes max'
, @step_name = N'Run SSIS'
, @step_id = 2
, @cmdexec_success_code = 0
, @on_success_action = 1
, @on_fail_action = 2
, @retry_attempts = 0
, @retry_interval = 0
, @os_run_priority = 0
, @subsystem = N'SSIS'
, @command = N'/ISSERVER "\"\SSISDB\Demo\ProjectDeploymentModel\Package2.dtsx\"" /SERVER "\".\dev2014\"" /Par "\"$ServerOption::LOGGING_LEVEL(Int16)\"";1 /Par "\"$ServerOption::SYNCHRONIZED(Boolean)\"";True /CALLERINFO SQLAGENT /REPORTING E'
, @database_name = N'master'
, @flags = 0;
GO
USE msdb;
GO
EXEC msdb.dbo.sp_update_job
@job_name = N'SQL Agent 2 minutes max'
, @enabled = 1
, @start_step_id = 1
, @notify_level_eventlog = 0
, @notify_level_email = 2
, @notify_level_page = 2
, @delete_level = 0
, @description = N''
, @category_name = N'[Uncategorized (Local)]'
, @notify_email_operator_name = N''
, @notify_page_operator_name = N'';
GO
USE msdb;
GO
DECLARE @schedule_id int;
EXEC msdb.dbo.sp_add_jobschedule
@job_name = N'SQL Agent 2 minutes max'
, @name = N'Every 2 minutes'
, @enabled = 1
, @freq_type = 4
, @freq_interval = 1
, @freq_subday_type = 4
, @freq_subday_interval = 2
, @freq_relative_interval = 0
, @freq_recurrence_factor = 1
, @active_start_date = 20181018
, @active_end_date = 99991231
, @active_start_time = 60000
, @active_end_time = 235959
, @schedule_id = @schedule_id OUTPUT;
SELECT
@schedule_id;
GO