執行多個遠端作業
我需要從 sql server 2005 實例(本地伺服器)在 150 多個 sql server 實例(sql server 2000,遠端)上手動執行作業。所有這些實例的工作都是相同的。該作業只是呼叫一個不帶參數的儲存過程,這在所有實例中也是相同的。這些工作按計劃進行。但現在他們希望我根據要求手動執行所有實例或指定實例的作業。
對此的最佳做法是什麼?我試過用 openrowset 來呼叫遠端儲存過程。但是每次執行作業都需要幾分鐘,所以如果我使用循環來執行所有這些作業,它將一個接一個地執行,而且時間很長。理想情況下,它應該能夠在每個實例上執行儲存過程,而無需等待它完成。更理想的是,它應該能夠在每個實例上執行作業而無需等待它完成,因此它可以在每個實例的作業歷史記錄中留下記錄。
並且儲存過程來自第三方,因此無法更改。
更新:
由於“人們”要求從 SSRS 報告中對其進行初始化,因此使用 SSRS 在伺服器上呼叫一些 T-SQL/proc 是最合適的。我現在遇到的問題是,當使用 OPENQUERY 或 OPENROWSET 從本地伺服器呼叫遠端 SQL Server 2000 實例上的 msdb.dbo.sp_start_job 時,我得到了無法跟隨錯誤。
處理對象“exec msdb.dbo.sp_start_job @job_name = ‘xxx’”。連結伺服器“xxx”的 OLE DB 提供程序“SQLNCLI”表示該對像沒有列,或者目前使用者對該對像沒有權限。
我想這可能是因為 sp_start_job 沒有返回任何內容,因為我可以使用 OPENQUERY/OPENROWSET 毫無問題地呼叫其他遠端過程。那麼有什麼解決方法嗎?
更新:
我發現它在 t-sql 中實際上非常簡單。
執行
$$ linkedServerName $$.msdb.dbo.sp_start_job @job_name = ’test2’ 所以我不需要使用 OPENROWSET/OPENQUERY,因為所有遠端 SQL Server 2000 實例都已添加為遠端伺服器。
我想說最簡單的方法是通過 PowerShell 和 SMO。以下面的程式碼為例:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null $SqlServerNames = "Server1", "Server2" $SqlJobName = "YourJob" foreach ($SqlServerName in $SqlServerNames) { $SqlServer = New-Object Microsoft.SqlServer.Management.Smo.Server($SqlServerName) $SqlServer.JobServer.Jobs[$SqlJobName].Start() }
所有這一切都會遍歷伺服器列表(明確表示為字元串數組變數,但也可以很容易地從 SQL Server 數據庫表、文本文件等中獲取),連接到目前伺服器,然後啟動作業名稱為您將
$SqlJobName
變數設置為的任何作業。還值得注意的是,該
Start()
函式在繼續執行程式碼之前不會等待作業完成。如您所見,只需幾行 PowerShell 程式碼即可完成此任務。但我會更進一步,例如錯誤處理。您不希望它爆炸並且不知道發生了什麼故障、何時發生故障以及它在哪些伺服器上執行/未執行。
foreach ($SqlServerName in $SqlServerNames) { try { $SqlServer = New-Object Microsoft.SqlServer.Management.Smo.Server($SqlServerName) $SqlServer.JobServer.Jobs[$SqlJobName].Start() } catch { # add your error handling code here ## for instance, write the error to a text file } }
並且,與任何程式碼一樣,在非生產環境中對其進行測試,以確保它執行您認為會和應該執行的操作。根據您的需求/環境重新工作。
根據 RoKa 的評論:
是否可以對其進行編輯以檢查作業目前是否正在執行、錯誤處理?
好點子,絕對是要檢查的東西(以及通過檢查非空值是否確實存在作業):
foreach ($SqlServerName in $SqlServerNames) { try { $SqlServer = New-Object Microsoft.SqlServer.Management.Smo.Server($SqlServerName) $SqlJob = $SqlServer.JobServer.Jobs[$SqlJobName] if (($SqlJob) -and ($SqlJob.CurrentRunStatus -eq [Microsoft.SqlServer.Management.Smo.Agent.JobExecutionStatus]::Idle)) { $SqlJob.Start() } else { # handle/log accordingly if the job doesn't exist or it's not idle } } catch { # add your error handling code here ## for instance, write the error to a text file } }
編輯:在重新閱讀您的問題時,我看到了 SQL Server 2000。那些將成為目標實例嗎?如果是這種情況,並且您確實決定使用我提供的 PowerShell/SMO 答案,那麼絕對可以肯定地進行測試並確保它會按照您的意願行事。在遠離生產環境的地方進行測試,並 100% 確定它會按照您的想法進行。
編輯:看起來 SQL Server 2012 之前的 SMO 版本(即 2005、2008 和 2008 R2)支持管理 SQL Server 2000 實例。我正在通過此 BOL 參考找到此資訊。
Agent Master Job 是否適合您?看看這個: