共用方式為


使用 WCF 通道模型串流 Oracle Database LOB 數據類型

Microsoft BizTalk Adapter for Oracle Database 支援特定作業的 LOB 數據端對端串流。 本主題中的各節說明當您使用 WCF 通道模型時,如何實作 LOB 數據的串流。

如需配接器如何支援LOB資料類型串流的背景資訊,請參閱 在Oracle Database 配接器中串流大型物件資料類型。 在繼續之前,您應該先閱讀本主題。

示範LOB數據流的範例可在 Oracle 資料庫配接器隨附的 SDK 範例中取得。 如需詳細資訊,請參閱 SDK 中的範例

將輸出訊息串流至配接器

配接器支援UpdateLOB作業之要求訊息的端對端LOB資料串流。

若要支援 WCF 通道模型中 UpdateLOB 作業的端對端串流,您必須:

  1. UseAmbientTransaction 系結屬性設定為 true。

  2. 實作能夠串流 LOB 數據的 System.ServiceModel.Channels.BodyWriter (在 LOB 數據上執行節點值串流)。

  3. 在交易範圍內執行 UpdateLOB 作業。

  4. 使用 BodyWriter 提供訊息本文,並以 Message.Create 方法的適當多載建立 System.ServiceModel.Message 以叫用作業。

設定 UseAmbientTransaction 綁定屬性

下列範例示範如何建立 Oracle 資料庫配接器的系結,並設定 UseAmbientTransaction 系結屬性。

// Create binding  
OracleDBBinding odbBinding = new OracleDBBinding();  
  
//set the binding property  
binding.UseAmbientTransaction = true;  
  

實作主體編寫程式

下列範例示範執行節點值串流之 BodyWriter 的實作。

/// <summary>  
/// This class overrides the OnWriteBodyContents function to do node-value streaming  
/// </summary>  
class StreamingBodyWriter : BodyWriter, IDisposable  
{  
    XmlReader m_reader = null;  
  
    int m_chunkSize;  
    /// <summary>  
    /// Initializes the body writer  
    /// </summary>  
    /// <param name="reader">Reader for input</param>  
    /// <param name="chunkSize">The chunksize in which the data is passed to adapter</param>  
    public StreamingBodyWriter(XmlReader reader, int chunkSize)  
        : base(false)  
    {  
        m_reader = reader;  
        if (chunkSize \<= 0)  
            throw new ApplicationException("ChunkSize should be a positive value");  
        m_chunkSize = chunkSize;  
    }  
  
    protected override void OnWriteBodyContents(XmlDictionaryWriter writer)  
    {  
        if (m_reader == null)  
            throw new ApplicationException("Reader cannot be null");  
  
        while (m_reader.Read())  
        {  
            switch (m_reader.NodeType)  
            {  
                case XmlNodeType.Element:  
                    writer.WriteStartElement(m_reader.LocalName, m_reader.NamespaceURI);  
                    break;  
                case XmlNodeType.Text:  
                    #region Streaming Code  
                    char[] tempBuffer = new char[m_chunkSize];  
                    int length = 0;  
                    while ((length = m_reader.ReadValueChunk(tempBuffer, 0, m_chunkSize)) > 0)  
                    {  
                        writer.WriteString(new String(tempBuffer, 0, length));  
                    }  
                    #endregion  
                    break;  
                case XmlNodeType.EndElement:  
                    writer.WriteEndElement();  
                    break;  
            }  
        }  
  
    }  
  
    #region IDisposable Members  
  
    public void Dispose()  
    {  
        if (m_reader != null)  
        {  
            m_reader.Close();  
            m_reader = null;  
        }  
    }  
  
    #endregion  
}  

在交易範圍內執行作業

下列範例示範如何在交易範圍內執行作業。

// Create a transaction scope  
using(TransactionScope tx = new TransactionScope())  
{  
  // perform operations within the transaction  
  // ...  
  // ...  
  
  //Complete the transaction  
  tx.Complete()  
}  
  

使用 BodyWriter 建立訊息

下列範例示範如何在上述範例中使用 BodyWriter 建立 UpdateLOB 要求訊息。 訊息數據會從檔案讀取。

// Create a transaction scope  
using(TransactionScope tx = new TransactionScope())  
{  
    XmlReader readerIn = XmlReader.Create ("updatelob.xml");  
    // StreamingBodyWrtier class is responsible for streaming  
    StreamingBodyWriter stBW = new StreamingBodyWriter(readerIn, chunkSize);  
  
    Message InputMsg = Message.CreateMessage(MessageVersion.Default,  
    "http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER/UpdateLOB",   
    stBW);  
  
    //Send the request message and get the output message  
    OutputMsg = channel.Request(InputMsg);  
  
    tx.Complete();  
}  
  

從配接器串流輸入訊息

配接器支援下列輸入訊息的端對端 LOB 資料串流:

  • 包含 LOB 資料的 OUT 或 IN OUT 參數之函式的回應訊息。 請注意,RECORD TYPE 參數可以包含 LOB 資料行。

  • 包含 LOB 資料的 OUT REF CURSOR 參數(或傳回值)函式的回應訊息。 這包括 IN OUT REF CURSOR 參數的輸出面。

  • 包含 LOB 資料的 IN 或 IN OUT 參數之程序的回應訊息。 請注意,RECORD TYPE 參數可以包含 LOB 資料行。

  • 包含 LOB 資料的 OUT REF CURSOR 參數之程序的回應訊息。 這包括 IN OUT REF CURSOR 參數的輸出部分

  • 傳回包含 LOB 資料之結果集之 SQLEXECUTE 作業的回應訊息。

  • 數據表或視圖選取傳回包含LOB數據的作業的回應訊息。

  • 要求 (輸入) POLLINGSTMT 作業的訊息

    若要在 WCF 通道模型中的輸入訊息上支援端對端串流,您必須:

  1. 實作能夠串流 LOB 數據的 System.Xml.XmlDictionaryWriter (在 LOB 數據上執行節點值串流)。

  2. 請透過此 XmlDictionaryWriter 來調用 WriteBodyContents 方法以處理 Message

