[MSSQL] SQL Server Agent 排程自動化更新不同 Server 上的資料表

串接 Stored Procedure 、不同 Server 的資料匯出匯入的步驟,產生 SSIS 封裝。依 Stored Procedure 執行結果的回傳值,決定是否執行資料匯入匯出的步驟。

Shan
C.Shan
10 min readMay 3, 2021

--

前言

近期工作遇到的需求是每個月須將測試機的資料,同步至正式機資料庫。簡化實際流程,在這篇文章單純分享: 如何透過 Stored Procedure (簡稱 SP) 的執行結果回傳值,決定是否進行資料匯入匯出的步驟。若 SP 回傳特定值或 前一部執行失敗,會寄發信件通知。流程如下:

排程流程

工具

步驟

1. Create a stored procedure in SQL Server

首先,先簡單建一個有參數回傳的 SP。

2. Create SQL Server connections in SSIS

在 Visual Studio 裡,建一個專案 (請回顧參考文章),由於會使用到 2 個不同 Server 上的資料庫,所以先建立其連接管理員

實作上,連接 SP 我是用 ADO.NET 類型的連線;匯出匯入則是使用 OLE DB 類型的連線。不同類型的連接管理員,會影響到參數設定,詳細可以參考這篇

連接管理員

3. Set a parameter in SSIS

TestSP 有 result 及 message 的參數回傳,在這次的實作中,需要在專案中,點右鍵選擇變數。接著新增 result 及 message ,並設定其型別與初始值。

這裡 result 參數的用途,與 pipeline 的邏輯判斷相關;message 參數,則是會用於寄發通知信的內容,也就是說信件的內文,是來自於 SP 的回傳參數。讓我們繼續看下去 …

設定變數

4. Create a execute SQL task in SSIS

先建 執行 SQL 工作 (execute SQL task)

執行 SQL 工作編輯器
參數對應

這裡的變數名稱 User::result 、 User::message 是上個步驟所設定的變數。假如上一步沒有設定好變數,這裡抓取對應的變數名稱可能會出現錯誤:

0xC0010001 The variable cannot be found

這種情況,是我把上一步設定的 result 變數刪除,模擬在執行 SQL 工作中,有用到 User::result 參數。但在專案裡,沒有設定對應的變數時,會顯示此錯誤。

執行 SQL 工作設定好之後,對其點右鍵,選執行工作,可以測試 TestSP 是否能執行成功。我必須說, VS2019 真的很方便!一開始,我並沒有看到這個功能鍵。假如沒有用 Integration Services Project 專案開啟封裝檔,並不會顯示這項功能,也因此踩很多雷。

點選執行工作

執行成功後,在元件上,會顯示綠色勾。反之失敗,會顯示紅色叉,此時請看輸出視窗的訊息。

執行成功

什麼情況是沒有用 Integration Services Project 專案開啟封裝檔?

我一開始是透過 SQL Server 匯出和匯入精靈產生 .dtsx 封裝檔,並非用 VS2019 Integration Services Project 專案建立一個封裝檔。只差這個步驟,少了執行工作功能鍵遇到問題就很難 debug ,讓我踩很多坑,撞很多牆。

SQL Server 匯出和匯入精靈
VS2019 建立 Integration Services Project 專案

5. Create a data flow task in SSIS

接續建資料流程工作 (data flow task),也就是匯出匯入的步驟。

資料流程的地方,會需要設定匯出的來源及匯入的目的地。

請設定來源端的資料庫與資料表。

OLE DB 來源編輯器

請設定目的地端的資料庫與資料表。

OLE DB 目的地編輯器

接著可以按下執行工作,實際測試結果是否成功。

6. Create a script task for email sending in SSIS

請參閱 [MSSQL] SSIS 透過指令碼工作寄發信件

7. Design the pipeline with the parameter

完成執行 SQL 工作、資料流程工作以及指令碼工作的元件設定,可以發現滑鼠移到元件上的時候,底下會出現綠色箭頭。拖曳箭頭,會出現延伸虛線。這個虛線碰到另一元件,可以將兩個元件關聯起來。

延伸虛線

雙點擊綠色連接線,會出現優先順序條件約束編輯器,如下圖。假設箭頭是由執行 TestSP,指向同步線上資料庫。在條件約束選項中,如圖設定,當 TestSP 元件執行成功,才會接著執行同步線上資料庫元件;反之 TestSP 元件執行失敗,就不會接著執行同步線上資料庫元件。

優先順序條件約束編輯器
設定條件約束

另外,在優先順序條件約束編輯器裡,運算式也存取變數,作為條件約束,如下圖。當箭頭起點的元件執行成功 AND result 為 2,則繼續執行箭頭指向的元件。

優先順序條件約束編輯器

當箭頭起點的元件執行失敗 OR result 不為 2,則繼續執行箭頭指向的元件。

優先順序條件約束編輯器

待所有流程都設定好後,可以按下開始/執行封裝,確認流程是否正常。

開始/執行封裝

8. Create a SQL task on SQL Server Agent

參照使用 Sql Agent 排程執行 Stored Procedure,在 SQL Server Agent 裡,建立新的作業。同時在作業步驟屬性裡,封裝的地方,選擇對應的 .dtsx 封裝檔。

作業步驟屬性,設定封裝檔

排程會依設定時間,執行封裝檔。另外,在檢視紀錄的地方,可以看到作業是否成功或失敗的原因。

檢視紀錄
紀錄檔摘要

心得

其實一開始聽到要定時同步資料,很自然想到用 C# 寫一個主控台應用程式。直到實作的時候,透過程式碼呼叫 SP 取得回傳值是可以的,但在匯出匯入的步驟卡關。難點在於:

  1. 匯出匯入資料量龐大,如單純用程式碼存取資料庫,記憶體可能會超載,排程執行的時間也可能會超過 1 小時
  2. 透過 SQL 匯出精靈產出的 SSIS 封裝檔,在主控台應用程式裡,查無適用的 dll 套件執行封裝檔

以上難點,外加我希望可以用一支服務完成需求。向前輩求救後,他給我幾個方向,一是給我 [VS]使用 Visual Studio 2019 開發商業智慧方案 這篇文章 (出現第三次!!!),再來叫我打開透過 SQL 匯出精靈產出 SSIS 的封裝檔。然後是我發現新大陸了,在那!我看到新大陸!

接著花了三天的時間,摸索怎麼把 SP 與匯出匯入的步驟串接在一起。troubleshooting 非常多次,一撞再撞,那道牆終於破了!我決定用這篇文章,紀錄破牆而出的過程 (?)。

參考

系列文

--

--

Shan
C.Shan

過去學習機械理論,現在撰寫網頁程式。我喜歡唱歌,喜歡畫畫,喜歡旅遊,存在藝術的感性,也兼具工程師的理性。腦容量87%,未來期望用文字、影像紀錄經歷。