SSIS 腳本任務(Script Task)實戰


最近在忙一個酒店預訂系統項目,已集成API XML,但是提交酒店訂單到API之后,訂單的狀態要實行與API同步。因為可能下一分鍾,API的訂單狀態可能已經確認,但本地訂單狀態還是 處理當中的。

當客人打開某個訂單詳細信息的時候,再去Call 一次API的狀態。這是既傳統,又笨的方法。

但是問題 接踵而至

1. 訂單處理既然不及時,又不准時。
2. API提供商不給單條記錄去同步狀態。
等等。


詳細解決方案:

用SSIS 設計 腳本任務, 再部署SSIS包任務,每2分鍾Call一次API。

 

步驟:

1.生成Post XML代碼

T-SQL CODE

ALTER proc [dbo].[BookingXML]
as
declare @XmlOutput xml
declare @a nvarchar(max)
set @XmlOutput = (
select distinct a.APICode as hmcref from dbo.HotelBooking a left join dbo.sys_Procduct b on a.FID=b.FID where isnull(a.APICode,'')<>'' and isnull(a.APIStatus,'') in ('IC','CA','OR')
--and a.BDT>=Getdate() and b.Del=0
FOR XML Path(''), ROOT('hmcreflist'), ELEMENTS)

if cast(@XmlOutput as nvarchar(max))<>''
begin
    set @a = '<request><company>aa</company><id>bb</id><pass>cc</pass><lang>SIM</lang>{@Str}</request>'
    select cast(replace(@a, '{@Str}', cast(@XmlOutput as nvarchar(max))) as xml)
end
else
begin
    select ''
end

 

XML CODE

<request>
  <company>aa</company>
  <id>bb</id>
  <pass>cc</pass>
  <lang>SIM</lang>
  <hmcreflist>
    <hmcref>W2049850</hmcref>
    <hmcref>W2049856</hmcref>
    <hmcref>W2050473</hmcref>
    <hmcref>W2050522</hmcref>
    <hmcref>W2050593</hmcref>
    <hmcref>W2050594</hmcref>
  </hmcreflist>
</request>

 

2.設計SSIS包

 

設置ResultSet XML

 

結果集 變量名稱為 user::XMLOutput  結果名稱為0

 

 

腳本任務
PrecompileScriptIntoBinaryCode 要設為False, 否則提示 “IDE未成生成二進制的錯誤”

 

ReadWriteVariables 設為sql 任務的ResultSet 的變量 XMLOutput

 

重點來了

點擊 “設計腳本”,使用HttpWebRequest用post發送請求,再用HtppWebResponse返回XML,再用根據訂單號update 狀態。

VB.net讀取sql server ResultSet變量

Dts.Variables("XMLOutput")

 

腳本任務鏈接Sql server數據庫, 原先在 連接管理設置有 AServ 名稱連接器,有腳本任務直接調用就行。

Dts.Connections.Item("AServ").AcquireConnection(Nothing)
Dim conn As New SqlClient.SqlConnection(Dts.Connections.Item("AServ").ConnectionString)

 

注:用 IO.StreamWriter 生成操作和返回的日志,方便以后維護。

請把全局和腳體任務的MaximumErrorCount調大一點,這樣發生錯誤之后,會繼續執行任務。

 

完整的VB.net如下:

其中 Admin_UpdateBookingStatus 自定義訂單狀態處理儲存過程。

Imports System
Imports System.IO
Imports System.Net
Imports System.Data
Imports System.Text
Imports System.Math
Imports System.Xml
Imports Microsoft.SqlServer.Dts.Runtime


Public Class ScriptMain



    Public Sub Main()
        '
        ' Add your code here
        '
        'Dts.TaskResult = Dts.Results.Success

        Dim XMLString As String = " "


        If Dts.Variables("XMLOutput").Value.ToString <> "" Then

            XMLString = Dts.Variables("XMLOutput").Value.ToString.Replace("<ROOT>", "").Replace("</ROOT>", "")
            XMLString = "<?xml version=""1.0"" encoding=""UTF-8"" ?>" + XMLString

            Dim request As WebRequest = WebRequest.Create("http://www.abc.com/api/ddd.php")

            ' Set the Method property of the request to POST.
            request.Method = "POST"

            ' Create POST data and convert it to a byte array.
            Dim postData As String = XMLString
            Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)

            ' Set the ContentType property of the WebRequest.
            request.ContentType = "application/soap+xml; charset=utf-8"

            ' Set the ContentLength property of the WebRequest.
            request.ContentLength = byteArray.Length

            'Get the request stream.
            Dim dataStream As Stream = request.GetRequestStream()

            ' Write the data to the request stream.
            dataStream.Write(byteArray, 0, byteArray.Length)

            ' Close the Stream object.
            dataStream.Close()

            ' Get the response.
            Dim response As WebResponse = request.GetResponse()

            ' Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream()


            ' Open the stream using a StreamReader for easy access.
            Dim reader As New StreamReader(dataStream)

            Dim xmlDoc As New XmlDocument()
            xmlDoc.LoadXml(reader.ReadToEnd())

            Dim HMCREF As XmlNodeList
            Dim STATUSCODE As XmlNodeList

            HMCREF = xmlDoc.SelectNodes("//HMCREF")
            STATUSCODE = xmlDoc.SelectNodes("//STATUSCODE")

            ' Read the content.
            Dim BNO As String = ""
            Dim Status As String = ""

            Dim i As Integer
            Dim bstr As String = ""
            bstr = "E:\\log\\bookingstatus\\log-" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt"

            If HMCREF.Count = STATUSCODE.Count Then

                For i = 0 To HMCREF.Count - 1
                    If STATUSCODE.Item(i).InnerText() <> "" And HMCREF.Item(i).InnerText() <> "" Then

                        If BNO <> "" Then
                            BNO = BNO + "," + HMCREF.Item(i).InnerText()
                        Else
                            BNO = HMCREF.Item(i).InnerText()
                        End If

                        If Status <> "" Then
                            Status = Status + "," + STATUSCODE.Item(i).InnerText()
                        Else
                            Status = STATUSCODE.Item(i).InnerText()
                        End If

                    End If
                Next
            Else
                GenerateXmlFile(bstr, "'&XML=" + xmlDoc.InnerXml)
            End If


            If BNO <> "" And Status <> "" Then
                Dts.Connections.Item("AServ").AcquireConnection(Nothing)
                Dim conn As New SqlClient.SqlConnection(Dts.Connections.Item("AServ").ConnectionString)
                Dim cmd As New SqlClient.SqlCommand
                conn.Open()
                cmd.Connection = conn
                cmd.CommandTimeout = 300
                cmd.CommandText = " Admin_UpdateBookingStatus '" + BNO + "', '" + Status + "' "
                cmd.ExecuteNonQuery()
                conn.Close()
                GenerateXmlFile(bstr, "SQL = Admin_UpdateBookingStatus '" + BNO + "', '" + Status + "'&XML=" + xmlDoc.InnerXml)
            End If

            dataStream.Close()
            response.Close()

        End If




    End Sub

    Public Sub GenerateXmlFile(ByVal filePath As String, ByVal fileContents As String)

        Dim objStreamWriter As IO.StreamWriter
        Try

            objStreamWriter = New IO.StreamWriter(filePath)

            objStreamWriter.Write(fileContents)

            objStreamWriter.Close()

        Catch Excep As Exception

            MsgBox(Excep.Message)

        End Try

        Dts.TaskResult = Dts.Results.Success
    End Sub

End Class





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM