T-SQLを使用して、MS SQL Serverのあるインスタンスから別のインスタンスにジョブとスケジュールを転送する

まえがき



多くの場合、エージェントジョブをMS SQL Serverの別のインスタンスに転送する必要があります。 エージェントのタスクだけを転送する必要がある場合や、MS SQL Serverの新しいバージョンにアップグレードする場合が多いため、msdbデータベースの復元が常に適切なソリューションとは限りません。 それでは、msdbデータベースを復元せずに、どのようにエージェントジョブを転送できますか?



この記事では、MS SQL Serverのあるインスタンスから別のインスタンスにエージェントジョブをコピーするT-SQLスクリプトの実装例を分析します。 このソリューションは、MS SQL Server 2012-2016からMS SQL Server 2017にエージェントタスクを転送するときにテストされました。



解決策



最初に、アクションのシーケンスについて説明します。



1)転送する必要のないタスクのリストを作成する

2)タスク自体を転送する

3)転送されたタスクのステップを転送する

4)転送されたタスクの転送スケジュール

5)転送されたタスクのスケジュールとタスクのリンクを転送します

6)移行されたジョブのターゲットサーバーを転送する

7)タスクを登録してスケジュールをアクティブにし、これらのタスクを非アクティブモードに転送します(タスクをオフにすることにより)

8)転送されたすべてのタスクの所有者を割り当てます(たとえば、sa)



次に、各項目について、T-SQLでの実装を提供します。



8つのステップはすべて1つのブロックで実行する必要があります。 ただし、理解を深めるために、各ブロックについて個別に説明します。 これらの8つの手順を実行する前に、タスクのコピー先となるMS SQL Serverのインスタンスをリンクする必要もあります。



だから:



1)転送する必要のないタスクを収集します。



リクエスト
select ss.[schedule_uid] ,js.[job_id] into #tbl_notentity from [msdb].[dbo].[sysjobschedules] as js inner join [msdb].[dbo].[sysschedules] as ss on js.[schedule_id]=ss.[schedule_id] where [job_id] in ( < GUID-  ,    > )
      
      





したがって、タスクスケジュールのGUIDとタスク自体のGUIDのペアを含む、移植性のないタスク#tbl_notentityのテーブルを受け取りました。



2)タスク自体を転送します。



リクエスト
 select *, 0 as IsAdd into #tbl_jobs from [-].[msdb].[dbo].[sysjobs]; ;with src as ( select * from [msdb].[dbo].[sysjobs] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[job_id]=src.[job_id] ) ) merge #tbl_jobs as trg using src on trg.[job_id]=src.[job_id] when not matched by target then INSERT ([job_id] ,[originating_server_id] ,[name] ,[enabled] ,[description] ,[start_step_id] ,[category_id] ,[owner_sid] ,[notify_level_eventlog] ,[notify_level_email] ,[notify_level_netsend] ,[notify_level_page] ,[notify_email_operator_id] ,[notify_netsend_operator_id] ,[notify_page_operator_id] ,[delete_level] ,[date_created] ,[date_modified] ,[version_number] ,[IsAdd]) VALUES (src.[job_id] ,src.[originating_server_id] ,src.[name] ,src.[enabled] ,src.[description] ,src.[start_step_id] ,src.[category_id] ,src.[owner_sid] ,src.[notify_level_eventlog] ,src.[notify_level_email] ,src.[notify_level_netsend] ,src.[notify_level_page] ,src.[notify_email_operator_id] ,src.[notify_netsend_operator_id] ,src.[notify_page_operator_id] ,src.[delete_level] ,src.[date_created] ,src.[date_modified] ,src.[version_number] ,1); insert into [-].[msdb].[dbo].[sysjobs]([job_id] ,[originating_server_id] ,[name] ,[enabled] ,[description] ,[start_step_id] ,[category_id] ,[owner_sid] ,[notify_level_eventlog] ,[notify_level_email] ,[notify_level_netsend] ,[notify_level_page] ,[notify_email_operator_id] ,[notify_netsend_operator_id] ,[notify_page_operator_id] ,[delete_level] ,[date_created] ,[date_modified] ,[version_number]) select [job_id] ,[originating_server_id] ,[name] ,[enabled] ,[description] ,[start_step_id] ,[category_id] ,[owner_sid] ,[notify_level_eventlog] ,[notify_level_email] ,[notify_level_netsend] ,[notify_level_page] ,[notify_email_operator_id] ,[notify_netsend_operator_id] ,[notify_page_operator_id] ,[delete_level] ,[date_created] ,[date_modified] ,[version_number] from #tbl_jobs where IsAdd=1;
      
      





