共用方式為


使用 WCF 服務模型在 Oracle 資料庫中接收輪詢型資料變更訊息

您可以設定 Microsoft BizTalk Adapter for Oracle Database,針對 Oracle 資料表或檢視接收輪詢型資料變更訊息。 若要接收資料變更的訊息,配接器會定期針對 Oracle 資料表或檢視執行 SQL 查詢,後面接著選擇性的 PL/SQL 程式碼區塊。 然後,Oracle Database 配接器會將 SQL 查詢的結果傳回至您的應用程式,做為輸入 POLLINGSTMT 作業中的強型別結果集。 如需使用 Oracle 資料庫配接器在 Oracle 資料庫上設定及執行輪詢之機制的詳細資訊,請參閱 在 Oracle 資料庫配接器中接收輪詢型資料變更訊息。 強烈建議您先閱讀本主題,再繼續進行。

若要在使用 WCF 服務模型時接收 POLLINGSTMT 作業,您必須:

  • 從配接器所公開的中繼資料,為 POLLINGSTMT 作業產生 WCF 服務合約 (介面) 。 若要這樣做,您可以使用新增配接器服務參考 Visual Studio 外掛程式或 ServiceModel 中繼資料公用程式工具 (svcutil.exe) 。

  • 從這個介面實作 WCF 服務。

  • 使用服務主機裝載此 WCF 服務, (System.ServiceModel.ServiceHost) 。

    本節中的主題提供資訊和程式,協助您在 WCF 服務模型中對 Oracle 資料庫資料表和檢視執行輪詢。

關於本主題中使用的範例

本主題中的範例會使用 /SCOTT/ACCOUNTACTIVITY 資料表和 /SCOTT/Package/ACCOUNT_PKG/PROCESS_ACTIVITY 函式。 產生這些成品的腳本會隨附 BizTalk 配接器套件範例。 如需範例的詳細資訊,請參閱 配接器範例

在 WCF 服務模型中設定輪詢

您可以設定 Oracle Database 配接器,以在 Oracle 資料庫資料表和檢視表上執行輪詢,方法是設定系結屬性和選擇性連接屬性 (參數) 。 其中有些屬性是必要屬性,有些屬性必須同時在設計階段和執行時間設定。

  • 在設計階段,當您連線到 Oracle 資料庫以產生 WCF 服務合約時,您可以設定連接參數和系結屬性。

  • 在執行時間,您會在用來建立服務主機的 OracleDBBinding 物件上設定系結屬性。 當您將服務接聽程式新增至服務主機時,您可以設定連接參數。

    下列清單提供用來設定輪詢之系結屬性和連接參數的簡短概觀:

  • PollingStatement系結屬性。 您必須在設計階段和執行時間設定這個系結屬性。

  • 選擇性的系結屬性。 這些只需要在執行時間設定。

  • AcceptCredentialsInUri系結屬性。 如果您想要在連線 URI 中啟用認證,則必須在執行時間期間將此系結屬性設定為 true 。 當您將服務端點新增至服務主機時,使用者名稱和密碼必須存在於連線 URI 中。

  • 連線 URI 中的 PollingId 查詢字串參數。 如果您想要變更 POLLINGSTMT 作業的命名空間,則必須在設計階段和執行時間設定此連接屬性。

    如需用來設定輪詢之系結屬性和連接參數的完整描述,請參閱 在 Oracle 資料庫配接器中接收輪詢型資料變更訊息

WCF 服務合約和類別

您可以使用新增配接器服務參考 Visual Studio 外掛程式或 ServiceModel 中繼資料公用程式工具 (svcutil.exe) 來建立 WCF 服務合約, (介面) 和支援 POLLINGSTMT 作業的類別。

當您使用下列任一工具來連線到 Oracle 資料庫,以產生 POLLINGSTMT 作業的服務合約時:

  • 您必須指定 PollingStatement 系結屬性。 配接器會使用此系結屬性中的 SELECT 語句,為 POLLINGSTMT 作業所傳回的強型別結果集產生正確的中繼資料。

  • 您可以選擇性地在連線 URI 中指定 PollingId 參數。 配接器會使用此參數來產生 POLLINGSTMT 作業的命名空間。

    在下列範例中:

  • PollingStatement 設定為 「SELECT * FROM ACCOUNTACTIVITY FOR UPDATE」。

  • PollingId 設定為 「AcctActivity」。

