共用方式為


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

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

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

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

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

Binding 屬性 Description
InboundOperationType 指定您要執行 輪詢通知 輸入作業。 預設值為 Polling
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 配接器的範例。 Oracle E-Business 配接器範例也會提供以本主題為基礎的範例 SelectPolling_ChannelModel

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

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

從配接器接收輪詢訊息

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

  2. 在方案總管中,新增 、 Microsoft.ServiceModel.ChannelsSystem.ServiceModel 和 的 System.Runtime.Serialization 參考 Microsoft.Adapters.OracleEBS

  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. 在通道上叫用 接收 ,以從配接器取得下一個輸入訊息。

    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 應用程式