最初に、受信サーバーで利用可能なすべてのジョブをテーブル#tbl_jobsに収集します。 次に、MERGE命令を使用して、[job_id]フィールドに沿って、アルゴリズムのステップ1の#tbl_notentityテーブルにないソースサーバーのすべての欠落ジョブをこのテーブルにマージします。 挿入された行は、IsAdd列で1としてマークされます。 そして、すべてのジョブを[msdb]。[Dbo]。[Dbo]。[Sysjobs]テーブルに追加します。このテーブルは、IsAdd = 1の条件で#tbl_jobsテーブルから取得します。 したがって、これらのジョブは、アルゴリズムの項目1からテーブル#tbl_notentityにない宛先サーバーに転送されました。



3)転送されたタスクのステップを転送します。



リクエスト
 select *, 0 as IsAdd into #tbl_jobsteps from [-].[msdb].[dbo].[sysjobsteps]; ;with src as ( select * from [msdb].[dbo].[sysjobsteps] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[job_id]=src.[job_id] ) ) merge #tbl_jobsteps as trg using src on trg.[job_id]=src.[job_id] and trg.[step_id]=src.[step_id] when not matched by target then INSERT ([job_id] ,[step_id] ,[step_name] ,[subsystem] ,[command] ,[flags] ,[additional_parameters] ,[cmdexec_success_code] ,[on_success_action] ,[on_success_step_id] ,[on_fail_action] ,[on_fail_step_id] ,[server] ,[database_name] ,[database_user_name] ,[retry_attempts] ,[retry_interval] ,[os_run_priority] ,[output_file_name] ,[last_run_outcome] ,[last_run_duration] ,[last_run_retries] ,[last_run_date] ,[last_run_time] ,[proxy_id] ,[step_uid] ,[IsAdd]) VALUES (src.[job_id] ,src.[step_id] ,src.[step_name] ,src.[subsystem] ,src.[command] ,src.[flags] ,src.[additional_parameters] ,src.[cmdexec_success_code] ,src.[on_success_action] ,src.[on_success_step_id] ,src.[on_fail_action] ,src.[on_fail_step_id] ,src.[server] ,src.[database_name] ,src.[database_user_name] ,src.[retry_attempts] ,src.[retry_interval] ,src.[os_run_priority] ,src.[output_file_name] ,src.[last_run_outcome] ,src.[last_run_duration] ,src.[last_run_retries] ,src.[last_run_date] ,src.[last_run_time] ,src.[proxy_id] ,src.[step_uid] ,1); insert into [-].[msdb].[dbo].[sysjobsteps]([job_id] ,[step_id] ,[step_name] ,[subsystem] ,[command] ,[flags] ,[additional_parameters] ,[cmdexec_success_code] ,[on_success_action] ,[on_success_step_id] ,[on_fail_action] ,[on_fail_step_id] ,[server] ,[database_name] ,[database_user_name] ,[retry_attempts] ,[retry_interval] ,[os_run_priority] ,[output_file_name] ,[last_run_outcome] ,[last_run_duration] ,[last_run_retries] ,[last_run_date] ,[last_run_time] ,[proxy_id] ,[step_uid]) select [job_id] ,[step_id] ,[step_name] ,[subsystem] ,[command] ,[flags] ,[additional_parameters] ,[cmdexec_success_code] ,[on_success_action] ,[on_success_step_id] ,[on_fail_action] ,[on_fail_step_id] ,[server] ,[database_name] ,[database_user_name] ,[retry_attempts] ,[retry_interval] ,[os_run_priority] ,[output_file_name] ,[last_run_outcome] ,[last_run_duration] ,[last_run_retries] ,[last_run_date] ,[last_run_time] ,[proxy_id] ,[step_uid] from #tbl_jobsteps where IsAdd=1; drop table #tbl_jobsteps;
      
      





