WCF サービス モデルを使用して Oracle Database の関数とプロシージャを呼び出す

Microsoft BizTalk Adapter for Oracle Database では、プロシージャ、関数、およびパッケージが操作として表示されます。 WCF サービス モデルでは、これらの操作は WCF クライアントのメソッドとして表されます。 WCF サービス モデルと Oracle データベース アダプター:

  • サポート関数。 Oracle 関数の RETURN 値は、WCF クライアント メソッドの戻り値として表示されます。 Oracle パラメーターは、WCF クライアント メソッドに対してパラメーター (以下で定義されている適切な方向) として表示されます。

  • サポート手順。 Oracle プロシージャの最初の OUT パラメーターは、WCF クライアント メソッドの戻り値として表示されます。 その他のすべての Oracle パラメーターは、WCF クライアント メソッドに対してパラメーターとして表示されます (以下に定義されている適切な方向)。

  • Oracle パッケージをサポートします。 操作の名前とそのパラメーター型の名前空間は、パッケージ名で修飾されます。

  • オーバーロードされた関数とプロシージャをサポートします

  • プロシージャと関数の両方で、基本的な Oracle データ型の IN、OUT、および IN OUT パラメーターをサポートします。 OUT パラメーターは WCF クライアント メソッドで out パラメーターとして表示され、IN OUT パラメーターは ref パラメーターとして表示されます。

  • プロシージャと関数、および関数 RETURN 値に対して IN、OUT、および IN OUT REF CURSOR パラメーターをサポートします。 詳細については、「 WCF サービス モデルを使用した Oracle Database での REF CURSORS を使用した操作の実行」を参照してください。

  • プロシージャと関数の IN、OUT、および IN OUT RECORD 型パラメーター、および関数 RETURN 値をサポートします。 詳細については、「 WCF サービス モデルを使用した Oracle データベースでの RECORD 型を使用した操作の実行」を参照してください。

このトピックで使用する例について

このトピックの例では、/SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNTオーバーロードされたプロシージャを使用します。 この手順では、アカウント ID またはアカウント名に基づいて、SCOTT/ACCOUNT テーブルからレコードを読み取ります。 このプロシージャとテーブルを生成するスクリプトは、SDK サンプルと共に提供されています。 SDK サンプルの詳細については、「SDK のサンプル」を参照してください。

WCF クライアント クラス

次の表は、WCF クライアントの名前と、Oracle Database アダプターが表示するプロシージャ、関数、パッケージに対して生成されるメソッドを示しています。 関数またはプロシージャがオーバーロードされていない限り、単一の WCF クライアントを使用して、スキーマ内のすべての関数、スキーマ内のすべてのプロシージャ、またはパッケージ内のすべての関数とプロシージャを呼び出します。

Oracle Artifact WCF クライアント操作名
手順 [SCHEMA]ProcedureClient。[PROC_NAME] SCOTTProcedureClient.MYPROC
機能 [SCHEMA]FunctionClient。[FUNC_NAME] SCOTTProcedureClient.MYFUNC
パッケージ (プロシージャまたは関数) [SCHEMA]Package[PACKAGE_NAME]Client。[PROC_NAMEまたはFUNC_NAME] SCOTTPackageMYPACKAGEClient.MYPROC

[SCHEMA] = Oracle 成果物のコレクション。たとえば、SCOTT です。

[PROC_NAME] = Oracle プロシージャの名前。たとえば、MYPROC です。

[FUNC_NAME] = Oracle 関数の名前。たとえば、MYFUNC です。

[PACKAGE_NAME] = Oracle パッケージの名前。

Oracle Database アダプターは、Oracle RECORD 型パラメーターと戻り値、および REF CURSOR パラメーターによって返される結果セットを、Oracle レコードの行データ (またはフィールド) を含む複合 XML 型として表します。 WCF サービス モデルでは、これらの各 XML 型は .NET クラスとして表されます。クラスのプロパティは、RECORD 型または REF CURSOR 結果セットのフィールドを表します。 Oracle RECORD 型は、常に厳密に型指定された .NET クラスとして表されます。 ただし、REF CURSOR 結果セットは、REF CURSOR 自体が厳密に型指定されているか弱く型指定されているかに基づいて、厳密に型指定されたレコードまたは弱く型指定されたレコードとして表すことができます。 REF CURSOR 型パラメーターまたは RECORD 型パラメーター (または戻り値) を表すクラスは、プロシージャ、関数、またはパッケージに基づいて一意の名前空間で生成されます。 次の表に、これらの名前空間を示します。

