共用方式為


使用 SELECT 語句搭配 WCF 通道模型輪詢 Oracle E-Business Suite

您可以使用 SELECT 語句持續輪詢 Oracle E-Business Suite 中的介面數據表、介面檢視、數據表和檢視,來設定 Oracle E-Business 配接器來接收定期的數據變更訊息。 您可以將 SELECT 語句指定為輪詢語句,配接器會定期執行以輪詢 Oracle E-Business Suite。 您也可以指定輪詢語句執行後,配接器要執行的 PL/SQL 程式代碼區塊。

若要啟用輪詢,您必須指定特定系結屬性,如本主題所述。 如需配接器如何支援輪詢的詳細資訊,請參閱 使用輪詢支援輸入呼叫

使用 Oracle E-Business Suite 配接器繫結屬性設定輪詢操作

下表摘要說明您用來設定配接器以接收數據變更訊息的 Oracle E-Business 配接器系結屬性。 在執行輪詢應用程式時,您必須指定這些系結屬性。

綁定屬性 說明
InboundOperationType 指定您要執行 輪詢通知 輸入作業。 預設為 輪詢
PolledDataAvailableStatement 指定配接器執行的 SQL 語句,以判斷是否有任何數據可供輪詢。 只有當記錄可用時,您為 PollingInput 系結屬性指定的 SELECT 語句才會執行。
PollingInterval 指定 Oracle E-Business 配接器執行 PolledDataAvailableStatement 系結屬性所指定的語句的間隔,以秒為單位。 預設值為30秒。 輪詢間隔會決定連續輪詢之間的時間間隔。 如果語句在指定的間隔內執行,適配器會在間隔的剩餘時間內暫停。
PollingInput 指定輪詢語句。 若要使用 SELECT 陳述式查詢評估,您必須為此綁定屬性指定一個 SELECT 陳述式。 預設值為 null。

您必須指定 PollingInput 系結屬性的值,才能啟用輪詢。 只有在有數據可供輪詢時,才會執行輪詢語句,這是 由 PolledDataAvailableStatement 系結 屬性所決定。
PollingAction 指定輪詢作業的動作。 您可以使用「新增轉接器服務參考」Visual Studio 外掛程式,從為操作生成的服務接口中判斷輪詢動作。
PostPollStatement 指定執行 PollingInput 系結屬性所指定語句之後執行的語句區塊。
PollWhileDataFound 如果數據表中有可用的數據,指定 Oracle E-Business 配接器是否應忽略輪詢間隔並持續執行輪詢語句。 如果數據表中沒有可用的數據,配接器會還原為在指定的輪詢間隔執行輪詢語句。 預設值為 false。

如需更完整的這些屬性描述,請參閱 BizTalk Adapter for Oracle E-Business Suite 綁定屬性。 如需如何使用 Oracle E-Business 配接器輪詢 Oracle 資料庫的詳細說明,請閱讀本主題的後續內容。

本主題如何展示輪詢的運作方式

在本主題中,為了示範 Oracle E-Business 配接器如何使用 SELECT 語句支援接收數據變更訊息,您可以在 Application Object Library 應用程式中輪詢MS_SAMPLE_EMPLOYEE介面數據表。 當您執行隨附範例的create_apps_artifacts.sql腳本,以在 Oracle E-Business Suite 中建立這些物件時,就會建立此數據表。

為了示範輪詢作業,我們會執行下列動作:

  • PolledDataAvailableStatement 系結 屬性指定 SELECT 語句,以判斷要輪詢的介面數據表 (MS_SAMPLE_EMPLOYEE) 具有任何數據的位置。 在此範例中,您可以將這個系結屬性設定為:

    SELECT COUNT (*) FROM MS_SAMPLE_EMPLOYEE  
    

    這可確保配接器只有在 MS_SAMPLE_EMPLOYEE 介面數據表有資料時,才會執行輪詢語句。

  • 指定 PollingInput 系結屬性的 SELECT 語句。 此語句會擷取MS_SAMPLE_EMPLOYEE介面數據表中的所有數據列。 在此範例中,您可以將這個系結屬性設定為:

    SELECT * FROM MS_SAMPLE_EMPLOYEE FOR UPDATE  
    

    備註

    如需 SELECT 語句中使用的 FOR UPDATE 子句相關信息,請參閱 從 Oracle E-Business Suite 接收輪詢型數據變更訊息

  • 指定 DELETE 語句做為 PostPollStatement 系結 屬性的一部分。 此語句會刪除介面數據表MS_SAMPLE_EMPLOYEE中的所有數據。 在此範例中,您可以將這個系結屬性設定為:

    DELETE FROM MS_SAMPLE_EMPLOYEE  
    

    發生這種情況之後,下次執行針對 PollingInput 指定的語句時,它將不會擷取任何數據。

  • 在將更多數據新增至MS_SAMPLE_EMPLOYEE介面數據表之前,您不會收到任何輪詢訊息,因此您必須使用新的記錄重新填入MS_SAMPLE_EMPLOYEE介面數據表。 您可以執行範例所提供的insert_apps_data.sql腳本來執行此動作。 執行此腳本之後,下一個輪詢作業會擷取插入數據表的新記錄。