最初に、受信サーバーで利用可能なすべてのジョブステップをテーブル#tbl_jobstepsに収集します。 次に、MERGE命令を使用して、[job_id]フィールドと[step_id]フィールドを、アルゴリズムのステップ1の#tbl_notentityテーブルにないソースサーバーのすべての欠落ジョブステップをこのテーブルにマージします。 挿入された行は、IsAdd列で1としてマークされます。 さらに、すべてのジョブステップをテーブル[msdb]。[Dbo]。[Dbo] .IsAdd = 1の条件でテーブル#tbl_jobstepsからの受信者サーバーの[Sysjobsteps]に追加します。 次に、テーブル#tbl_jobstepsを削除します。さらにそれはもう必要ありません。



したがって、これらのタスクのすべてのステップは、アルゴリズムの項目1のテーブル#tbl_notentityにない宛先サーバーに転送されました。



4)転送されたタスクのスケジュールを転送するには:



リクエスト
 select *, 0 as IsAdd into #tbl_sysschedules from [-].[msdb].[dbo].[sysschedules]; ;with src as ( select * from [msdb].[dbo].[sysschedules] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[schedule_uid]=src.[schedule_uid] ) ) merge #tbl_sysschedules as trg using src on trg.[schedule_uid]=src.[schedule_uid] when not matched by target then INSERT ([schedule_id] ,[schedule_uid] ,[originating_server_id] ,[name] ,[owner_sid] ,[enabled] ,[freq_type] ,[freq_interval] ,[freq_subday_type] ,[freq_subday_interval] ,[freq_relative_interval] ,[freq_recurrence_factor] ,[active_start_date] ,[active_end_date] ,[active_start_time] ,[active_end_time] ,[date_created] ,[date_modified] ,[version_number] ,[IsAdd]) VALUES (src.[schedule_id] ,src.[schedule_uid] ,src.[originating_server_id] ,src.[name] ,src.[owner_sid] ,src.[enabled] ,src.[freq_type] ,src.[freq_interval] ,src.[freq_subday_type] ,src.[freq_subday_interval] ,src.[freq_relative_interval] ,src.[freq_recurrence_factor] ,src.[active_start_date] ,src.[active_end_date] ,src.[active_start_time] ,src.[active_end_time] ,src.[date_created] ,src.[date_modified] ,src.[version_number] ,1); insert into [-].[msdb].[dbo].[sysschedules]([schedule_uid] ,[originating_server_id] ,[name] ,[owner_sid] ,[enabled] ,[freq_type] ,[freq_interval] ,[freq_subday_type] ,[freq_subday_interval] ,[freq_relative_interval] ,[freq_recurrence_factor] ,[active_start_date] ,[active_end_date] ,[active_start_time] ,[active_end_time] ,[date_created] ,[date_modified] ,[version_number]) select [schedule_uid] ,[originating_server_id] ,[name] ,[owner_sid] ,[enabled] ,[freq_type] ,[freq_interval] ,[freq_subday_type] ,[freq_subday_interval] ,[freq_relative_interval] ,[freq_recurrence_factor] ,[active_start_date] ,[active_end_date] ,[active_start_time] ,[active_end_time] ,[date_created] ,[date_modified] ,[version_number] from #tbl_sysschedules where IsAdd=1; drop table #tbl_sysschedules;
      
      





