Condividi tramite


Eseguire operazioni usando REF CURSORS nel database Oracle usando il modello di servizio WCF

Ref CURSOR è un tipo di dati Oracle PL/SQL che rappresenta un puntatore a un set di risultati nel database Oracle. L'adapter Microsoft BizTalk per Oracle Database supporta i parametri REF CURSOR nelle procedure, nelle funzioni e nei pacchetti. I parametri REF CURSOR possono essere fortemente tipizzato o tipizzato in modo debole a seconda della modalità di dichiarazione nella routine o nella funzione. Per una spiegazione dettagliata del modo in cui i parametri REF CURSOR sono rappresentati dall'adapter Di database Oracle, vedere Schemi messaggio per REF CURSORS. Nella tabella seguente viene riepilogato il modo in cui i parametri REF CURSOR sono rappresentati nel modello di servizio WCF.

Direzione parametro REF CURSOR fortemente tipizzato REF CURSOR debolmente tipizzato
IN string [PARAM_NAME]

Stringa contenente un blocco PL/SQL. Il blocco PL/SQL deve restituire un REF CURSOR aperto eseguendo un'istruzione "OPEN FOR SELECT" o richiamando una funzione o una routine. Un punto interrogativo (?) indica la posizione del CURSORE REF che restituisce il parametro . Ad esempio, "BEGIN OPEN ? FOR SELECT * FROM MY_TABLE; END" o "BEGIN MY_PROC(PARM1, ?, PARM2); END;".
Uguale a fortemente tipizzato
OUT out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME]

Set di record fortemente tipizzato.
out [GENERIC_NS].GenRecordRow[] [PARAM_NAME]

Set di record generici tipizzato in modo debole.
IN USCITA I parametri IN OUT REF CURSOR sono suddivisi in un parametro IN e OUT. Il parametro IN viene aggiunto con "_IN" nella firma del metodo per distinguerlo dal parametro OUT. Il parametro OUT è rappresentato da un set di record fortemente tipizzato.

string [PARAM_NAME]_IN

out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME]
I parametri IN OUT REF CURSOR sono suddivisi in un parametro IN e OUT. Il parametro IN viene aggiunto con "_IN" per distinguerlo dal parametro OUT. Il parametro OUT è rappresentato da un set di record di tipo debole.

string [PARAM_NAME]_IN

out [GENERIC_NS].GenRecordRow[] [PARAM_NAME]

[PARAM_NAME] = nome del parametro nella definizione della funzione o della routine nel database Oracle; ad esempio MYREFCURSOR.

[PROC_NS] = Spazio dei nomi univoco generato per contenere parametri del pacchetto, della routine o della funzione; ad esempio "microsoft.lobservices.oracledb._2007._03.SCOTT. Package.ACCOUNT_PKG. GET_ACTIVITY".

[GENERIC_NS] = Spazio dei nomi in cui è definito il set di record generico " microsoft.lobservices.oracledb._2007._03".

Informazioni sugli esempi usati in questo argomento

Gli esempi in questo argomento usano /SCOTT/Package/ACCOUNT_PKG Oracle PACKAGE. La procedura seguente viene utilizzata da ACCOUNT_PKG:

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

Uno script per generare questo pacchetto viene fornito con gli esempi dell'SDK. Per altre informazioni sugli esempi dell'SDK, vedere Esempi nell'SDK.

Parametri REF CURSOR nel modello di servizio WCF

Gli esempi seguenti illustrano le classi e il client WCF generati per la routine /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY. Questa procedura include parametri IN e OUT REF CURSOR fortemente tipizzato e un parametro IN OUT REF CURSOR fortemente tipizzato.

Ecco la firma del metodo generato nel client WCF per richiamare GET_ACTIVITY.

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

Nel metodo GET_ACTIVITY il parametro IN OUT INOUTRECS viene suddiviso in due parametri:

  • INOUTRECS_IN è una stringa che rappresenta un parametro IN REF CURSOR.

  • INOUTRECS è un set di record fortemente tipizzato che rappresenta un parametro OUT REF CURSOR.

    Il parametro OUT, OUTRECS, tipizzato in modo debole, è rappresentato come un set di record generico. Il parametro IN, INRECS, tipizzato in modo debole, è rappresentato come stringa.

Parametri Strongly-Typed OUT REF CURSOR

I parametri OUT (o IN OUT) REF CURSOR fortemente tipizzato vengono generati in uno spazio dei nomi univoco basato su SCHEMA, PACKAGE e sul nome della routine o della funzione in cui vengono usati. Per la routine /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY, questo spazio dei nomi è microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY. Il nome della classe è formato aggiungendo il nome del parametro con "RECORD" e la classe è costituita da proprietà che rappresentano i campi Oracle. Di seguito viene illustrata una parte della classe che rappresenta i record fortemente tipizzato generati per il parametro 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;  
            }  
        }  
  
        ...  
  
    }  
}  

Parametri Weakly-Typed OUT REF CURSOR

I parametri OUT (o IN OUT) REF CURSOR debolmente tipizzato sono rappresentati dalla classe di record generica. Il set di record generico viene sempre generato nello stesso spazio dei nomi e con lo stesso nome di classe indipendentemente dalla funzione o dalla routine. Nel codice seguente viene illustrata la classe di record generica microsoft.lobservices.oracledb._2007._03.GenRecordRow, che rappresenta i record per il parametro OUTRECS OUT SYS_REFCURSOR (tipizzato in modo debole).

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

Uso dei parametri REF CURSOR con un client WCF

Per richiamare una routine o una funzione con parametri REF CURSOR tramite un client WCF, eseguire le operazioni seguenti:

  1. Passare una stringa per ogni parametro IN o IN OUT REF CURSOR che contiene il blocco PL/SQL per aprire REF CURSOR. Questo blocco può eseguire un'istruzione OPEN FOR SELECT oppure richiamare una funzione o una routine che restituisce un REF CURSOR aperto in un parametro OUT.

  2. Quando la routine o la funzione viene restituita, utilizzare i dati nei set di record restituiti per qualsiasi parametro OUT o IN OUT REF CURSOR. Il set di record sarà un set di record generico per parametri REF CURSOR di tipo debole o un set di record fortemente tipizzato per i parametri REF CURSOR fortemente tipizzato.

    Per altre informazioni su come richiamare routine e funzioni usando il modello di servizio WCF, vedere Richiamare funzioni e routine in Oracle Database usando il modello di servizio WCF.

    Nell'esempio seguente viene chiamata la routine GET_ACTIVITY. Illustra entrambi i modi per specificare un parametro IN REF CURSOR:

  • Per il parametro IN REF CURSOR, viene specificata un'istruzione OPEN FOR SELECT per restituire l'attività per account 100001.

  • Per il parametro IN OUT REF CURSOR, viene richiamata la routine /SCOTT/Package/ACCOUNT_PKG/GET_ALL_ACTIVITY. Questa procedura apre un OGGETTO REF CURSOR che contiene tutte le attività nella tabella ACCOUNTACTIVITY e lo restituisce come parametro OUT.

    L'esempio illustra anche come leggere i dati dal set di record restituiti per i parametri REF CURSOR fortemente tipizzato e debole.

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

Vedere anche

Sviluppare un'applicazione di database Oracle usando il modello di servizio WCF