WCF サービス モデルを使用して Oracle Database で REF CURSORS を使用して操作を実行する

REF CURSOR は、Oracle データベース内の結果セットへのポインターを表す Oracle PL/SQL データ型です。 Microsoft BizTalk Adapter for Oracle Database では、プロシージャ、関数、およびパッケージの REF CURSOR パラメーターがサポートされています。 REF CURSOR パラメーターは、プロシージャまたは関数での宣言方法に応じて、厳密に型指定することも、弱く型指定することもできます。 Oracle データベース アダプターで REF CURSOR パラメーターを表す方法の詳細については、「 REF CURSORS のメッセージ スキーマ」を参照してください。次の表は、WCF サービス モデルで REF CURSOR パラメーターがどのように表されるかをまとめたものです。

パラメーターの方向 厳密に型指定された REF CURSOR 弱く型指定された REF CURSOR
IN string [PARAM_NAME]

PL/SQL ブロックを含む文字列。 PL/SQL ブロックは、"OPEN FOR SELECT" ステートメントを実行するか、関数またはプロシージャを呼び出すことによって、開かれた REF CURSOR を返す必要があります。 疑問符 (?) は、パラメーターを返す REF CURSOR の位置を示します。 たとえば、"BEGIN OPEN ? FOR SELECT * FROM MY_TABLE;END"、または "BEGIN MY_PROC(PARM1, ?, PARM2);END;"
厳密に型指定されたのと同じ
OUT out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME]

厳密に型指定されたレコード セット。
out [GENERIC_NS].GenRecordRow[] [PARAM_NAME]

弱く型指定されたジェネリック レコード セット。
IN OUT IN OUT REF CURSOR パラメーターは、IN パラメーターと OUT パラメーターに分割されます。 IN パラメーターには、OUT パラメーターと区別するために、メソッド シグネチャに "_IN" が追加されます。 OUT パラメーターは、厳密に型指定されたレコード セットによって表されます。

string [PARAM_NAME]_IN

out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME]
IN OUT REF CURSOR パラメーターは、IN パラメーターと OUT パラメーターに分割されます。 IN パラメーターには、OUT パラメーターと区別するために、"_IN" が追加されます。 OUT パラメーターは、弱く型指定されたレコード セットによって表されます。

string [PARAM_NAME]_IN

out [GENERIC_NS].GenRecordRow[] [PARAM_NAME]

[PARAM_NAME] = Oracle データベースの関数またはプロシージャ定義のパラメーターの名前。たとえば、MYREFCURSOR です。

[PROC_NS] = パッケージ、プロシージャ、または関数のパラメーターを格納するために生成される一意の名前空間。たとえば、"microsoft.lobservices.oracledb._2007._03.SCOTT。Package.ACCOUNT_PKG。GET_ACTIVITY"。

[GENERIC_NS] = ジェネリック レコード セットが定義されている名前空間 、"microsoft.lobservices.oracledb._2007._03" です。

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

このトピックの例では、/SCOTT/Package/ACCOUNT_PKG Oracle PACKAGE を使用します。 ACCOUNT_PKGから次の手順を使用します。

PROCEDURE get_activity(inrecs IN SYS_REFCURSOR, status OUT NUMBER, inoutrecs IN OUT activity_ref_type, outrecs OUT SYS_REFCURSOR);  

このパッケージを生成するスクリプトは、SDK サンプルと共に提供されます。 SDK サンプルの詳細については、「SDK のサンプル」を参照してください。

WCF サービス モデルの REF CURSOR パラメーター

次の例では、/SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY プロシージャ用に生成されたクラスと WCF クライアントを示します。 このプロシージャには、弱く型指定された IN および OUT REF CURSOR パラメーターと、厳密に型指定された IN OUT REF CURSOR パラメーターがあります。

GET_ACTIVITYを呼び出すために WCF クライアントで生成されるメソッドのシグネチャを次に示します。

public System.Nullable<decimal> GET_ACTIVITY(string INRECS, string INOUTRECS_IN, out microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY.INOUTRECSRECORD[] INOUTRECS, out microsoft.lobservices.oracledb._2007._03.GenRecordRow[] OUTRECS);  

GET_ACTIVITY メソッドでは、IN OUT パラメーター INOUTRECS は 2 つのパラメーターに分割されます。

  • INOUTRECS_INは、IN REF CURSOR パラメーターを表す文字列です。

  • INOUTRECS は、OUT REF CURSOR パラメーターを表す厳密に型指定されたレコード セットです。

    弱く型指定された OUT パラメーター OUTRECS は、汎用レコード セットとして表されます。 弱く型指定された IN パラメーター INRECS は、文字列として表されます。