實作 XmlDictionaryWriter 的方法

下列範例示範執行節點值串流之 XmlDictionaryWriter 的實作。

using System;  
using System.Xml;  
using System.Text;  
  
class FileXmlWriter : XmlDictionaryWriter  
{  
    XmlTextWriter xts;  
  
    public FileXmlWriter(string file)  
    {  
        xts = new XmlTextWriter(file, Encoding.UTF8);  
    }  
  
    public override void WriteBase64(byte[] buffer, int index, int count)  
    {  
        xts.WriteBase64(buffer, index, count);  
    }  
  
    public override void WriteCData(string text)  
    {  
        xts.WriteCData(text);  
    }  
  
    public override void WriteCharEntity(char ch)  
    {  
        xts.WriteCharEntity(ch);  
    }  
  
    public override void WriteChars(char[] buffer, int index, int count)  
    {  
        xts.WriteChars(buffer, index, count);  
    }  
  
    public override void WriteComment(string text)  
    {  
        xts.WriteComment(text);  
    }  
  
    public override void WriteDocType(string name, string pubid, string sysid, string subset)  
    {  
        xts.WriteDocType(name, pubid, sysid, subset);  
    }  
  
    public override void WriteEndAttribute()  
    {  
        xts.WriteEndAttribute();  
    }  
  
    public override void WriteEndDocument()  
    {  
        xts.WriteEndDocument();  
    }  
  
    public override void WriteEndElement()  
    {  
        xts.WriteEndElement();  
    }  
  
    public override void WriteEntityRef(string name)  
    {  
        xts.WriteEntityRef(name);  
    }  
  
    public override void WriteFullEndElement()  
    {  
        xts.WriteFullEndElement();  
    }  
  
    public override void WriteProcessingInstruction(string name, string text)  
    {  
        xts.WriteProcessingInstruction(name, text);  
    }  
  
    public override void WriteRaw(string data)  
    {  
        xts.WriteRaw(data);  
    }  
  
    public override void WriteRaw(char[] buffer, int index, int count)  
    {  
        xts.WriteRaw(buffer, index, count);  
    }  
  
    public override void WriteStartAttribute(string prefix, string localName, string ns)  
    {  
        xts.WriteStartAttribute(prefix, localName, ns);  
    }  
  
    public override void WriteStartDocument(bool standalone)  
    {  
        xts.WriteStartDocument(standalone);  
    }  
  
    public override void WriteStartDocument()  
    {  
        xts.WriteStartDocument();  
    }  
  
    public override void WriteStartElement(string prefix, string localName, string ns)  
    {  
        xts.WriteStartElement(localName);  
    }  
  
    public override void WriteString(string text)  
    {  
        xts.WriteString(text);  
    }  
  
    public override void WriteSurrogateCharEntity(char lowChar, char highChar)  
    {  
        xts.WriteSurrogateCharEntity(lowChar, highChar);  
    }  
  
    public override void WriteWhitespace(string ws)  
    {  
        xts.WriteWhitespace(ws);  
    }  
  
    public override void Close()  
    {  
        xts.Close();  
    }  
  
    public override void Flush()  
    {  
        xts.Flush();  
    }  
  
    public override string LookupPrefix(string ns)  
    {  
        return xts.LookupPrefix(ns);  
    }  
  
    public override WriteState WriteState  
    {  
        get { return xts.WriteState; }  
    }  
  
}  

使用 XmlDictionaryWriter 處理訊息

下列範例示範如何使用上述範例中實作的 FileXmlWriter 來取用數據表 Select 回應訊息。 ( FileWriter 類別是由子類別 XmlDictionaryWriter 所建立。此範例會使用 IRequestChannel 通道來叫用 Select 作業。 已省略建立頻道的詳細資訊。 Select 要求訊息會從檔案讀取,而且 Select 回應消息會寫入檔案。

// Read Select message body from a file  
XmlReader readerIn = XmlReader.Create("select.xml");  
Message InputMsg = Message.CreateMessage(MessageVersion.Default,  
    "http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER/Select", readerIn);  
  
Message OutputMsg = channel.Request(InputMsg);  
  
// Streaming response message to select_output.xml using the custom XmlDictionaryWriter;  
FileXmlWriter fileXmlWriter = new FileXmlWriter("select_output.xml");  
OutputMsg.WriteBodyContents(fileXmlWriter);  
fileXmlWriter.Flush();  
fileXmlWriter.Close();  
  
// Streaming complete close output message;  
OutputMsg.Close();  

下列 XML 顯示 Select 作業的要求訊息(select.xml 檔案的內容)。 CUSTOMER 資料表包含名為 PHOTO 的 BLOB 欄。

<Select xmlns="http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER">  
  <COLUMN_NAMES>*</COLUMN_NAMES>  
  <FILTER>NAME='Kim Ralls'</FILTER>  
</Select>  

另請參閱

使用 WCF 通道模型開發 Oracle 資料庫應用程式