您可以使用 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 應用程式(通道模型)以接收輸入輪詢訊息的指示。
從配接器接收輪詢訊息
在 Visual Studio 中建立Microsoft Visual C# ® 專案。 針對本主題,建立主控台應用程式。
在 [方案總管] 中,新增
Microsoft.Adapters.OracleEBS
、Microsoft.ServiceModel.Channels
、System.ServiceModel
和System.Runtime.Serialization
的參考。開啟Program.cs檔案,並新增下列命名空間:
Microsoft.Adapters.OracleEBS
System.ServiceModel
System.ServiceModel.Description
System.ServiceModel.Channels
System.Xml
指定連線 URI。 如需配接器連線 URI 的詳細資訊,請參閱 建立 Oracle E-Business Suite 連線 URI。
Uri ConnectionUri = new Uri("oracleebs://ebs_instance_name");
建立 OracleEBSBinding 的實例,並設定設定輪詢所需的系結屬性。 您至少必須設定 InboundOperationType、 PolledDataAvailableStatement、 PollingInput 和 PollingAction 系結屬性。 如需用來設定輪詢之繫結屬性的詳細資訊,請參閱 使用輪詢支持輸入呼叫。
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>";
建立係結參數集合並設定認證。
ClientCredentials credentials = new ClientCredentials(); credentials.UserName.UserName = "<Enter user name here>"; credentials.UserName.Password = "<Enter password here>"; BindingParameterCollection bindingParams = new BindingParameterCollection(); bindingParams.Add(credentials);
建立通道接聽程式並加以開啟。 您可以在 OracleEBSBinding 上叫用 BuildChannelListener<IInputChannel> 方法來建立接聽程式。
IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(connectionUri, bindingParams); listener.Open();
藉由在接聽程式上叫用 AcceptChannel 方法並開啟它,以取得 IInputChannel 通道。
IInputChannel channel = listener.AcceptChannel(); channel.Open();
在通道上叫用 Receive ,以從配接器取得下一個輸入訊息。
Message message = channel.Receive();
取用輸入作業所傳回的結果集。 您可以使用 XmlReader 或 XmlDictionaryWriter 來取用訊息。
XmlReader reader = message.GetReaderAtBodyContents();
當您完成處理要求時,請關閉通道。
channel.Close()
這很重要
完成處理輸入作業之後,您必須關閉通道。 無法關閉通道可能會影響程式代碼的行為。
當您完成接收資料變更的訊息時,請關閉接聽程式。
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();
}
}
}
}
}