OUT REF CURSOR パラメーターの Strongly-Typed

厳密に型指定された OUT (または IN OUT) REF CURSOR パラメーターは、SCHEMA、PACKAGE、およびそれらが使用されるプロシージャまたは関数の名前に基づいて、一意の名前空間で生成されます。 /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY プロシージャの場合、この名前空間は です microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY。 クラス名は、パラメーターの名前に "RECORD" を付加して形成され、クラスは Oracle フィールドを表すプロパティで構成されます。 INOUTRECS REF CURSOR パラメーターに対して生成される厳密に型指定されたレコードを表す クラスの一部を次に示します。

namespace microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY {  
    using System.Runtime.Serialization;  
  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute()]  
    public partial class INOUTRECSRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {  
  
        ...  
  
        private System.Nullable<decimal> TIDField;  
  
        ...  
  
        [System.Runtime.Serialization.DataMemberAttribute()]  
        public System.Nullable<decimal> TID {  
            get {  
                return this.TIDField;  
            }  
            set {  
                this.TIDField = value;  
            }  
        }  
  
        ...  
  
    }  
}  

OUT REF CURSOR パラメーターの Weakly-Typed

弱く型指定された OUT (または IN OUT) REF CURSOR パラメーターは、ジェネリック レコード クラスによって表されます。 ジェネリック レコード セットは、関数またはプロシージャに関係なく、常に同じ名前空間と同じクラス名で生成されます。 次のコードは、OUTRECS OUT SYS_REFCURSOR パラメーター (弱く型指定) のレコードを表す汎用レコード クラス microsoft.lobservices.oracledb._2007 ._03.GenRecordRow を示しています。

namespace microsoft.lobservices.oracledb._2007._03 {  
    using System.Runtime.Serialization;  
  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute()]  
    public partial class GenRecordRow : object, System.Runtime.Serialization.IExtensibleDataObject {  
  
        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;  
  
        private microsoft.lobservices.oracledb._2007._03.GenRecordColumn[] GenRecordColumnField;  
  
        public System.Runtime.Serialization.ExtensionDataObject ExtensionData {  
            get {  
                return this.extensionDataField;  
            }  
            set {  
                this.extensionDataField = value;  
            }  
        }  
  
        [System.Runtime.Serialization.DataMemberAttribute()]  
        public microsoft.lobservices.oracledb._2007._03.GenRecordColumn[] GenRecordColumn {  
            get {  
                return this.GenRecordColumnField;  
            }  
            set {  
                this.GenRecordColumnField = value;  
            }  
        }  
    }  
  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute()]  
    public partial class GenRecordColumn : object, System.Runtime.Serialization.IExtensibleDataObject {  
  
        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;  
  
        private string ColumnNameField;  
  
        private string ColumnValueField;  
  
        private string ColumnTypeField;  
  
        public System.Runtime.Serialization.ExtensionDataObject ExtensionData {  
            get {  
                return this.extensionDataField;  
            }  
            set {  
                this.extensionDataField = value;  
            }  
        }  
  
        [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false)]  
        public string ColumnName {  
            get {  
                return this.ColumnNameField;  
            }  
            set {  
                this.ColumnNameField = value;  
            }  
        }  
  
        [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]  
        public string ColumnValue {  
            get {  
                return this.ColumnValueField;  
            }  
            set {  
                this.ColumnValueField = value;  
            }  
        }  
  
        [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false, Order=2)]  
        public string ColumnType {  
            get {  
                return this.ColumnTypeField;  
            }  
            set {  
                this.ColumnTypeField = value;  
            }  
        }  
    }  
}  

WCF クライアントでの REF CURSOR パラメーターの使用