Oracle Artifact 名前空間
手順 [BASE_NS]。 [SCHEMA].手順。[PROC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Procedure.MYPROC
機能 [BASE_NS]。 [SCHEMA].関数。[FUNC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Function.MYFUNC
パッケージ (プロシージャ) [BASE_NS]。 [SCHEMA].パッケージ。[PACKAGE_NAME]。[PROC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYPROC
パッケージ (関数) [BASE_NS]。 [SCHEMA].パッケージ。[PACKAGE_NAME]。[FUNC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYFUNC
ジェネリック レコード セット (弱く型指定) [BASE_NS] microsoft.lobservices.oracledb._2007._03

[BASE_NS] = 基本アダプターの名前空間。microsoft.lobservices.oracledb._2007._03。

[SCHEMA] = Oracle 成果物のコレクション。たとえば、SCOTT です。

[PROC_NAME] = Oracle プロシージャの名前。例えば;MYPROC。

[FUNC_NAME] = Oracle 関数の名前。たとえば、MYFUNC です。

[PACKAGE_NAME] = Oracle パッケージの名前。

RECORD パラメーターにこれらの名前空間を使用する方法については、「 WCF サービス モデルを使用した Oracle Database での RECORD 型を使用した操作の実行」を参照してください。 REF CURSOR パラメーターにこれらの名前空間を使用する方法の詳細については、「 WCF サービス モデルを使用した Oracle Database での REF CURSORS を使用した操作の実行」を参照してください。

一般に、Oracle パラメーターと戻り値は、WCF クライアント メソッドで次のようにマップされます。

  • Oracle IN パラメーターは、.NET (入力) パラメーターにマップされます。

  • Oracle OUT パラメーターは、.NET out パラメーターにマップされます。

  • Oracle IN OUT パラメーターは、.NET ref パラメーターにマップされます。

  • 関数 RETURN 値は、メソッドの戻り値にマップされます。

    ただし、次の 2 つの重要な例外があります。

  • Oracle IN OUT REF CURSOR パラメーターは、入力文字列と出力 (出力) レコード セットに分割されます。 これは、Oracle Database アダプターが IN REF CUSROR パラメーターを文字列として表し、OUT REF CURSOR パラメーターを複合型 (レコード セット) として表しているためです。これらは 1 つのパラメーターに結合できません。

  • Oracle プロシージャの最初の OUT パラメーターは、WCF クライアント メソッドの戻り値にマップされます。 これは標準的な WCF 動作です。

    次の例は、単純な Oracle プロシージャ (SCOTT スキーマに読み込まれる) と、それを呼び出すために生成される WCF クライアント メソッドのシグネチャの一部を示しています。 Oracle プロシージャには、3 つの IN パラメーター、3 つの IN OUT パラメーター、および 3 つの OUT パラメーターがあります。ただし、WCF クライアント メソッドでは、最初の OUT パラメーターのパラメーターはマップされません。 代わりに、メソッドの戻り値にマップされます。

CREATE or REPLACE PROCEDURE Sample_Procedure   
    (  
     INNUMBER      IN         NUMBER,  
     INVARCHAR     IN         VARCHAR2,  
     INDATE        IN         DATE,  
     INOUTNUMBER   IN OUT     NUMBER,  
     INOUTVARCHAR  IN OUT     VARCHAR,  
     INOUTDATE     IN OUT     DATE,  
     OUTNUMBER     OUT        NUMBER,  
     OUTVARCHAR    OUT        VARCHAR2,  
     OUTDATE       OUT        DATE  
    ) AS   
    BEGIN  
  
        ...  
  
    END;  
    /  
  
[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
public partial class SCOTTProcedureClient : System.ServiceModel.ClientBase<SCOTTProcedure>, SCOTTProcedure {  
  
    public System.Nullable<decimal> SAMPLE_PROCEDURE  
       (  
        System.Nullable<decimal> INNUMBER,   
        string INVARCHAR,   
        System.Nullable\<System.DateTime\> INDATE,   
        ref System.Nullable<decimal> INOUTNUMBER,   
        ref string INOUTVARCHAR,   
        ref System.Nullable\<System.DateTime\> INOUTDATE,   
        out string OUTVARCHAR,   
        out System.Nullable\<System.DateTime\> OUTDATE  
        );  
}  

オーバーロードされたプロシージャ、関数、パッケージのサポート

Oracle Database アダプターは、オーバーロードされた各成果物に対して表示されるノード ID と名前空間に一意の文字列を追加することで、オーバーロードされたプロシージャ、関数、およびパッケージをサポートします。 この文字列は、最初のオーバーロードの場合は "overload1"、次のオーバーロードの場合は "overload2" です。

WCF サービス モデルでは、オーバーロードされた各プロシージャまたは関数は、一意の WCF クライアントによって表されます。 これは、SCHEMA 内のすべての関数、SCHEMA 内のすべてのプロシージャ、または PACKAGE 内のすべてのプロシージャと関数が同じ WCF クライアントによって呼び出される、オーバーロードされていない場合とは異なります。 次の表は、オーバーロードされたプロシージャ、関数、パッケージに対して生成された WCF クライアント名とメソッドを示しています。

Oracle Artifact WCF クライアント名
オーバーロードされたパッケージ (プロシージャ) [SCHEMA]Package[PACKAGE_NAME][PROC_NAME] ][OVERLOAD_ID]Client。[PROC_NAME] SCOTTPackageMYPACKAGEMYPROCoverload1Client.MYPROC
オーバーロードされたパッケージ (関数) [SCHEMA]Package[PACKAGE_NAME][FUNC_NAME] ][OVERLOAD_ID]クライアント。[FUNC_NAME] SCOTTPackageMYPACKAGEMYFUNCoverload1Client.MYFUNC

[SCHEMA] = Oracle 成果物のコレクション。たとえば、SCOTT です。

[PROC_NAME] = Oracle プロシージャの名前。例えば;MYPROC。

[FUNC_NAME] = Oracle 関数の名前。たとえば、MYFUNC です。

[PACKAGE_NAME] = Oracle パッケージの名前。

[OVERLOAD_ID] = オーバーロードされた成果物を識別する一意の文字列。"overload1"、"overload2"など。

次の表は、オーバーロードされたプロシージャ、関数、およびパッケージに対して生成される名前空間を示しています。

Oracle Artifact 名前空間
パッケージ (プロシージャ) [BASE_NS]。 [SCHEMA].パッケージ。[PACKAGE_NAME]。[PROC_NAME][OVERLOAD_ID] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYPROC.overload1
パッケージ (関数) [BASE_NS]。 [SCHEMA].パッケージ。[PACKAGE_NAME]。[FUNC_NAME]。[OVERLOAD_ID] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYFUNC.overload1
ジェネリック レコード セット (弱く型指定) [BASE_NS] microsoft.lobservices.oracledb._2007._03

[BASE_NS] = 基本アダプターの名前空間。microsoft.lobservices.oracledb._2007._03。

[SCHEMA] = Oracle 成果物のコレクション。たとえば、SCOTT です。

[PROC_NAME] = Oracle プロシージャの名前。例えば;MYPROC。

[FUNC_NAME] = Oracle 関数の名前。たとえば、MYFUNC です。

[PACKAGE_NAME] = Oracle パッケージの名前。

[OVERLOAD_ID] = オーバーロードされた成果物を識別する一意の文字列。"overload1"、"overload2"など。 文字列の数値は、Oracle データベースによって管理される成果物のオーバーロード ID です。

次の例は、ACCOUNT_PKG パッケージ内のオーバーロードされたGET_ACCOUNT プロシージャに対して生成された WCF クライアントとメソッド シグネチャを示しています。 (Oracle 宣言が含まれています)。この例では、各オーバーロードに対して一意の WCF クライアントを生成する方法と、クライアントごとに生成されたメソッドが一意の名前空間でレコード セットを返す方法を示します。

/* Procedure that takes account ID and returns record for existing account in the ACCOUNT table */  
PROCEDURE get_account(aid IN account.acctid%TYPE, acct OUT account%ROWTYPE) ;  
  
/* Procedure that takes account name and returns record for existing account in the ACCOUNT table */  
PROCEDURE get_account(aname IN account.name%TYPE, acct OUT account%ROWTYPE) ;  
  
[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
public partial class SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1Client : System.ServiceModel.ClientBase<SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1>, SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1 {  
  
    public microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload1.ACCTRECORD GET_ACCOUNT(System.Nullable<decimal> AID);  
}  
  
[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
public partial class SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2Client : System.ServiceModel.ClientBase<SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2>, SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2 {  
  
    public microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload2.ACCTRECORD GET_ACCOUNT(string ANAME);  
}  

関数とプロシージャの呼び出し

WCF クライアントを使用して関数またはプロシージャを呼び出すには、次の手順を実行します。

  1. 対象の関数、プロシージャ、またはパッケージの WCF クライアント クラスを生成します。 このクラスには、ターゲット成果物で呼び出す操作のメソッドを含める必要があります。

    Note

    [アダプター サービス参照の追加] Visual Studio プラグインでは、オーバーロードされた関数とプロシージャが [ 使用可能なカテゴリと操作 ] ボックスに [NAME].1、[NAME].2、[NAME].3 などとして表示されます。ここで、[NAME] はオーバーロードされた成果物の名前で、数値は Oracle データベースのオーバーロード ID です。

  2. WCF クライアント クラスのインスタンスを作成し、そのメソッドを呼び出して関数またはプロシージャを呼び出します。

    ORACLE データベース アダプターで WCF クライアント クラスを作成し、操作を呼び出す方法の詳細については、「Oracle データベース アダプターを使用 した WCF サービス モデルの概要」を参照してください。

    Oracle データベース アダプターは、Oracle データベースのトランザクション内で各操作を実行します。

重要

REF CURSOR および RECORD 型パラメーターを表すクラス、または関数またはプロシージャ (およびパッケージ) の値を返すクラスは、関数またはプロシージャごとに一意の名前空間で宣言されます。 つまり、たとえば、2 つの異なる関数の戻り値として使用される PACKAGE REF CURSOR 型は、各 WCF クライアント メソッドの一意の名前空間で宣言されます。 これらの異なる戻り値を保持するために個別の変数を宣言するか、WCF クライアント メソッドのいずれかを呼び出すときに変数を適切にキャストする必要があります。

次の例では、オーバーロードされた /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT プロシージャを呼び出して、/SCOTT/ACCOUNT テーブルからアカウント レコードを取得する方法を示します。 まず、/SCOTT/Package/ACCOUNT_PKG/CREATE_ACCOUNT プロシージャを呼び出して、新しいレコードを作成します。 その後、GET_ACCOUNTのさまざまなオーバーロードを呼び出すことによって、新しいレコードが 2 回読み取られます。 この例では、3 つの WCF クライアントを使用します。1 つは CREATE_ACCOUNT プロシージャ用、もう 1 つは GET_ACCOUNT オーバーロード用です。 エイリアスは、GET_ACCOUNTの戻り値に使用される名前空間を区別するために使用されます。 完全なサンプルは、SDK のサンプルで入手できます。 SDK サンプルの詳細については、「SDK のサンプル」を参照してください。

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add WCF, WCF Adapter LOB SDK, and Oracle Database adapter namepaces  
using System.ServiceModel;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
// Include this namespace for WCF Adapter LOB SDK and Oracle Database adapter exceptions  
using Microsoft.ServiceModel.Channels.Common;  
  
// Alias client namespaces to shorten declarations of "shared" types   
using CREATE_ACCOUNTns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT;  
using GET_ACCOUNT_BY_IDns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload1;  
using GET_ACCOUNT_BY_NAMEns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload2;  
  
// This sample demonstrates calling overloaded packaged procedures on Oracle  
// First a new account is created by calling CREATE_ACCOUNT which takes two record parameters  
// Then the information for the new account is returned by calling an overloaded procedure GET_ACCOUNT  
// The first overload returns the account information by account ID  
// The second overload returns the account information by account name  
// Notice that different clients (and namespaces) are created for overloaded procedures and functions  
namespace OracleOverloadsSM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            decimal acctId;  
            string newAccountName = "Paula Bento";  
  
            Console.WriteLine("Creating clients");  
            // Create Client for CREATE_ACCOUNT Function  
            SCOTTPackageACCOUNT_PKGClient createAccountClient =   
                new SCOTTPackageACCOUNT_PKGClient("OracleDBBinding_SCOTT.Package.ACCOUNT_PKG");  
            // NOTE: user name and password are case-sensitive  
            createAccountClient.ClientCredentials.UserName.UserName = "SCOTT";  
            createAccountClient.ClientCredentials.UserName.Password = "TIGER";  
  
            // Create Client for GET_ACCOUNT Overload 1 -- takes ACCOUNT ID parameter  
            SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1Client getAccountByIdClient =   
                new SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1Client("OracleDBBinding_SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload1");  
            // NOTE: user name and password are case-sensitive  
            getAccountByIdClient.ClientCredentials.UserName.UserName = "SCOTT";  
            getAccountByIdClient.ClientCredentials.UserName.Password = "TIGER";  
  
            // Create Client for GET_ACCOUNT Overload 2 -- takes ACCOUNT NAME parameter  
            // NOTE: this client can be created from configuration; detail provided here  
            // for demonstration  
            OracleDBBinding overload2Binding = new OracleDBBinding();  
            EndpointAddress overload2EndpointAddress = new EndpointAddress("oracleDB://ADAPTER");  
            SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2Client getAccountByNameClient =   
                new SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2Client(overload2Binding, overload2EndpointAddress);  
            // NOTE: user name and password are case-sensitive  
            getAccountByNameClient.ClientCredentials.UserName.UserName = "SCOTT";  
            getAccountByNameClient.ClientCredentials.UserName.Password = "TIGER";  
  
            try  
            {  
                Console.WriteLine("Opening clients -- please wait");  
                // Open clients  
                createAccountClient.Open();  
                getAccountByIdClient.Open();  
                getAccountByNameClient.Open();  
  
                Console.WriteLine("Creating new account");  
                // Create an account record  
                // NOTE: ACCTRECORD is defined in all three namespaces so specify the definition  
                // that corresponds to the client.  
                CREATE_ACCOUNTns.ACCTRECORD acctRec = new CREATE_ACCOUNTns.ACCTRECORD();  
  
                // Set any value for ACCTID -- new account ID is returned by CREATE_ACCOUNT  
                acctRec.ACCTID = 0;  
                acctRec.NAME = newAccountName;  
                acctRec.BALANCE = 10537;  
  
                // Create address record  
                CREATE_ACCOUNTns.ACCOUNT_PKGADDRESS_REC_TYPERECORD addrRec = new CREATE_ACCOUNTns.ACCOUNT_PKGADDRESS_REC_TYPERECORD();  
                addrRec.STREET = "456 Valley Rd";  
                addrRec.CITY = "New York";  
                addrRec.STATE = "NY";  
  
                // Create account  
                acctId = (decimal)createAccountClient.CREATE_ACCOUNT(acctRec, addrRec);  
                Console.WriteLine("New Account Created: AccountId = {0}, Name = {1}, Balance = {2:C}",  
                   acctId, acctRec.NAME, acctRec.BALANCE);  
  
                /* Get new account by Id */  
                GET_ACCOUNT_BY_IDns.ACCTRECORD acctById = getAccountByIdClient.GET_ACCOUNT(acctId);  
                Console.WriteLine("Account Returned by Id: AccountId={0}, Name={1}, Balance={2:C}",  
                    acctById.ACCTID, acctById.NAME, acctById.BALANCE);  
  
                /* Get new account by Name */  
                GET_ACCOUNT_BY_NAMEns.ACCTRECORD acctByName = getAccountByNameClient.GET_ACCOUNT(newAccountName);  
                Console.WriteLine("Account Returned by Name: AccountId={0}, Name={1}, Balance={2:C}",  
                    acctByName.ACCTID, acctByName.NAME, acctByName.BALANCE);  
  
                Console.WriteLine("Hit <RETURN> to finish");  
                Console.ReadLine();  
            }  
            catch (TargetSystemException tex)  
            {  
                Console.WriteLine("Exception occurred on the Oracle Database");  
                Console.WriteLine(tex.InnerException.Message);  
            }  
            catch (ConnectionException cex)  
            {  
                Console.WriteLine("Exception occurred connecting to the Oracle Database");  
                Console.WriteLine(cex.InnerException.Message);  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine("Exception is: " + ex.Message);  
                if (ex.InnerException != null)  
                {  
                    Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);  
                }  
                throw ex;  
            }  
            finally  
            {  
                // Close all the clients  
                createAccountClient.Close();  
                getAccountByIdClient.Close();  
                getAccountByNameClient.Close();  
            }  
  
        }  
    }  
}  

参照

WCF サービス モデルを使用した Oracle データベース アプリケーションの開発