Sql-Server-2008-R2
包級別的 SSIS 事件處理程序
我有一個相當簡單的 SSIS 包(少數執行任務和一些數據流任務)。我希望得到的最終結果:
- 當包裹中的任何地方發生錯誤時,我想通過電子郵件收到通知
- 我希望該電子郵件包括:包名稱、失敗的任務和錯誤資訊。
據我了解,我通過以下方式進行了設置:
- 為包級別創建一個事件處理
OnError
程序(Excutable 設置為包名稱)。- 配置 SMTP 連接並添加到發送郵件任務中
Subject
在該任務中,我為and配置了一個表達式MessageSource
。這兩個表達式如下所示。表達式:
主題 -
"Error occurred on " + @[System::PackageName]
消息源 - (添加換行符以提高可讀性)
(DT_WSTR,250)("An error occurred in execution of the package: " + @[System::PackageName] + "\n" + "The task that experienced the error: " + @[System::TaskName] + "\n" + "The error information returned:\n" + "Error Code: " + (DT_WSTR,50)(@[System::ErrorCode]) + "\n" + "Error Description: " + @[System::ErrorDescription])
現在我強制出錯後發生了什麼:
- 任務按預期失敗,但事件處理程序也失敗了。
OnError
事件已觸發,但與預期不同。第一個問題是截斷,收到錯誤A truncation occurred during evaluation of the expression
。這是收到的電子郵件的內容,我沒有看到預期的新行:An error occurred in execution of the package: The task that experienced the error: Failure notification The error information returned: Error Code: 0 Error Description:
- 同一 OnError 的第二個錯誤:
property "MessageSource" cannot be evaluated. Modify the expression to be valid.
- 任務失敗時,我收到了兩封電子郵件。
環境資訊:SQL Server 2008 R2,此時僅通過 BIDS 執行包。
問題:
- 我的表達有什麼問題
MessageSource
?我顯然可以在屬性視窗中成功評估表達式,並且理解這是因為沒有填充變數。那麼如何配置它不會被截斷,無論傳入什麼錯誤,只需將其設置為一些較大的數字長度?- 我不是在尋找一些自定義方法或程式碼來執行此操作,因為該程序包相當簡單,並且只在每個藍月亮執行。但是,最好
OnError
為每個任務簡單地創建一個事件嗎?據我了解,任何失敗的子任務都會將錯誤資訊傳遞給父包,所以它應該可以正常工作嗎?
2012 年之前,表達式限制為 4k。這不是變數的限制,您可以將愚蠢的長值分配給變數,只是不能用表達式來完成。使用腳本任務對您的變數進行連接和分配,看看是否沒有清除 #1
你可能會遇到的事情,我從來沒有找到一個令人滿意的解決方案,是消息的雙重發射。我知道,他們說設置傳播為 false 以及所有這些,但我似乎從來沒有按照我的意願讓它工作。在我們的世界中,如果出現錯誤,包將失敗,因此 OnTaskFailed 事件對於僅獲取一次信號更有用,但您的里程數會有所不同。
我們在另一項工作中使用的一種更好的方法是讓程序每 N 分鐘掃描一次 sys.ssiserrorlog 表以查找故障。由於所有包都記錄到它,因此對我們來說這是一種更清潔、更可重用的方法。
我見過人們提到總是從父包的上下文中執行包以遵守 DRY(不要重複自己)原則,因此父包有錯誤通知等內置於其中。
最後一點要注意,不要完全依賴 SSIS 的錯誤處理。我們的部署進展順利,至少我們是這麼認為的。但是,當程序包被觸發時,它無法驗證,因為表的元數據與數據流的預期不匹配。驗證失敗的包就像語法錯誤,因此 OnError/OnTaskFailed 事件甚至沒有機會觸發並告訴我們我們處於糟糕的狀態。我們在不知不覺中走了幾天。哎呀