WCF クライアントを使用して REF CURSOR パラメーターを使用してプロシージャまたは関数を呼び出すには、次の操作を行います。

  1. PL/SQL ブロックを含む IN パラメーターまたは IN OUT REF CURSOR パラメーターごとに文字列を渡して、REF CURSOR を開きます。 このブロックは、OPEN FOR SELECT ステートメントを実行するか、OUT パラメーターで開かれた REF CURSOR を返す関数またはプロシージャを呼び出すことができます。

  2. プロシージャまたは関数が戻るときに、OUT または IN OUT REF CURSOR パラメーターに対して返されるレコード セット内のデータを操作します。 レコード セットは、弱く型指定された REF CURSOR パラメーターの場合は汎用レコード セット、厳密に型指定された REF CURSOR パラメーターの場合は厳密に型指定されたレコード セットになります。

    WCF サービス モデルを使用してプロシージャと関数を呼び出す方法の詳細については、「WCF サービス モデルを使用して Oracle Database で関数とプロシージャを呼び出す」を参照してください。

    次の例では、GET_ACTIVITY プロシージャを呼び出します。 IN REF CURSOR パラメーターを指定する両方の方法を示します。

  • IN REF CURSOR パラメーターの場合は、ACCOUNT 100001のアクティビティを返すために OPEN FOR SELECT ステートメントが指定されます。

  • IN OUT REF CURSOR パラメーターの場合は、/SCOTT/Package/ACCOUNT_PKG/GET_ALL_ACTIVITY プロシージャが呼び出されます。 このプロシージャは、ACCOUNTACTIVITY テーブル内のすべてのアクティビティを含む REF CURSOR を開き、OUT パラメーターとして返します。

    この例では、厳密に型指定された REF CURSOR パラメーターと弱く型指定された REF CURSOR パラメーターの両方に対して返されるレコード セットからデータを読み取る方法も示します。

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add WCF, WCF LOB Adapter SDK, and Oracle Database adapter namepaces  
using System.ServiceModel;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
// Include this namespace for WCF LOB Adapter SDK and Oracle Database adapter exceptions  
using Microsoft.ServiceModel.Channels.Common;  
  
// namespaces for strongly-typed and weakly typed REF CURSOR records  
using GET_ACTIVITYns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY;  
using GENERICns = microsoft.lobservices.oracledb._2007._03;  
  
// In this sample, INRECS is opened by using an OPEN FOR statement, and  
// INOUTRECS_IN is opened by calling the GET_ALL_ACTIVITY procedure on Oracle.  
  
namespace OracleRefCursorsSM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            // Create the client  
            SCOTTPackageACCOUNT_PKGClient accountPkgClient =   
                new SCOTTPackageACCOUNT_PKGClient("OracleDBBinding_SCOTT.Package.ACCOUNT_PKG");  
            // Set credentials  
            accountPkgClient.ClientCredentials.UserName.UserName = "SCOTT";  
            accountPkgClient.ClientCredentials.UserName.Password = "TIGER";  
  
            try  
            {  
  
                GET_ACTIVITYns.INOUTRECSRECORD[] strongCursor;  
                GENERICns.GenRecordRow[] weakCursor;  
  
                Console.WriteLine("Opening client");  
                // Open the client  
                accountPkgClient.Open();  
  
                Console.WriteLine("Invoking ACCOUNT_PKG.GET_ACTIVITY");  
                // Get  ACCOUNTACTIVITY records  
                // The IN REF CURSOR is set to all activity for account 100001  
                // The input part of the IN OUT ref cursor calls GET_ALL_ACTIVITY  
                // The weakly-typed OUT REF CURSOR parameter returns a list of activity for account 100001  
                // The strongly-typed IN OUT REF CURSOR parameter returns a list of all activity  
                string inRecsString = "BEGIN OPEN ? FOR SELECT * FROM ACCOUNTACTIVITY WHERE ACCOUNT=100001; END;";  
                string inoutRecsString = "BEGIN ACCOUNT_PKG.GET_ALL_ACTIVITY(?); END;";  
  
                accountPkgClient.GET_ACTIVITY(  
                                inRecsString,  
                                inoutRecsString,  
                                out strongCursor,  
                                out weakCursor);  
  
                // Display strong ref cursor (all activity)  
                Console.WriteLine("\nList of all activity returned (strong ref cursor)");  
                Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");  
                for (int i = 0; i < strongCursor.Length; i++)  
                {  
                    Console.WriteLine("{0}\t{1}\t{2:C}\t{3}\t{4}",strongCursor[i].TID,  
                        strongCursor[i].ACCOUNT,   
                        strongCursor[i].AMOUNT,   
                        strongCursor[1].TRANSDATE,  
                        strongCursor[i].DESCRIPTION);  
                }  
  
                // Display weak ref cursor (account 100001)  
                Console.WriteLine("\nList of activity for account 100001 returned (weak ref cursor)");  
                Console.WriteLine("Tx Id\tAmount\tDate\t\t\tDescription");  
                for (int i = 0; i < weakCursor.Length; i++)  
                {  
                    Console.WriteLine("{0}\t{1:C}\t{2}\t{3}", weakCursor[i].GenRecordColumn[0].ColumnValue,  
                        weakCursor[i].GenRecordColumn[2].ColumnValue,  
                        weakCursor[i].GenRecordColumn[4].ColumnValue,  
                        weakCursor[i].GenRecordColumn[3].ColumnValue);  
                }  
  
                Console.WriteLine("\nHit <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 the client  
                accountPkgClient.Close();  
            }  
        }  
    }  
}  

参照

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