公告版位
哈囉,丫德我會常常更新一些工作上的心情記事及資訊科技新知與大家分享...

專案上有遇到客戶只有提供web services,我們只能接web services的資料下來,當做轉檔的資料來源

我想應該也有很多人有這樣的需求吧..

以下的教學,是實際發生的案例,如果已經會在ssis中使用web services的達人們,就可以不用看囉!

這次的案例很簡單

只是純粹做資料同步,什麼意思呢?也就是說資料其實都在客戶端輸入,但我們這邊也要同步備份他們其中的一個資料表的內容,以便做後續的處理

因此我們請客戶提供一個web services,然後我們接收他的資料來做同步..

首先在ssis的控制流程中拉出一個"web 服務工作"的控制項

image

接下來請新增兩個全域變數

第一個itexchds是接收web services用的

第二個viewds是測試時用的,後面會講到..

image

接下來請在"一般"頁籤的,httpconnection中新增一個連接

image

接下來在下圖的 伺服器url的地在輸入你們要接收的web services網址,假設我的webservices的name叫做test.asmx

例如:http://www.test.com.tw/TestWeb/Service/Test.asmx?WSDL

image

測試成功後,下一步就是要做一個wsdlfile的接收目的檔

你可以在以後要發行ssis的dtsx的地方,先建一個空的xxx.wsdl檔案(ps:xxx指的是你自己想命名的主檔名,建議可以用記事本建立,改掉副檔名就可以了),因為待會兒我們要指定wsdlfile,而這個檔案必須先存在,建立成功後,回到"web 服務工作"控制項的設定畫面

在wsdlfile選擇剛才建立好的空的test.wsdl檔案,然後點"下載wsdl"

image


為什麼呢?我說明一下,如果是在測試時,你可以指到任何地方都可以,但如果屆時要執行這個dtsx時,就要考慮這個wsdl要放在哪?

建議是跟發行dtsx後的地方放在一起,那在指定wsdlfile的時候,就指到發行位置的xxx.wsdl這個檔案,這樣發行後也就不會發行找不到檔案的問題

接下來切換到輸入頁籤

在services的地方選擇要執行的web services name,這個地方,必須在前面的"一般"頁籤中有執行"下載wsdl",才會選的到哦,不然是空的會沒得選

在method的地方選擇該web services中的function

image

接下來切換到"輸出"頁籤

在outputtype的地方選擇"變數"

在variable的地方選擇之前所設定的變數名稱,我自己是設itexchds,那看倌就依你們自訂的變數名稱來設定吧

完成後,按確定關閉視窗

image

接下來,拉出一個"資料流程工作"

image

在"資料流程工作"上點選滑鼠右鍵選編輯

接下來,拉出一個指令碼元件

為什麼在這裡不是選資料流程來源中的控制項,因為ssis的資料流程來源沒有提供接變數當作資料來源的部份

可以接變數當作資料來源的只有"指令碼元件"控制項,所以我們要選這個

image

拉出後,會再彈一個視窗,請選擇"來源",如下圖,選完後,按確定

image

接下來在"指令碼元件"中按滑鼠右鍵選編輯

在"輸入及輸出"的頁籤中,請照下圖操作,畫面上有看到四個輸出資料行,那是我這邊demo的範例

這裡要加入資料行指的是你從web services接下來後的欄位名稱有些哪,要自行輸入(比較麻煩的在這個地方,欄位多的話,那就當做練打字吧,哈)

記得一定要指定欄位的型別及長度哦

2009-2-16 下午 01-38-08.jpg  

接下來在切換到"指令碼"的頁籤

在readonlyvariables的地方輸入itexchds,這個變數也就是在之前設定為接web services資料的變數名稱,打上去之後,接下來請點選設計指令碼

image

接下來會開啟編輯程式碼的視窗如下

image

記得加入一個system.xml.dll的參考

image

image

接下來在CreateNewOutputRows()的function中輸入如下的程式碼

'-------------------------------------------------------------------------------------------------------------------

