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




posted @ 2012-08-18 00:19  Tom_Tan  阅读(5366)  评论(2编辑  收藏