最初に、テーブル#tbl_sysschedulesの受信サーバーで利用可能なすべてのスケジュールを収集します。 次に、MERGE命令を使用して、[schedule_uid]フィールドに沿って、アルゴリズムの項目1の#tbl_notentityテーブルにないソースサーバーからのすべての欠落スケジュールをこのテーブルにマージします。 挿入された行は、IsAdd列で1としてマークされます。 さらに、すべてのスケジュールをテーブル[msdb] [Dbo]に追加します。[Dbo]。条件IsAdd = 1に従って、テーブル#tbl_sysschedulesからの受信サーバーの[Sysschedules]。 次に、テーブル#tbl_sysschedulesを削除します。さらにそれはもう必要ありません。



したがって、すべてのスケジュールは、アルゴリズムの項目1のテーブル#tbl_notentityにない宛先サーバーに転送されました。



5)転送されたタスクのスケジュールタスクリンクを転送します。



リクエスト
 select js.*, ss.[schedule_uid], 0 as IsAdd into #tbl_jobschedules from [-].[msdb].[dbo].[sysjobschedules] as js inner join [-].[msdb].[dbo].[sysschedules] as ss on js.[schedule_id]=ss.[schedule_id]; ;with src as ( select js.[job_id] ,js.[next_run_date] ,js.[next_run_time] ,ss.[schedule_uid] ,serv.[schedule_id] from [msdb].[dbo].[sysjobschedules] as js inner join [msdb].[dbo].[sysschedules] as ss on js.[schedule_id]=ss.[schedule_id] inner join [-].[msdb].[dbo].[sysschedules] as serv on serv.[schedule_uid]=ss.[schedule_uid] where not exists ( select top(1) 1 from #tbl_notentity as t where t.[schedule_uid]=ss.[schedule_uid] ) ) merge #tbl_jobschedules as trg using src on trg.[job_id]=src.[job_id] and trg.[schedule_uid]=src.[schedule_uid] when not matched by target then INSERT ([schedule_id] ,[schedule_uid] ,[job_id] ,[next_run_date] ,[next_run_time] ,[IsAdd]) VALUES (src.[schedule_id] ,src.[schedule_uid] ,src.[job_id] ,src.[next_run_date] ,src.[next_run_time] ,1); insert into [-].[msdb].[dbo].[sysjobschedules]([schedule_id] ,[job_id] ) select [schedule_id] ,[job_id] from #tbl_jobschedules where IsAdd=1; drop table #tbl_jobschedules;
      
      





最初に、テーブル#tbl_jobschedulesの宛先サーバーで利用可能なすべてのスケジュールとジョブの関係を収集します。 次に、MERGE命令を使用して、[job_id]フィールドと[schedule_uid]フィールドを、アルゴリズムのセクション1の#tbl_notentityテーブルにないソースサーバーからのすべての欠落リンクをこのテーブルにマージします。 挿入された行は、IsAdd列で1としてマークされます。 さらに、すべてのスケジュールをテーブル[msdb] [Dbo]に追加します。[Dbo]。条件IsAdd = 1に従って、テーブル#tbl_jobschedulesから受信サーバーの[Sysjobschedules]を追加します。 次に、テーブル#tbl_jobschedulesを削除します。さらに必要なくなりました。



したがって、すべてのスケジュール-タスクバンドルは、アルゴリズムの項目1のテーブル#tbl_notentityにない宛先サーバーに転送されました。



6)移行されたジョブのターゲットサーバーを転送する