Dim i As Integer
        Dim xmldoc As New Xml.XmlDataDocument
        Dim strm As New System.IO.MemoryStream(Text.UnicodeEncoding.Unicode.GetBytes(Me.ReadOnlyVariables("itexchds").Value.ToString()))
        xmldoc.DataSet.ReadXml(strm)
        For i = 0 To xmldoc.DataSet.Tables(0).Rows.Count - 1
            With 輸出0Buffer
                .AddRow()
                .chym = CType(xmldoc.DataSet.Tables(0).Rows(i)("ch_ym"), String)
                .currency = CType(xmldoc.DataSet.Tables(0).Rows(i)("currency"), String)
                .exchrate = CType(xmldoc.DataSet.Tables(0).Rows(i)("exch_rate"), Integer)
                Try
                    .currname = CType(xmldoc.DataSet.Tables(0).Rows(i)("curr_name"), String)
                Catch ex As Exception
                    .currname = System.String.Empty
                End Try

            End With
        Next
        輸出0Buffer.EndOfRowset()

'-------------------------------------------------------------------------------------------------------------------

程式碼中的輸出0buffer這個名稱指的是你在"輸入及輸出"頁籤中所定義的名稱,預設為"輸出0",如果你有換掉,則我的程式碼,你也要改掉

image

中間那一段

.chym = CType(xmldoc.DataSet.Tables(0).Rows(i)("ch_ym"), String)
.currency = CType(xmldoc.DataSet.Tables(0).Rows(i)("currency"), String)
.exchrate = CType(xmldoc.DataSet.Tables(0).Rows(i)("exch_rate"), Integer)

指的是你web services接收下來的欄位,你有哪些是要使用的,需要使用的就要打上去

Try
       .currname = CType(xmldoc.DataSet.Tables(0).Rows(i)("curr_name"), String)
Catch ex As Exception
       .currname = System.String.Empty
End Try

這一段是判斷如果接收下來的欄位內容有null值的話,而接收的欄位又是string的話,就要放System.String.Empty,不然執行時會失敗,若完成後,按確定


接下來的動作,只是要測試資料是否真的有下來,所以我們"資料錄集目的地"的方式測試查看,實際上run的話,就看各位看倌要怎麼接,你也可以拉"oledb目的地"把資料寫到資料庫中,但建議最好是先放到"資料錄集目的地"中測試一下看看,ok 的話再換掉比較好

所以請在"資料流程目的地"中拉出"資料錄集目的地",並把綠線連起來,如下圖所示

image

接下來在"資料錄集目的地"點滑鼠右鍵,選編輯在variablename中選擇之前建立的變數viewds,當做呈現的資料集

image

接下來切換到"輸入資料行"頁籤,將想要看的欄位勾選起來

image 

接下來,請在綠線上按滑鼠右鍵選編輯,設定一個資料檢視器,不會的話,請參考SSIS-使用變數來下sql,這篇文章的最下方有說明如何設定,我就不再多加描述了

image

執行結果,因為資料是需要保密的不能呈現,所以用馬賽克..,但結論是資料是有接收到的..

2008-12-16 下午 06-54-48

在ssis中接web servcies是可以做的到,但要設定的地方也是很多,希望這篇文章可以幫助到需要的人

有問題請留言,或留下迴響討論囉

 

創作者介紹

信德隨想

丫德 發表在 痞客邦 PIXNET 留言(13) 人氣()


留言列表 (13)

