有時候不僅僅需要在內部執行package包,多數情況下,是需要在外部進行調用,比如,需要一個批處理或者控制臺程序進行外部調用SSIS包,而往往這個包所配置的連接字符串是經過加密處理的,所以當外部調用SSIS包的時候,一方面需要給包賦值連接字符串,一方面傳遞其他參數,其實給包賦值就是往包里傳遞參數。
當遇到問題在網上進行查找解決方案的時候,有時候答案很零碎,或者只是部分代碼,淺藏輒止,而有的處理方法都是很老的版本所用到的,所以這很雞肋。當我寫隨筆時,總是反復修改,親力親為,確保完整代碼,確保測試通過。雖然很基礎,甚至沒必要,權當自己是學習記錄
1. 先用VS2015建立一個最簡單的SSIS包,設置一個包變量StrPram,初始值為VInitial,里面放入一個腳本組件,設置一個可寫變量,選中之前設置的包變量StrPram,然后編輯腳本,讓其彈出傳進來的變量值
如上圖,直接在VS2015上測試是沒有問題的,那么如果要在控制臺調用這個包,針對SQL2014,需要引用 Microsoft.SQLServer.ManagedDTS.dll 組件,默認路徑為:
C:\Program Files (x86)\Microsoft SQL Server\120\SDK\Assemblies\Microsoft.SQLServer.ManagedDTS.dll
引用之后,再添加命名空間 using Microsoft.SqlServer.Dts.Runtime;
2.新建控制臺項目的代碼如下:
public static void RaadSSDT() { Console.WriteLine("Start a read task for dts..."); Application app = new Application(); try { string Path = @"D:\ZF\TESTpage\ISpro1\ISpro1\Package.dtsx"; //加載包 Package package = app.LoadPackage(Path, null); //獲取包結果 DTSExecResult result = package.Execute(); //判斷包執行結果 if (result.Equals(DTSExecResult.Success)) { Console.WriteLine("Excute dts is success..."); } else { Console.WriteLine("Excute dts is Failure..." + System.DateTime.Now.ToString()); } Console.ReadLine(); } catch (Exception ex) { throw new Exception(ex.Message); } }
網上很多資料寫的都是引用DTSRuntimeWrap.dll 組件,加載包用的也是
DtsRunTime.IDTSPackage90 package = app.LoadPackage(Path, true, null);
我想說的是 這是針對SQL2005的版本配置的方案,社會是向前發展的,再過兩天就是2017年,如今這些老舊的解決方案不能再幫助我們解決問題,只能是了解知識,在查找解決方案時,一定要關注版本,以免造成不必要的麻煩。
3.驗證
程序的調試離不開狀態的分析,當我在VS的設計模式運行包的時候,是沒有問題的,但是我在控制臺調用包的時候,返回結果result一直都是Failure,這就尷尬了,折騰了我一整天都沒有搞明白,后來我又在SQL 集成服務中進行封裝跑包驗證,同樣也是成功,沒有問題,但是為何C#調用時失敗,后來我寫了一個foreach,輸出失敗信息
if (result.Equals(DTSExecResult.Failure)) { foreach (DtsError dtserr in pack.Errors) { Console.WriteLine(dtserr.Description); } } else { Console.WriteLine("Sussess"); } Console.ReadKey();
運行的時候控制臺提示如下:The JavaScript Task is Currupted... ,說是腳本組件損壞,VS2015設計模式跑包和SQL2014集成服務執行包是沒有問題的,我又添加了一個Excute SQL Task組件,結果控制臺輸出的Description 為:
最后繞了一大圈,終于證明問題還是出在控制臺項目的版本上面,然后搜索錯誤代碼,找到了這位園友的隨筆 http://www.cnblogs.com/yujwshx/p/4519916.html,雖然只有寥寥數語,卻指明了是因為 引用了SQL的命名空間,造成版本不一致,需要在控制臺項目的配置文件中 設置屬性 useLegacyV2RuntimeActivationPolicy 為 true:
<?xml version="1.0" encoding="utf-8"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/> </startup> </configuration>
然后,啟動控制臺項目,果然在控制臺得到:Success ,再一次證明了對程序本身而言,版本的重要性。
4. 多數情況下不僅僅是調用SSIS包,還要往里面傳值,或者從包里讀取值,只要針對Variables["參數"]進行操作就好,前提是,這些參數在包中是設置好的,否則,系統會提示獲取失敗,找不到參數.所以在真正使用的時候,習慣上還是要進行一下判斷(PS:當包加載成功,即可對其進行參數值的交互,即使最終的Result結果為:Failure)
string iba = package.Variables["StrParam"].Value.ToString(); //VInitial 初始值 // 給package中的變量進行賦值 package.Variables["StrParam"].Value = "Sientuo"; // 讀取package中的變量值 string ibb = package.Variables["StrParam"].Value.ToString(); //Sientuo 外部賦值后的值
5.同理,在調用包時,如果是給包的連接管理器傳遞連接字符串的話,是對 Connections["數據源管理器名"].ConnectionString 進行操作,同樣是要做好判斷,是否存在
//讀取配置文件中的鏈接字符串,并進行解密 string con = ConfigurationManager.ConnectionStrings["dbConnStr_Temp"].ToString(); string RealPwd = AddPwd.GetConDb(con); package.Connections["DBTest.sa"].ConnectionString = RealPwd;
所謂的數據源管理器名,右鍵-添加連接源
這個連接管理器功能非常強大,可以對很多數據進行配置,而操作SSIS離不開和數據打交道,其實大數據的核心ETL,就是對數據進行 抽取、轉換、加載,而SSIS工具功能非常強大,可以為各種各樣的數據交互提供平臺,從而實現邏輯上的數據共享,構成人類社會的基單元是人,而人的各種行為都可以被當做數據進行存儲,數據共享時代為我們帶來便捷的同時,也讓我們無處遁形,這是一個最好的時代。
權當做學習記錄
--市人皆大笑,舉手揶揄之
文章列表