リクエスト
 select *, 0 as IsAdd into #tbl_sysjobservers from [-].[msdb].[dbo].[sysjobservers]; ;with src as ( select * from [msdb].[dbo].[sysjobservers] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[job_id]=src.[job_id] ) ) merge #tbl_sysjobservers as trg using src on trg.[job_id]=src.[job_id] and trg.[server_id]=src.[server_id] when not matched by target then INSERT ([job_id] ,[server_id] ,[last_run_outcome] ,[last_outcome_message] ,[last_run_date] ,[last_run_time] ,[last_run_duration] ,[IsAdd]) VALUES (src.[job_id] ,src.[server_id] ,src.[last_run_outcome] ,src.[last_outcome_message] ,src.[last_run_date] ,src.[last_run_time] ,src.[last_run_duration] ,1); insert into [-].[msdb].[dbo].[sysjobservers]([job_id] ,[server_id] ,[last_run_outcome] ,[last_outcome_message] ,[last_run_date] ,[last_run_time] ,[last_run_duration]) select [job_id] ,[server_id] ,[last_run_outcome] ,[last_outcome_message] ,[last_run_date] ,[last_run_time] ,[last_run_duration] from #tbl_sysjobservers where IsAdd=1; drop table #tbl_sysjobservers; drop table #tbl_notentity;
      
      





最初に、テーブル#tbl_sysjobserversの受信サーバーで利用可能なすべてのジョブターゲットサーバー接続を収集します。 次に、MERGE命令を使用して、[job_id]フィールドと[server_id]フィールドを、アルゴリズムのセクション1の#tbl_notentityテーブルにないソースサーバーからのすべてのリンクをこのテーブルにマージします。 挿入された行は、IsAdd列で1としてマークされます。 そして、すべてのリンクを[msdb]。[Dbo]。[Sysjobservers]受信者サーバーに追加します。#tbl_sysjobserversテーブルからIsAdd = 1の条件下で。 次に、テーブル#tbl_sysjobserversと#tbl_notentityを削除します。さらに、それらはもう必要ありません。



したがって、すべてのタスクターゲットサーバーバインディングは、アルゴリズムの項目1の#tbl_notentityテーブルにない宛先サーバーに転送されました。



タスクにローカルサーバー以外のターゲットサーバーが含まれている場合(つまり、識別子がゼロに等しくない場合)、まずこれらのターゲットサーバー自体の定義を転送してから、アルゴリズムのステップ6を作成する必要があることに注意することが重要です。



7)タスクを登録してスケジュールをアクティブにし、これらのタスクを非アクティブモードに移行します(タスクをオフにすることにより)



そして



8)転送されたすべてのタスクの所有者を割り当てます(たとえば、sa)



リクエスト
 declare @job_id uniqueidentifier; --    sa update sj set sj.[owner_sid]=0x01 from #tbl_jobs as t inner join [-].[msdb].[dbo].[sysjobs] as sj on t.[job_id]=sj.[job_id] where [IsAdd]=1; while(exists(select top(1) 1 from #tbl_jobs where [IsAdd]=1)) begin select top(1) @job_id=[job_id] from #tbl_jobs where [IsAdd]=1; EXEC [-].[msdb].[dbo].sp_update_job @job_id=@job_id, @enabled=0 delete from #tbl_jobs where [job_id]=@job_id; end drop table #tbl_jobs;
      
      