發表留言
  • 嘉
  • 您好
    很感謝您部落格上所分享的SSIS的文章 對我來說受益良多 ^^

    我想做出以下功能 但試了好久都沒辦法成功
    用SSIS去抓遠端某個 固定目錄 裡的所有XML檔案 的某些固定節點
    直接寫入localhost的資料庫
    比如說XML文件如下:
    <?xml version="1.0" encoding="UTF-8" ?>
    - <AAA>
    - <BBB>
    - <CCC>
    - <DDD>
    <EEE>2008-12-30T01:24:54.0Z</EEE>
    <FFF>abc</FFF>
    <No>SL-1222</No>
    - <GGG>
    <HHH>123</HHH>
    <HHH>456</HHH>
    <HHH>789</HHH>
    </GGG>
    <III>ADD</III>
    <JJJ>def</JJJ>
    <KKK>active</KKK>
    - <LLL>
    <MMM>4</MMM>
    </LLL>
    - <NNN>
    <OOO>ghi</OOO>
    </NNN>
    <PPP>B122202</PPP>
    <QQQ>jkl</QQQ>
    </DDD>
    </CCC>
    </BBB>
    </AAA>
    然後我要把這份XML文件寫成三筆資料存入資料庫
    三筆資料的值如下:
    (欄位a-欄位b-欄位c-欄位d-欄位e)
    abc-123-def-ghi-jkl
    abc-456-def-ghi-jkl
    abc-789-def-ghi-jkl
    請問這樣要如何做到呢?
    若您能抽個空幫我 那我就太幸福了 謝謝 ^^
  • 嗯...首先謝謝你來看我的blog
    你所提的xml問題,我還沒做過呢!
    不過,我會試看看的
    用blog就是有這種好處,可以做到一些平常沒有辦法接觸到的經驗
    也謝謝你提供這個問題給我哦
    我會試試看的

    丫德 於 2009/02/13 15:21 回覆

  • 嘉
  • ㄟ 您真是太客氣了
    真的很謝謝您願意重視我的問題 ^^
  • 問一下,你是要固定抓
    <FFF>
    <HHH>
    <JJJ>
    <OOO>
    <QQQ>
    這幾個結點的值嗎?
    還有就是你的每個xml中都是固定這些嗎?

    另外請問你的xml是怎麼產生的?透過web serivces嗎?

    丫德 於 2009/02/13 16:21 回覆

  • 嘉
  • 問一下,你是要固定抓<FFF><HHH><JJJ><OOO><QQQ>這幾個結點的值嗎?
    ---是的,就這五個節點的值即可。

    還有就是你的每個xml中都是固定這些嗎?
    ---其實有5種xml的格式,但都大同小異,可能就多或少一、二個節點,我會以reg、imp、exp、pack、unpack這5種檔案名稱來區別不同格式,比如說:reg20090213143700.xml或imp20090213143800.xml之類的。
    ---續上個問題,即使不同格式,但就是取上個問題所提到的這5個節點的值。

    另外請問你的xml是怎麼產生的?透過web serivces嗎?
    ---是的,就是透過Web Services的方式接收到的。

    謝謝
  • 咦!那你既然可以用web services抓資料,為什麼還要再透過xml檔來做資料轉換?
    應該是直接抓web services所提供的方法中回傳的的資料集就可以了吧?
    剩下的方式就如我這篇文章所述應該就可以了
    還是你的web services是可以讓我測試看看的?

    丫德 於 2009/02/13 16:59 回覆

  • 悄悄話
  • yangxinde
  • 哈囉!嘉先生
    ok我知道了,但我要傳什麼參數給那個下載的function呢?
    麻煩你再用悄悄話傳給我,謝謝
    不然我沒有辦法進行下去
  • 嘉
  • 啊,對不起,我忘了。
    可是我是嘉小姐。

    可是那個網址上放的是舊的web services 新版的只有走區網
    而且負責web services那位同事出國去了 下週才會回來
    function的參數已經不可考了 因為改版過很多次

    對不起,讓您白忙一場了。
    又或者直接以xml文件做測試?
    目前也只有這個方法可行了 -.-
  • 哦!Sorry!嘉小姐
    如果是走區網的話,那就沒辦法了
    嗯 ...如果要以xml來寫的話,因為要配xsd,而你們的xml檔轉xsd後
    發現沒有辦法對應到欄位
    我想到的另一個方法是比較苯的方法,就是在.net中用繞迴圈的方式去一行一行讀
    若有讀到<FFF>的,就自行拆解到</FFF>結束前
    用跑迴圈的方式執行

    但最好的方法還是透過web serices,不然的話,要耗費更多的精神及時間去做哦
    另外再請教一下,你說執行到[指令碼元件(出現錯誤時為黃色)]到[資料錄集目的地]中間的管線時
    卻出現「在根層次的資料無效。 第 1 行,位置 1。」
    請問你的web services是用.net寫的嗎?

    另一個問題是若你單純只執行"web服務工作"這個控制項,是成功的嗎?
    若是成功的話,請你再拉一個"指令碼工作"元件
    將從web services中取得的資料的dataset傳給"指令碼工作"-->這個你會吧?

    然後在main()這個function中輸入下列文字

    Dim xmldoc As New Xml.XmlDataDocument
    Dim strm As New System.IO.MemoryStream(Text.UnicodeEncoding.Unicode.GetBytes(Dts.Variables("rs").Value.ToString()))
    xmldoc.DataSet.ReadXml(strm)
    MsgBox(xmldoc.DataSet.Tables(0).Rows(0)(0).ToString)
    MsgBox(xmldoc.DataSet.Tables(0).Rows.Count)

    上述語法中有一個"rs",這個換成你自己訂的dataset變數名稱,先這樣執行看看有沒有成功
    有的話,就是你在"指令碼元件"中的定義是有問題的 ,再針對這個部份修正
    如果這個地方就執行失敗的話,那可能就要用我說的方法了
    看結果如何我們再討論看看

    丫德 於 2009/02/13 18:28 回覆

  • 嘉
  • 您好 對不起 到現在才回覆您

    先回報一下上次我曾提到的錯誤狀況:"在根層次的資料無效。 第 1 行,位置 1。"
    目前已無出現;是因為我在設定"web服務工作"時未設定傳入的參數所致,非常抱歉。

    請問你的web services是用.net寫的嗎?
    ---是的,我的web services是用.net寫的。

    另一個問題是若你單純只執行"web服務工作"這個控制項,是成功的嗎?
    ---是的,若單純只執行"web服務工作"是成功的。

    ---另我在"web服務工作"中有設中斷點,抓到變數"itexchds"的value為:"<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<string><root><sort_head sortno=\"SL-Test\"/><sort_head sortno=\"sl333\"/><sort_head sortno=\"SL-1222\"/><sort_head sortno=\"SL-0886\"/><sort_head sortno=\"SL-0885\"/></root></string>"

    將從web services中取得的資料的dataset傳給"指令碼工作"-->這個你會吧?
    ---我沒另外拉一個"指令碼工作",而是直接在原來的CreateNewOutputRows()的function中加入您所說的那二個MsgBox,之後所出現的錯誤訊息是"找不到資料表 0。"

    謝謝
  • 嘉
  • 我現在測試的就沒使用我在1F所提到的那個比較複雜的xml格式,而先用很單純的格式(就是8F所提到的"itexchds"的value)先去做測試,若有成功,再去用1F所提的xml格式。

    我在"指令碼元件"的"輸入及輸出"的頁籤中,只設定一個輸出資料行"no",因為我只要抓到"itexchds"的value中的"sortno"這個節點的值即可。
  • 所以你目前執行的結果是對的?是ok的囉?
    如果是的話,那就恭禧你囉!
    另外如果你想要再了解我說的check部份的話,請參考一下這篇文章http://yangxinde.pixnet.net/blog/post/26106767

    丫德 於 2009/02/16 11:28 回覆

  • 嘉
  • ㄟ,不是啦。
    如我8F所說的,會出現"找不到資料表0"的錯誤訊息。

    我9F是說xml格式先改成較簡單的方式去做測試

    謝謝
  • 所以說你現在是卡在"找不到資料表0" 這個地方嗎?
    ok那這樣說好了
    你先用我
    http://yangxinde.pixnet.net/blog/post/26106767
    這篇文章所說的試試看,可不可以成功的抓到第一個列的第一個值,及回傳整個資料筆數
    可以的話,應該是在寫"指令碼元件"的程式碼有誤
    再不行的話,看可不可以連過去你們那裡看看了!
    不然就是請你給我看一下你目前是怎麼做的畫面擷圖
    寄到yangxindegmail .com給我看看
    問一下,你們公司只有你在用ssis嗎?

    丫德 於 2009/02/16 13:49 回覆

  • 妮
  • SSIS-Web 服務工作設定問題請教

    請問我在一般"頁籤中有執行"下載wsdl",我也確認過wsdl是存在的,但在輸入頁籤中的service下拉選項是空白的,請問還有那些設定需注意呢?麻煩你囉
  • 建議是跟dtsx放在一起同一層目錄中

    丫德 於 2009/12/16 23:54 回覆

  • 悄悄話
  • 悄悄話