WCF 服務合約 (介面)

下列程式碼顯示針對 POLLINGSTMT 作業產生的 WCF 服務合約 (介面) 。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03", ConfigurationName="POLLINGSTMT_OperationGroup")]  
public interface POLLINGSTMT_OperationGroup {  
  
    // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)  
    // of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)  
    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMT")]  
    void POLLINGSTMT(POLLINGSTMT request);  
}  

訊息合約

訊息合約命名空間是由連線 URI 中的 PollingId 參數修改。 要求訊息會傳回一組強型別記錄。

[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.MessageContractAttribute(WrapperName="POLLINGSTMT", WrapperNamespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", IsWrapped=true)]  
public partial class POLLINGSTMT {  
  
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", Order=0)]  
    public microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD;  
  
    public POLLINGSTMT() {  
    }  
  
    public POLLINGSTMT(microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD) {  
        this.POLLINGSTMTRECORD = POLLINGSTMTRECORD;  
    }  
}  

資料合約命名空間

「資料合約」(Data Contract) 是服務與用戶端之間的正式合約,其中會抽象地描述要交換的資料。 也就是說,為了進行通訊,用戶端和服務不需要共用相同的類型,只有相同的資料合約。

如果是資料變更訊息,如果連線 URI 中指定的) ,PollingId 參數也會修改資料合約命名空間 (。 資料合約是由代表查詢結果集中強型別記錄的類別所組成。 在此範例中會省略類別定義的詳細資料。 類別包含屬性,這些屬性代表結果集中的資料行。

在下列範例中,會使用 PollingId 「AcctActivity」。

namespace microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity {  
    using System.Runtime.Serialization;  
  
    [System.Diagnostics.DebuggerStepThroughAttribute()]  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute(Name="POLLINGSTMTRECORD", Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity")]  
    public partial class POLLINGSTMTRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {…}  
     }  
}  

WCF 服務類別

[新增配接器服務參考外掛程式] 也會產生檔案,該檔案具有從服務合約 (介面) 實作之 WCF 服務類別的存根。 檔案名為 OracleDBBindingService.cs。 您可以將邏輯直接插入此類別來處理 POLLINGSTMT 作業。 如果您使用 svcutil.exe 來產生服務合約介面,則必須自行實作此類別。 下列程式碼顯示新增配接器服務參考外掛程式所產生的 WCF 服務類別。

namespace OracleDBBindingNamespace {  
  
    public class OracleDBBindingService : POLLINGSTMT_OperationGroup {  
  
        // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)   
        // of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)  
        public virtual void POLLINGSTMT(POLLINGSTMT request) {  
            throw new System.NotImplementedException("The method or operation is not implemented.");  
        }  
    }  
}  

接收 POLLINGSTMT 作業

從 Oracle 資料庫配接器接收輪詢資料

  1. 使用新增配接器服務參考外掛程式或 svcutil.exe,為 POLLINGSTMT 作業產生 WCF 服務合約 (介面) 和協助程式類別。 如需詳細資訊,請參閱 產生 ORACLE 資料庫解決方案成品的 WCF 用戶端或 WCF 服務合約。 連線到配接器時,您至少必須設定 PollingStatement 系結屬性。 您可以選擇性地在連線 URI 中指定 PollingId 參數。 如果您使用 [新增配接器服務參考外掛程式],您應該設定設定所需的所有系結參數。 這可確保它們已正確設定在產生的組態檔中。

  2. 從步驟 1 中產生的介面和協助程式類別實作 WCF 服務。 如果發生錯誤處理從 POLLINGSTMT 作業收到的資料,這個類別的 POLLINGSTMT 方法可能會擲回例外狀況以中止輪詢交易;否則方法不會傳回任何專案。 您必須屬性 WCF 服務類別,如下所示:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
    
    1. 如果您使用新增配接器服務參考外掛程式來產生介面,則可以直接在產生的OracleDBBindingService類別的POLLINGSTMT方法中實作邏輯。 您可以在 OracleDBBindingService.cs 中找到此類別。 此範例子類別中的這個程式碼是 OracleDBBindingService 類別。

      [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
      
      public class PollingStmtService : OracleDBBindingService  
      {  
          public override void POLLINGSTMT(POLLINGSTMT request)  
          {  
              Console.WriteLine("\nNew Polling Records Received");  
              Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");  
              for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++)  
              {  
                  Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID,  
                                      request.POLLINGSTMTRECORD[i].ACCOUNT,  
                                      request.POLLINGSTMTRECORD[i].AMOUNT,  
                                      request.POLLINGSTMTRECORD[i].TRANSDATE,  
                                      request.POLLINGSTMTRECORD[i].DESCRIPTION);  
              }  
          }  
      }  
      
    2. 如果您使用 svcutil.exe 來產生介面,您必須建立 WCF 服務來實作 介面,並在此類別的 POLLINGSTMT 方法中實作邏輯。

  3. 建立在步驟 2 中建立之 WCF 服務的實例。

    // create service instance  
    PollingStmtService pollingInstance = new PollingStmtService();  
    
  4. 使用 WCF 服務和基底連線 URI 建立 System.ServiceModel.ServiceHost 的實例。 基底連線 URI 不能包含 userinfoparams 或 query_string。

    // Enable service host  
    Uri[] baseUri = new Uri[] { new Uri("oracledb://Adapter") };  
    ServiceHost srvHost = new ServiceHost(pollingInstance, baseUri);  
    
  5. 建立 OracleDBBinding ,並設定其系結屬性來設定輪詢作業。 您可以在程式碼中明確執行此動作,或在組態中以宣告方式執行此動作。 您至少必須指定輪詢語句和輪詢間隔。 在此範例中,您會將認證指定為 URI 的一部分,因此您也必須將 AcceptCredentialsInUri 設定為 true

    // Create and configure a binding for the service endpoint. NOTE: binding  
    // parameters are set here for clarity, but these are already set in the  
    // the generated configuration file  
    OracleDBBinding binding = new OracleDBBinding();  
    
    // The credentials are included in the connection URI, so set this property to true  
    binding.AcceptCredentialsInUri = true;  
    
    // Same as statement specified in Configure Adapter dialog box  
    binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
    binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";  
    
    // Be sure to set the interval long enough to complete processing before  
    // the next poll  
    binding.PollingInterval = 15;  
    // Polling is transactional; be sure to set an adequate isolation level   
    // for your environment  
    binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;  
    
  6. 將服務端點新增至服務主機。 作法如下:

    • 使用步驟 5 中建立的系結。

    • 指定包含認證的連線 URI,並視需要指定 PollingId。

    • 將合約指定為 「POLLINGSTMT_OperationGroup」。

    // Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract  
    Uri serviceUri = new Uri("oracledb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity");  
    srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);  
    
  7. 若要接收輪詢資料,請開啟服務主機。 每當查詢傳回結果集時,配接器就會傳回資料。

    // Open the service host to begin polling  
    srvHost.Open();  
    
  8. 若要終止輪詢,請關閉服務主機。

    重要

    配接器會繼續輪詢,直到服務主機關閉為止。

    srvHost.Close();  
    

