Freigeben über


Ausführen von Vorgängen mithilfe von REF CURSORS in Oracle Database mithilfe des WCF-Dienstmodells

Ein REF CURSOR ist ein Oracle PL/SQL-Datentyp, der einen Zeiger auf ein Resultset in der Oracle-Datenbank darstellt. Der Microsoft BizTalk-Adapter für Oracle-Datenbank unterstützt REF CURSOR-Parameter in Prozeduren, Funktionen und Paketen. REF CURSOR-Parameter können stark typisiert oder schwach typisiert sein, je nachdem, wie sie in der Prozedur oder Funktion deklariert werden. Eine ausführliche Erläuterung der Darstellung von REF CURSOR-Parametern durch den Oracle Database-Adapter finden Sie unter Meldungsschemas für REF CURSORS. In der folgenden Tabelle wird zusammengefasst, wie REF CURSOR-Parameter im WCF-Dienstmodell dargestellt werden.

Parameterrichtung Stark typisierter REF CURSOR Schwach typisierter REF CURSOR
IN string [PARAM_NAME]

Zeichenfolge, die einen PL/SQL-Block enthält. Der PL/SQL-Block muss einen geöffneten REF CURSOR entweder durch Ausführen einer "OPEN FOR SELECT"-Anweisung oder durch Aufrufen einer Funktion oder Prozedur zurückgeben. Ein Fragezeichen (?) gibt die Position des REF CURSOR an, der den Parameter zurückgibt. Beispiel: "BEGIN OPEN ? FOR SELECT * FROM MY_TABLE; END" oder "BEGIN MY_PROC(PARM1, ?, PARM2); END;".
Identisch mit stark typisiert
OUT out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME]

Ein stark typisierter Datensatzsatz.
out [GENERIC_NS].GenRecordRow[] [PARAM_NAME]

Ein schwach typisierter generischer Datensatzsatz.
IN OUT IN OUT REF CURSOR-Parameter werden in einen IN- und einen OUT-Parameter aufgeteilt. Der IN-Parameter wird mit "_IN" in der Methodensignatur angefügt, um ihn vom OUT-Parameter zu unterscheiden. Der OUT-Parameter wird durch einen stark typisierten Datensatzsatz dargestellt.

string [PARAM_NAME]_IN

out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME]
IN OUT REF CURSOR-Parameter werden in einen IN- und einen OUT-Parameter aufgeteilt. Der IN-Parameter wird mit "_IN" angefügt, um ihn vom OUT-Parameter zu unterscheiden. Der OUT-Parameter wird durch einen schwach typisierten Datensatzsatz dargestellt.

string [PARAM_NAME]_IN

out [GENERIC_NS].GenRecordRow[] [PARAM_NAME]

[PARAM_NAME] = der Name des Parameters in der Funktions- oder Prozedurdefinition für die Oracle-Datenbank; z. B. MYREFCURSOR.

[PROC_NS] = Der eindeutige Namespace, der generiert wird, um Parameter des Pakets, der Prozedur oder der Funktion zu enthalten; beispiel: "microsoft.lobservices.oracledb._2007._03.SCOTT. Package.ACCOUNT_PKG. GET_ACTIVITY".

[GENERIC_NS] = Der Namespace, in dem der generische Datensatzsatz definiert ist, "microsoft.lobservices.oracledb._2007._03".

Informationen zu den in diesem Thema verwendeten Beispielen

In den Beispielen in diesem Thema wird das Oracle-PAKET /SCOTT/Package/ACCOUNT_PKG verwendet. Das folgende Verfahren wird von ACCOUNT_PKG verwendet:

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

Ein Skript zum Generieren dieses Pakets wird mit den SDK-Beispielen bereitgestellt. Weitere Informationen zu den SDK-Beispielen finden Sie unter Beispiele im SDK.

REF CURSOR-Parameter im WCF-Dienstmodell

Die folgenden Beispiele zeigen die Klassen und den WCF-Client, die für die Prozedur /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY generiert wurden. Diese Prozedur verfügt über schwach typisierte IN- und OUT REF CURSOR-Parameter und einen stark typisierten IN OUT REF CURSOR-Parameter.

Hier ist die Signatur der Methode, die im WCF-Client generiert wird, um GET_ACTIVITY aufzurufen.

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);  

In der GET_ACTIVITY-Methode wird der IN OUT-Parameter INOUTRECS in zwei Parameter unterteilt:

  • INOUTRECS_IN ist eine Zeichenfolge, die einen IN REF CURSOR-Parameter darstellt.

  • INOUTRECS ist ein stark typisierter Datensatzsatz, der einen OUT REF CURSOR-Parameter darstellt.

    Der schwach typisierte OUTRECS-Parameter wird als generischer Datensatzsatz dargestellt. Der schwach typisierte IN-Parameter INRECS wird als Zeichenfolge dargestellt.

Strongly-Typed OUT REF CURSOR-Parameter

REF CURSOR-Parameter mit starkem Typ (oder IN OUT) werden in einem eindeutigen Namespace basierend auf SCHEMA, PACKAGE und dem Namen der Prozedur oder Funktion generiert, in der sie verwendet werden. Für die Prozedur /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY ist microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITYdieser Namespace . Der Klassenname wird durch Anfügen des Namens des Parameters mit "RECORD" gebildet, und die Klasse besteht aus Eigenschaften, die die Oracle-Felder darstellen. Im Folgenden wird ein Teil der -Klasse gezeigt, der die stark typisierten Datensätze darstellt, die für den INOUTRECS REF CURSOR-Parameter generiert werden.

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;  
            }  
        }  
  
        ...  
  
    }  
}  

Weakly-Typed OUT REF CURSOR-Parameter

Schwach typisierte OUT(oder IN OUT)-REF CURSOR-Parameter werden durch die generische Datensatzklasse dargestellt. Der generische Datensatzsatz wird immer im selben Namespace und mit demselben Klassennamen generiert, unabhängig von der Funktion oder Prozedur. Der folgende Code zeigt die generische Datensatzklasse microsoft.lobservices.oracledb._2007._03.GenRecordRow, die die Datensätze für den OUTRECS OUT SYS_REFCURSOR Parameter (schwach typisiert) darstellt.

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;  
            }  
        }  
    }  
}  

Verwenden von REF CURSOR-Parametern mit einem WCF-Client

Gehen Sie wie folgt vor, um eine Prozedur oder Funktion mit REF CURSOR-Parametern mithilfe eines WCF-Clients aufzurufen:

  1. Übergeben Sie eine Zeichenfolge für jeden IN- oder IN OUT REF CURSOR-Parameter, der den PL/SQL-Block enthält, um den REF CURSOR zu öffnen. Dieser Block kann entweder eine OPEN FOR SELECT-Anweisung ausführen oder eine Funktion oder Prozedur aufrufen, die einen geöffneten REF CURSOR in einem OUT-Parameter zurückgibt.

  2. Wenn die Prozedur oder Funktion zurückgegeben wird, arbeiten Sie mit den Daten in den Datensatzsätzen, die für alle OUT- oder IN OUT REF CURSOR-Parameter zurückgegeben werden. Der Datensatzsatz ist ein generischer Datensatzsatz für schwach typisierte REF CURSOR-Parameter oder ein stark typisierter Datensatzsatz für stark typisierte REF CURSOR-Parameter.

    Weitere Informationen zum Aufrufen von Prozeduren und Funktionen mithilfe des WCF-Dienstmodells finden Sie unter Aufrufen von Funktionen und Prozeduren in Oracle Database mithilfe des WCF-Dienstmodells.

    Im folgenden Beispiel wird die GET_ACTIVITY-Prozedur aufgerufen. Es werden beide Möglichkeiten zum Angeben eines IN REF CURSOR-Parameters veranschaulicht:

  • Für den PARAMETER IN REF CURSOR wird eine OPEN FOR SELECT-Anweisung angegeben, um die Aktivität für ACCOUNT 100001 zurückzugeben.

  • Für den IN OUT REF CURSOR-Parameter wird die Prozedur /SCOTT/Package/ACCOUNT_PKG/GET_ALL_ACTIVITY aufgerufen. Diese Prozedur öffnet einen REF CURSOR, der die gesamte Aktivität in der ACCOUNTACTIVITY-Tabelle enthält, und gibt sie als OUT-Parameter zurück.

    Das Beispiel veranschaulicht auch, wie Daten aus dem Datensatzsatz gelesen werden, der sowohl für stark typisierte als auch für schwach typisierte REF CURSOR-Parameter zurückgegeben wird.

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();  
            }  
        }  
    }  
}  

Weitere Informationen

Entwickeln einer Oracle-Datenbankanwendung mit dem WCF-Dienstmodell