最初に、所有者saを転送されたすべてのタスクに割り当てます(テーブル#tbl_jobsから転送されたタスクを定義します)。 次に、転送された各タスクを登録し、転送先のサーバーでシステムストアドプロシージャ[msdb]。[Dbo] .sp_update_jobを呼び出して、転送されたタスクをオフにしてスケジュールをアクティブ化します。 次に、テーブル#tbl_jobsが不要になったため削除します。



したがって、sa所有者は転送されたすべてのタスクに割り当てられ、これらのタスクはすべて、それらをオフにすることで登録されました(そして、スケジュールがアクティブになりました)。

次に、必要なタスクをスクリプトまたは手動で有効にする必要があります。



スクリプト全体のコードは次のとおりです。



リクエスト
 --  ,     select ss.[schedule_uid] ,js.[job_id] into #tbl_notentity from [msdb].[dbo].[sysjobschedules] as js inner join [msdb].[dbo].[sysschedules] as ss on js.[schedule_id]=ss.[schedule_id] where [job_id] in ( < GUID-  ,    > ) --  select *, 0 as IsAdd into #tbl_jobs from [-].[msdb].[dbo].[sysjobs]; ;with src as ( select * from [msdb].[dbo].[sysjobs] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[job_id]=src.[job_id] ) ) merge #tbl_jobs as trg using src on trg.[job_id]=src.[job_id] when not matched by target then INSERT ([job_id] ,[originating_server_id] ,[name] ,[enabled] ,[description] ,[start_step_id] ,[category_id] ,[owner_sid] ,[notify_level_eventlog] ,[notify_level_email] ,[notify_level_netsend] ,[notify_level_page] ,[notify_email_operator_id] ,[notify_netsend_operator_id] ,[notify_page_operator_id] ,[delete_level] ,[date_created] ,[date_modified] ,[version_number] ,[IsAdd]) VALUES (src.[job_id] ,src.[originating_server_id] ,src.[name] ,src.[enabled] ,src.[description] ,src.[start_step_id] ,src.[category_id] ,src.[owner_sid] ,src.[notify_level_eventlog] ,src.[notify_level_email] ,src.[notify_level_netsend] ,src.[notify_level_page] ,src.[notify_email_operator_id] ,src.[notify_netsend_operator_id] ,src.[notify_page_operator_id] ,src.[delete_level] ,src.[date_created] ,src.[date_modified] ,src.[version_number] ,1); insert into [-].[msdb].[dbo].[sysjobs]([job_id] ,[originating_server_id] ,[name] ,[enabled] ,[description] ,[start_step_id] ,[category_id] ,[owner_sid] ,[notify_level_eventlog] ,[notify_level_email] ,[notify_level_netsend] ,[notify_level_page] ,[notify_email_operator_id] ,[notify_netsend_operator_id] ,[notify_page_operator_id] ,[delete_level] ,[date_created] ,[date_modified] ,[version_number]) select [job_id] ,[originating_server_id] ,[name] ,[enabled] ,[description] ,[start_step_id] ,[category_id] ,[owner_sid] ,[notify_level_eventlog] ,[notify_level_email] ,[notify_level_netsend] ,[notify_level_page] ,[notify_email_operator_id] ,[notify_netsend_operator_id] ,[notify_page_operator_id] ,[delete_level] ,[date_created] ,[date_modified] ,[version_number] from #tbl_jobs where IsAdd=1; --drop table #tbl_jobs; --   select *, 0 as IsAdd into #tbl_jobsteps from [-].[msdb].[dbo].[sysjobsteps]; ;with src as ( select * from [msdb].[dbo].[sysjobsteps] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[job_id]=src.[job_id] ) ) merge #tbl_jobsteps as trg using src on trg.[job_id]=src.[job_id] and trg.[step_id]=src.[step_id] when not matched by target then INSERT ([job_id] ,[step_id] ,[step_name] ,[subsystem] ,[command] ,[flags] ,[additional_parameters] ,[cmdexec_success_code] ,[on_success_action] ,[on_success_step_id] ,[on_fail_action] ,[on_fail_step_id] ,[server] ,[database_name] ,[database_user_name] ,[retry_attempts] ,[retry_interval] ,[os_run_priority] ,[output_file_name] ,[last_run_outcome] ,[last_run_duration] ,[last_run_retries] ,[last_run_date] ,[last_run_time] ,[proxy_id] ,[step_uid] ,[IsAdd]) VALUES (src.[job_id] ,src.[step_id] ,src.[step_name] ,src.[subsystem] ,src.[command] ,src.[flags] ,src.[additional_parameters] ,src.[cmdexec_success_code] ,src.[on_success_action] ,src.[on_success_step_id] ,src.[on_fail_action] ,src.[on_fail_step_id] ,src.[server] ,src.[database_name] ,src.[database_user_name] ,src.[retry_attempts] ,src.[retry_interval] ,src.[os_run_priority] ,src.[output_file_name] ,src.[last_run_outcome] ,src.[last_run_duration] ,src.[last_run_retries] ,src.[last_run_date] ,src.[last_run_time] ,src.[proxy_id] ,src.[step_uid] ,1); insert into [-].[msdb].[dbo].[sysjobsteps]([job_id] ,[step_id] ,[step_name] ,[subsystem] ,[command] ,[flags] ,[additional_parameters] ,[cmdexec_success_code] ,[on_success_action] ,[on_success_step_id] ,[on_fail_action] ,[on_fail_step_id] ,[server] ,[database_name] ,[database_user_name] ,[retry_attempts] ,[retry_interval] ,[os_run_priority] ,[output_file_name] ,[last_run_outcome] ,[last_run_duration] ,[last_run_retries] ,[last_run_date] ,[last_run_time] ,[proxy_id] ,[step_uid]) select [job_id] ,[step_id] ,[step_name] ,[subsystem] ,[command] ,[flags] ,[additional_parameters] ,[cmdexec_success_code] ,[on_success_action] ,[on_success_step_id] ,[on_fail_action] ,[on_fail_step_id] ,[server] ,[database_name] ,[database_user_name] ,[retry_attempts] ,[retry_interval] ,[os_run_priority] ,[output_file_name] ,[last_run_outcome] ,[last_run_duration] ,[last_run_retries] ,[last_run_date] ,[last_run_time] ,[proxy_id] ,[step_uid] from #tbl_jobsteps where IsAdd=1; drop table #tbl_jobsteps; --   select *, 0 as IsAdd into #tbl_sysschedules from [-].[msdb].[dbo].[sysschedules]; ;with src as ( select * from [msdb].[dbo].[sysschedules] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[schedule_uid]=src.[schedule_uid] ) ) merge #tbl_sysschedules as trg using src on trg.[schedule_uid]=src.[schedule_uid] when not matched by target then INSERT ([schedule_id] ,[schedule_uid] ,[originating_server_id] ,[name] ,[owner_sid] ,[enabled] ,[freq_type] ,[freq_interval] ,[freq_subday_type] ,[freq_subday_interval] ,[freq_relative_interval] ,[freq_recurrence_factor] ,[active_start_date] ,[active_end_date] ,[active_start_time] ,[active_end_time] ,[date_created] ,[date_modified] ,[version_number] ,[IsAdd]) VALUES (src.[schedule_id] ,src.[schedule_uid] ,src.[originating_server_id] ,src.[name] ,src.[owner_sid] ,src.[enabled] ,src.[freq_type] ,src.[freq_interval] ,src.[freq_subday_type] ,src.[freq_subday_interval] ,src.[freq_relative_interval] ,src.[freq_recurrence_factor] ,src.[active_start_date] ,src.[active_end_date] ,src.[active_start_time] ,src.[active_end_time] ,src.[date_created] ,src.[date_modified] ,src.[version_number] ,1); insert into [-].[msdb].[dbo].[sysschedules]([schedule_uid] ,[originating_server_id] ,[name] ,[owner_sid] ,[enabled] ,[freq_type] ,[freq_interval] ,[freq_subday_type] ,[freq_subday_interval] ,[freq_relative_interval] ,[freq_recurrence_factor] ,[active_start_date] ,[active_end_date] ,[active_start_time] ,[active_end_time] ,[date_created] ,[date_modified] ,[version_number]) select [schedule_uid] ,[originating_server_id] ,[name] ,[owner_sid] ,[enabled] ,[freq_type] ,[freq_interval] ,[freq_subday_type] ,[freq_subday_interval] ,[freq_relative_interval] ,[freq_recurrence_factor] ,[active_start_date] ,[active_end_date] ,[active_start_time] ,[active_end_time] ,[date_created] ,[date_modified] ,[version_number] from #tbl_sysschedules where IsAdd=1; drop table #tbl_sysschedules; --       select js.*, ss.[schedule_uid], 0 as IsAdd into #tbl_jobschedules from [-].[msdb].[dbo].[sysjobschedules] as js inner join [-].[msdb].[dbo].[sysschedules] as ss on js.[schedule_id]=ss.[schedule_id]; ;with src as ( select js.[job_id] ,js.[next_run_date] ,js.[next_run_time] ,ss.[schedule_uid] ,serv.[schedule_id] from [msdb].[dbo].[sysjobschedules] as js inner join [msdb].[dbo].[sysschedules] as ss on js.[schedule_id]=ss.[schedule_id] inner join [-].[msdb].[dbo].[sysschedules] as serv on serv.[schedule_uid]=ss.[schedule_uid] where not exists ( select top(1) 1 from #tbl_notentity as t where t.[schedule_uid]=ss.[schedule_uid] ) ) merge #tbl_jobschedules as trg using src on trg.[job_id]=src.[job_id] and trg.[schedule_uid]=src.[schedule_uid] when not matched by target then INSERT ([schedule_id] ,[schedule_uid] ,[job_id] ,[next_run_date] ,[next_run_time] ,[IsAdd]) VALUES (src.[schedule_id] ,src.[schedule_uid] ,src.[job_id] ,src.[next_run_date] ,src.[next_run_time] ,1); insert into [-].[msdb].[dbo].[sysjobschedules]([schedule_id] ,[job_id] ) select [schedule_id] ,[job_id] from #tbl_jobschedules where IsAdd=1; drop table #tbl_jobschedules; --   select *, 0 as IsAdd into #tbl_sysjobservers from [-].[msdb].[dbo].[sysjobservers]; ;with src as ( select * from [msdb].[dbo].[sysjobservers] as src where not exists ( select top(1) 1 from #tbl_notentity as t where t.[job_id]=src.[job_id] ) ) merge #tbl_sysjobservers as trg using src on trg.[job_id]=src.[job_id] and trg.[server_id]=src.[server_id] when not matched by target then INSERT ([job_id] ,[server_id] ,[last_run_outcome] ,[last_outcome_message] ,[last_run_date] ,[last_run_time] ,[last_run_duration] ,[IsAdd]) VALUES (src.[job_id] ,src.[server_id] ,src.[last_run_outcome] ,src.[last_outcome_message] ,src.[last_run_date] ,src.[last_run_time] ,src.[last_run_duration] ,1); insert into [-].[msdb].[dbo].[sysjobservers]([job_id] ,[server_id] ,[last_run_outcome] ,[last_outcome_message] ,[last_run_date] ,[last_run_time] ,[last_run_duration]) select [job_id] ,[server_id] ,[last_run_outcome] ,[last_outcome_message] ,[last_run_date] ,[last_run_time] ,[last_run_duration] from #tbl_sysjobservers where IsAdd=1; drop table #tbl_sysjobservers; drop table #tbl_notentity; --     ,       ( ) declare @job_id uniqueidentifier; --    sa update sj set sj.[owner_sid]=0x01 from #tbl_jobs as t inner join [-].[msdb].[dbo].[sysjobs] as sj on t.[job_id]=sj.[job_id] where [IsAdd]=1; while(exists(select top(1) 1 from #tbl_jobs where [IsAdd]=1)) begin select top(1) @job_id=[job_id] from #tbl_jobs where [IsAdd]=1; EXEC [-].[msdb].[dbo].sp_update_job @job_id=@job_id, @enabled=0 delete from #tbl_jobs where [job_id]=@job_id; end drop table #tbl_jobs;
      
      





結果



この記事では、MS SQL Serverの1つのインスタンスから別のインスタンスにエージェントのタスクとスケジュールを転送できるT-SQLスクリプトの実装例を検討しました。 また、このアプローチは他の手段を使用して実装できます。 たとえば、PowerShellまたはC#。



ソース:



» Msdb

» SQL Serverエージェントテーブル

Sp_update_job



All Articles