範例

下列範例顯示針對 /SCOTT/ACCOUNTACTIVITY 資料表執行的輪詢查詢。 輪詢後語句會叫用 Oracle 函式,將已處理的記錄移至另一個資料表 /SCOTT/ACCOUNTHISTORY。 POLLINGSTMT 作業的命名空間會藉由將連線 URI 中的 PollingId 參數設定為 「AccountActivity」 來修改。 在此範例中,POLLINGSTMT 作業的 WCF 服務是由產生的 OracleDBBindingService 類別子類別所建立;不過,您可以直接在產生的類別中實作邏輯。

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add these three references to use the Oracle adapter  
using System.ServiceModel;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
using microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity;  
using OracleDBBindingNamespace;  
  
namespace OraclePollingSM  
{  
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
  
    public class PollingStmtService : OracleDBBindingService  
    {  
        public override void POLLINGSTMT(POLLINGSTMT request)  
        {  
            Console.WriteLine("\nNew Polling Records Received");  
            Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");  
            for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++)  
            {  
                Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID,  
                                    request.POLLINGSTMTRECORD[i].ACCOUNT,  
                                    request.POLLINGSTMTRECORD[i].AMOUNT,  
                                    request.POLLINGSTMTRECORD[i].TRANSDATE,  
                                    request.POLLINGSTMTRECORD[i].DESCRIPTION);  
  
            }  
            Console.WriteLine("\nHit <RETURN> to stop polling");  
         }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            ServiceHost srvHost = null;  
  
            // This URI is used to specify the address for the ServiceEndpoint  
            // It must contain credentials and the PollingId (if any) that was used to generate  
            // the WCF service callback interface  
            Uri serviceUri = new Uri("OracleDb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity");  
  
            // This URI is used to initialize the ServiceHost. It cannot contain  
            // userinfoparms (credentials) or a query_string (PollingId); otherwise,  
            // an exception is thrown when the ServiceHost is initialized.  
            Uri[] baseUri = new Uri[] { new Uri("OracleDb://Adapter") };  
  
            Console.WriteLine("Sample started, initializing service host -- please wait");  
  
            // create an instanc of the WCF service callback class  
            PollingStmtService pollingInstance = new PollingStmtService();  
  
            try  
            {  
                // Create a ServiceHost with the service callback instance and a base URI (address)  
                srvHost = new ServiceHost(pollingInstance, baseUri);  
  
                // Create and configure a binding for the service endpoint. Note: binding  
                // parameters are set here for clarity but these are already set in the  
                // generated configuration file  
                //  
                // The following properties are set  
                //    AcceptCredentialsInUri (true) to enable credentials in the connection URI for AddServiceEndpoint  
                //    PollingStatement  
                //    PostPollStatement calls PROCESS_ACTIVITY on Oracle. This procedure moves the queried records to  
                //                      the ACCOUNTHISTORY table  
                //    PollingInterval (15 seconds)  
                //    TransactionIsolationLevel   
  
                OracleDBBinding binding = new OracleDBBinding();  
  
                // The Credentials are included in the Connection Uri so set this property true  
                binding.AcceptCredentialsInUri = true;  
  
                // Same as statement specified in Configure Adapter dialog box  
                binding.InboundOperationType = InboundOperation.Polling;  
                binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
                binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";  
  
                // Be sure to set the interval long enough to complete processing before  
                // the next poll  
                binding.PollingInterval = 15;  
  
                // Polling is transactional, be sure to set an adequate isolation level   
                // for your environment  
                binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;  
  
                // Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract  
                srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);  
  
                Console.WriteLine("Opening the service host");  
                // Open the service host to begin polling  
                srvHost.Open();  
  
                // Wait to receive request  
                Console.WriteLine("\nPolling started. Returned records will be written to the console.");  
                Console.WriteLine("Hit <RETURN> to stop polling");  
                Console.ReadLine();  
            }  
            catch (Exception e)  
            {  
                Console.WriteLine("Exception :" + e.Message);  
                Console.ReadLine();  
  
                /* If there is an Oracle Error it will be specified in the inner exception */  
                if (e.InnerException != null)  
                {  
                    Console.WriteLine("InnerException: " + e.InnerException.Message);  
                    Console.ReadLine();  
                }  
            }  
            finally  
            {  
                // IMPORTANT: you must close the ServiceHost to stop polling  
                if (srvHost.State == CommunicationState.Opened)  
                    srvHost.Close();  
                else  
                    srvHost.Abort();  
            }  
  
        }  
    }  
}  

另請參閱

使用 WCF 服務模型開發 Oracle 資料庫應用程式