處理輪詢請求訊息

配接器會在您的程式碼上啟動輪詢操作,以輪詢 Oracle E-Business Suite。 也就是說,配接器會透過IInputChannel通道圖形傳送您收到的輪詢要求訊息。 輪詢要求訊息包含 PollingInput 系結屬性所指定的查詢結果集。 您可以使用下列兩種方式之一來取用輪詢訊息:

  • 若要使用節點值串流來取用訊息,您必須在回應訊息上呼叫 WriteBodyContents 方法,並將實作節點值串流的 XmlDictionaryWriter 傳遞給它。

  • 若要使用節點串流來取用訊息,您可以在回應訊息上呼叫 GetReaderAtBodyContents 來取得 XmlReader

關於本主題中使用的範例

本主題中的範例會輪詢MS_SAMPLE_EMPLOYEE介面數據表。 產生數據表的腳本會隨附範例。 如需範例的詳細資訊,請參閱 Oracle EBS 配接器的範例。 這個與本主題相關的範例 SelectPolling_ChannelModel 也包括在 Oracle E-Business 配接器範例中。

使用 WCF 通道模型接收輪詢操作的傳入訊息

本節提供如何使用 Oracle E-Business 配接器撰寫 .NET 應用程式(通道模型)以接收輸入輪詢訊息的指示。

從配接器接收輪詢訊息

  1. 在 Visual Studio 中建立Microsoft Visual C# ® 專案。 針對本主題,建立主控台應用程式。

  2. 在 [方案總管] 中,新增 Microsoft.Adapters.OracleEBSMicrosoft.ServiceModel.ChannelsSystem.ServiceModelSystem.Runtime.Serialization 的參考。

  3. 開啟Program.cs檔案,並新增下列命名空間:

    • Microsoft.Adapters.OracleEBS

    • System.ServiceModel

    • System.ServiceModel.Description

    • System.ServiceModel.Channels

    • System.Xml

  4. 指定連線 URI。 如需配接器連線 URI 的詳細資訊,請參閱 建立 Oracle E-Business Suite 連線 URI

    Uri ConnectionUri = new Uri("oracleebs://ebs_instance_name");  
    
  5. 建立 OracleEBSBinding 的實例,並設定設定輪詢所需的系結屬性。 您至少必須設定 InboundOperationTypePolledDataAvailableStatementPollingInputPollingAction 系結屬性。 如需用來設定輪詢之繫結屬性的詳細資訊,請參閱 使用輪詢支持輸入呼叫

    OracleEBSBinding binding = new OracleEBSBinding();  
    binding.InboundOperationType = InboundOperation.Polling;  
    binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM MS_SAMPLE_EMPLOYEE";  
    binding.PollingInput = "SELECT * FROM MS_SAMPLE_EMPLOYEE FOR UPDATE";  
    binding.PollingAction = "InterfaceTables/Poll/FND/APPS/MS_SAMPLE_EMPLOYEE";  
    binding.PostPollStatement = "DELETE FROM MS_SAMPLE_EMPLOYEE";  
    
  6. 因為您要輪詢介面資料表,因此您也必須設定應用程式環境。 如需設定應用程式內容所需的應用程式內容和系結屬性的詳細資訊,請參閱 設定應用程式內容

    binding.OracleUserName = "<Enter user name here>";  
    binding.OraclePassword = "<Enter password here>";  
    binding.OracleEBSResponsibilityName = "<Enter responsibility here>";  
    
  7. 建立係結參數集合並設定認證。

    ClientCredentials credentials = new ClientCredentials();  
    credentials.UserName.UserName = "<Enter user name here>";  
    credentials.UserName.Password = "<Enter password here>";  
    
    BindingParameterCollection bindingParams = new BindingParameterCollection();  
    bindingParams.Add(credentials);  
    
  8. 建立通道接聽程式並加以開啟。 您可以在 OracleEBSBinding 上叫用 BuildChannelListener<IInputChannel> 方法來建立接聽程式。

    IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(connectionUri, bindingParams);  
    listener.Open();  
    
  9. 藉由在接聽程式上叫用 AcceptChannel 方法並開啟它,以取得 IInputChannel 通道。

    IInputChannel channel = listener.AcceptChannel();  
    channel.Open();  
    
  10. 在通道上叫用 Receive ,以從配接器取得下一個輸入訊息。

    Message message = channel.Receive();  
    
  11. 取用輸入作業所傳回的結果集。 您可以使用 XmlReaderXmlDictionaryWriter 來取用訊息。

    XmlReader reader = message.GetReaderAtBodyContents();  
    
  12. 當您完成處理要求時,請關閉通道。

    channel.Close()  
    

    這很重要

    完成處理輸入作業之後,您必須關閉通道。 無法關閉通道可能會影響程式代碼的行為。

  13. 當您完成接收資料變更的訊息時,請關閉接聽程式。

    listener.Close()  
    

    這很重要

    關閉接聽程式不會關閉使用接聽程式建立的通道。 您必須明確地關閉使用接聽程式建立的每個通道。

範例

下列範例顯示一個輪詢應用程式,其會對MS_SAMPLE_EMPLOYEE介面表進行輪詢。 PollingInput 屬性包含 select 語句,可讀取MS_SAMPLE_EMPLOYEE數據表中的所有數據,而 post poll 語句會刪除相同數據表中的所有數據。 寫入輪詢訊息到C:\PollingOutput.xml

在將更多數據新增至MS_SAMPLE_EMPLOYEE介面數據表之前,後續輪詢訊息將不會包含任何記錄。 您可以執行範例所提供的insert_apps_data.sql腳本來執行此動作。 執行這個腳本後,下一次輪詢作業將擷取插入到資料表中的新記錄。 配接器會持續檢查,直到您按下 <RETURN> 關閉服務主機為止。

using System;  
using Microsoft.Adapters.OracleEBS;  
using System.ServiceModel;  
using System.ServiceModel.Description;  
using System.ServiceModel.Channels;  
using System.Xml;  

namespace SelectPolling_ChannelModel  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Console.WriteLine("Sample started. This sample will poll 5 times and will perform the following tasks:");  
            Console.WriteLine("Press any key to start polling...");  
            Console.ReadLine();  
            IChannelListener<IInputChannel> listener = null;  

            IInputChannel channel = null;  

            try  
            {  
                TimeSpan messageTimeout = new TimeSpan(0, 0, 30);  

                OracleEBSBinding binding = new OracleEBSBinding();  
                binding.InboundOperationType = InboundOperation.Polling;  
                binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM MS_SAMPLE_EMPLOYEE";  
                binding.PollingInput = "SELECT * FROM MS_SAMPLE_EMPLOYEE FOR UPDATE";  
                binding.PollingAction = "InterfaceTables/Poll/FND/APPS/MS_SAMPLE_EMPLOYEE";  
                binding.PostPollStatement = "DELETE FROM MS_SAMPLE_EMPLOYEE";  
                binding.OracleUserName = "<Enter user name here>";  
                binding.OraclePassword = "<Enter password here>";  
                binding.OracleEBSResponsibilityName = "<Enter responsibility here>";  

                Uri ConnectionUri = new Uri("oracleebs://ebs_instance_name?");  

                ClientCredentials credentials = new ClientCredentials();  
                credentials.UserName.UserName = "<Enter user name here>";  
                credentials.UserName.Password = "<Enter password here>";  

                BindingParameterCollection bindingParams = new BindingParameterCollection();  
                bindingParams.Add(credentials);  

                listener = binding.BuildChannelListener<IInputChannel>(ConnectionUri, bindingParams);  
                listener.Open();  

                channel = listener.AcceptChannel();  
                channel.Open();  

                Console.WriteLine("Channel and Listener opened...");  
                Console.WriteLine("\nWaiting for polled data...");  
                Console.WriteLine("Receive request timeout is {0}", messageTimeout);  

                // Poll five times with the specified message timeout   
                // If a timeout occurs polling will be aborted  
                for (int i = 0; i < 5; i++)  
                {  
                    Console.WriteLine("Polling: " + i);  
                    Message message = null;  
                    XmlReader reader = null;  
                    try  
                    {  
                        //Message is received so process the results  
                        message = channel.Receive(messageTimeout);  
                    }  
                    catch (System.TimeoutException toEx)  
                    {  
                        Console.WriteLine("\nNo data for request number {0}: {1}", i + 1, toEx.Message);  
                        continue;  
                    }  

                    // Get the query results using an XML reader  
                    try  
                    {  
                        reader = message.GetReaderAtBodyContents();  
                    }  
                    catch (Exception ex)  
                    {  
                        Console.WriteLine("Exception :" + ex);  
                        throw;                          
                    }  

                    XmlDocument doc = new XmlDocument();  
                    doc.Load(reader);  
                    using (XmlWriter writer = XmlWriter.Create("C:\\PollingOutput.xml"))  
                    {  
                        doc.WriteTo(writer);  
                        Console.WriteLine("The polling response is saved at 'C:\\PollingOutput.xml'");  
                    }  
                    // return the cursor  
                    Console.WriteLine();  

                    // close the reader  
                    reader.Close();  

                    message.Close();  
                }  
                Console.WriteLine("\nPolling done -- hit <RETURN> to finish");  
                Console.ReadLine();  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine("Exception is: " + ex.Message);  
                Console.ReadLine();  
                if (ex.InnerException != null)  
                {  
                    Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);  
                    Console.ReadLine();  
                }  
            }  
            finally  
            {  
                // IMPORTANT: close the channel and listener to stop polling  
                if (channel != null)  
                {  
                    if (channel.State == CommunicationState.Opened)  
                        channel.Close();  
                    else  
                        channel.Abort();  
                }  

                if (listener != null)  
                {  
                    if (listener.State == CommunicationState.Opened)  
                        listener.Close();  
                    else  
                        listener.Abort();  
                }  
            }  
        }  
    }  
}  

另請參閱

使用 WCF 通道模型開發 Oracle E-Business Suite 應用程式