Condividi tramite


Richiamare funzioni e procedure nel database Oracle usando il modello di servizio WCF

L'adapter Microsoft BizTalk per Oracle Database espone procedure, funzioni e pacchetti come operazioni. Nel modello di servizio WCF queste operazioni vengono rappresentate come metodi in un client WCF. Il modello di servizio WCF e l'adattatore Oracle Database:

  • Funzioni di supporto. Il valore RETURN della funzione Oracle viene visualizzato come valore restituito del metodo client WCF. I parametri Oracle vengono esposti come parametri (con l'opportuna direzione come definito di seguito) nel metodo client WCF.

  • Procedure di supporto. Il primo parametro OUT della routine Oracle viene visualizzato come valore restituito del metodo client WCF. Tutti gli altri parametri Oracle vengono visualizzati come parametri (con la direzione appropriata come definito di seguito) al metodo client WCF.

  • Supportare i pacchetti Oracle. Il nome dell'operazione e lo spazio dei nomi dei relativi tipi di parametro sono qualificati dal nome del pacchetto.

  • Supportare le funzioni e le procedure sovraccaricate.

  • Supportare i parametri IN, OUT e IN OUT per i tipi di dati Oracle di base per entrambe le procedure e le funzioni. I parametri OUT vengono visualizzati come parametri out nel metodo client WCF e i parametri IN OUT vengono visualizzati come parametri di riferimento .

  • Supportare i parametri IN, OUT e IN OUT REF CURSOR per le routine e le funzioni, nonché i valori RETURN della funzione. Per altre informazioni, vedere Esecuzione di operazioni tramite REF CURSORS nel database Oracle tramite il modello di servizio WCF.

  • Supportare i parametri di tipo IN, OUT e IN OUT RECORD per le procedure e le funzioni, nonché i valori RETURN della funzione. Per altre informazioni, vedere Esecuzione di operazioni tramite tipi RECORD nel database Oracle tramite il modello di servizio WCF.

Informazioni sugli esempi usati in questo argomento

Gli esempi in questo argomento usano la procedura sovraccaricata /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT. Questa procedura legge un record dalla tabella SCOTT/ACCOUNT in base a un ID dell'account o a un nome dell'account. Uno script per generare questa procedura e una tabella vengono forniti con gli esempi dell'SDK. Per altre informazioni sugli esempi dell'SDK, vedere Esempi nell'SDK.

Classe WCF client

Nella tabella seguente viene illustrato il nome del client WCF e il metodo generato per procedure, funzioni e pacchetti visualizzati dall'adapter Oracle Database. A meno che non venga eseguito l'overload di una funzione o di una routine, viene usato un singolo client WCF per richiamare tutte le funzioni in uno schema, tutte le procedure in uno schema o tutte le funzioni e le routine in un pacchetto.

Oracle Artifact Nome operazione client WCF Esempio
Procedimento [SCHEMA]ProcedureClient. [PROC_NAME] SCOTTProcedureClient.MYPROC
Funzione [SCHEMA]FunctionClient. [FUNC_NAME] SCOTTProcedureClient.MYFUNC
Pacchetto (routine o funzione) [SCHEMA]Package[PACKAGE_NAME]Client.[PROC_NAME o FUNC_NAME] SCOTTPackageMYPACKAGEClient.MYPROC

[SCHEMA] = Raccolta di artefatti Oracle; ad esempio SCOTT.

[PROC_NAME] = Nome di una routine Oracle; ad esempio MYPROC.

[FUNC_NAME] = Nome di una funzione Oracle; ad esempio MYFUNC.

[PACKAGE_NAME] = Nome di un pacchetto Oracle.

L'adattatore Oracle Database rappresenta i parametri di tipo Oracle RECORD e i valori restituiti, nonché i set di risultati restituiti dai parametri REF CURSOR come tipi XML complessi che contengono i dati di riga (o i campi) di un record Oracle. Nel modello di servizio WCF ognuno di questi tipi XML è rappresentato come classe .NET; le proprietà della classe rappresentano i campi del tipo RECORD o del set di risultati REF CURSOR. I tipi ORACLE RECORD sono sempre rappresentati come classi .NET fortemente tipate. Tuttavia, un set di risultati REF CURSOR può essere rappresentato come record fortemente tipizzato o debolmente tipizzato, a seconda che il cursore REF stesso sia dichiarato come fortemente tipizzato o debolmente tipizzato. Le classi che rappresentano i parametri di tipo REF CURSOR o RECORD (o valori restituiti) vengono generate in uno spazio dei nomi univoco in base alla routine, alla funzione o al pacchetto. La tabella seguente illustra i namespace.

Oracle Artifact Namespace Esempio
Procedimento [BASE_NS]. [SCHEMA]. Procedimento. [PROC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Procedure.MYPROC
Funzione [BASE_NS]. [SCHEMA]. Funzione. [FUNC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Function.MYFUNC
Pacchetto (Procedura) [BASE_NS]. [SCHEMA].Package.[PACKAGE_NAME].[PROC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYPROC
Pacchetto (Funzione) [BASE_NS]. [SCHEMA].Package.[PACKAGE_NAME].[FUNC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYFUNC
Set di record generici (tipizzato in modo debole) [BASE_NS] microsoft.lobservices.oracledb._2007._03

[BASE_NS] = Spazio dei nomi dell'adattatore di base; microsoft.lobservices.oracledb._2007._03.

[SCHEMA] = Raccolta di artefatti Oracle; ad esempio SCOTT.

[PROC_NAME] = Nome di una routine Oracle; Per esempio; MYPROC.

[FUNC_NAME] = Nome di una funzione Oracle; ad esempio MYFUNC.

[PACKAGE_NAME] = Nome di un pacchetto Oracle.

Per informazioni sull'utilizzo di questi spazi dei nomi per i parametri RECORD, vedere Esecuzione di operazioni tramite tipi RECORD nel database Oracle tramite il modello di servizio WCF. Per informazioni sull'utilizzo di questi spazi dei nomi per i parametri REF CURSOR, vedere Esecuzione di operazioni tramite REF CURSORS nel database Oracle tramite il modello di servizio WCF.

In generale, i parametri Oracle e i valori restituiti vengono mappati come indicato di seguito nel metodo client WCF:

  • I parametri Oracle IN vengono mappati ai parametri .NET (input).

  • I parametri Oracle OUT vengono mappati ai parametri out .NET.

  • I parametri Oracle IN OUT vengono mappati ai parametri di riferimento .NET.

  • I valori RETURN della funzione vengono mappati al valore restituito del metodo.

    Esistono tuttavia due eccezioni importanti:

  • I parametri Oracle IN OUT REF CURSOR vengono suddivisi in una stringa di input e in un set di record di output (out). Poiché l'adattatore Di database Oracle rappresenta i parametri IN REF CUSROR come stringhe e parametri OUT REF CURSOR come tipi complessi (set di record), non possono essere combinati in un singolo parametro.

  • Il primo parametro OUT in una routine Oracle viene mappato al valore restituito del metodo client WCF. Si tratta di un comportamento WCF standard.

    Nell'esempio seguente viene illustrata una semplice routine Oracle (caricata nello schema SCOTT) e la firma del metodo client WCF generato per richiamarlo. La procedura Oracle ha tre parametri IN, tre parametri IN OUT e tre parametri OUT; Tuttavia, il metodo client WCF non esegue il mapping di un parametro per il primo parametro OUT. Viene invece mappato sul valore restituito del metodo.

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

Supporto per procedure, funzioni e pacchetti sovraccarichi

L'adapter Oracle Database supporta procedure, funzioni e pacchetti sovraccarichi aggiungendo una stringa univoca all'ID del nodo e allo spazio dei nomi che espone per ogni elemento sovraccarico. Questa stringa è "overload1" per il primo overload, "overload2" per l'overload successivo e così via.

Nel modello di servizio WCF ogni routine o funzione di overload è rappresentata da un client WCF univoco. Questo comportamento è diverso dal caso non sovraccaricato in cui tutte le funzioni in uno schema, tutte le procedure in uno schema o tutte le procedure e le funzioni in un pacchetto vengono richiamate dallo stesso client WCF. La tabella seguente illustra il nome e il metodo client WCF generati per le procedure, funzioni e pacchetti sovraccaricate.

Oracle Artifact Nome client WCF Esempio
Pacchetto sovraccarico (procedura) [SCHEMA]Package[PACKAGE_NAME][PROC_NAME] ][OVERLOAD_ID]Client. [PROC_NAME] SCOTTPackageMYPACKAGEMYPROCoverload1Client.MYPROC
Pacchetto di funzioni sovraccariche [SCHEMA]Package[PACKAGE_NAME][FUNC_NAME] ][OVERLOAD_ID]Client. [FUNC_NAME] SCOTTPackageMYPACKAGEMYFUNCoverload1Client.MYFUNC

[SCHEMA] = Raccolta di artefatti Oracle; ad esempio SCOTT.

[PROC_NAME] = Nome di una routine Oracle; Per esempio; MYPROC.

[FUNC_NAME] = Nome di una funzione Oracle; ad esempio MYFUNC.

[PACKAGE_NAME] = Nome di un pacchetto Oracle.

[OVERLOAD_ID] = Stringa univoca che identifica l'artefatto di sovraccarico; "overload1", "overload2" e così via.

Nella tabella seguente viene illustrato lo spazio dei nomi generato per procedure, funzioni e pacchetti sovraccaricati.

Oracle Artifact Namespace Esempio
Pacchetto (Procedura) [BASE_NS]. [SCHEMA]. Pacchetto. [PACKAGE_NAME]. [PROC_NAME] [OVERLOAD_ID] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYPROC.overload1
Pacchetto (Funzione) [BASE_NS]. [SCHEMA].Pacchetto.[PACKAGE_NAME].[FUNC_NAME].[OVERLOAD_ID] microsoft.lobservices.oracledb._2007._03.SCOTT.Package.MYPACKAGE.MYFUNC.overload1
Set di record generici (tipizzato in modo debole) [BASE_NS] microsoft.lobservices.oracledb._2007._03

[BASE_NS] = Spazio dei nomi dell'adattatore di base; microsoft.lobservices.oracledb._2007._03.

[SCHEMA] = Raccolta di artefatti Oracle; ad esempio SCOTT.

[PROC_NAME] = Nome di una routine Oracle; Per esempio; MYPROC.

[FUNC_NAME] = Nome di una funzione Oracle; ad esempio MYFUNC.

[PACKAGE_NAME] = Nome di un pacchetto Oracle.

[OVERLOAD_ID] = Stringa univoca che identifica l'artefatto sovraccarico; "overload1", "overload2" e così via. Il valore numerico nella stringa è l'ID di overload per l'artefatto gestito dal database Oracle.

Nell'esempio seguente vengono illustrati i client WCF e le firme dei metodi generati per la procedura GET_ACCOUNT sovraccaricata nel pacchetto ACCOUNT_PKG. Le dichiarazioni Oracle sono incluse. Questo esempio mostra come viene generato un client WCF univoco per ogni overload e come il metodo generato per ogni client restituisce un set di record in uno spazio dei nomi univoco.

/* 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);  
}  

Richiamo di funzioni e procedure

Per richiamare una funzione o una routine utilizzando un client WCF, seguire questa procedura.

  1. Generare una classe client WCF per la funzione di destinazione, la routine o il pacchetto. Questa classe deve contenere metodi per le operazioni che verranno richiamate sull'artefatto di destinazione.

    Annotazioni

    Nel plug-in Aggiungi Riferimento al Servizio Adapter di Visual Studio, le funzioni e procedure sovraccariche vengono visualizzate nella casella Categorie e operazioni disponibili come [NAME].1, [NAME].2, [NAME].3 e così via, dove [NAME] è il nome dell'artefatto sovraccarico e il valore numerico è l'ID di sovraccarico nel database Oracle.

  2. Creare un'istanza della classe client WCF e chiamare i relativi metodi per richiamare la funzione o la routine.

    Per informazioni più dettagliate su come creare una classe client WCF e richiamare operazioni sull'adattatore Oracle Database, vedere Panoramica del modello di servizio WCF con l'adapter di database Oracle.

    L'adapter Oracle Database esegue ogni operazione all'interno di una transazione nel database Oracle.

Importante

Le classi che rappresentano parametri di tipo REF CURSOR e RECORD o valori restituiti in funzioni o routine (e pacchetti) vengono dichiarate in uno spazio dei nomi univoco per ogni funzione o routine. Ciò significa, ad esempio, che un tipo PACKAGE REF CURSOR utilizzato come valore restituito in due funzioni diverse verrà dichiarato in uno spazio dei nomi univoco per ogni metodo client WCF. È necessario dichiarare variabili separate per contenere questi valori restituiti diversi o eseguire il cast appropriato della variabile quando si richiama uno dei metodi client WCF.

Nell'esempio seguente viene illustrata la chiamata alla procedura sovraccaricata /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT per ottenere i record dei conti dalla tabella /SCOTT/ACCOUNT. Per prima cosa viene creato un nuovo record chiamando la routine /SCOTT/Package/ACCOUNT_PKG/CREATE_ACCOUNT. Il nuovo record viene quindi letto due volte chiamando diversi sovraccarichi di GET_ACCOUNT. In questo esempio vengono utilizzati tre client WCF, uno per la routine CREATE_ACCOUNT e uno per gli overload GET_ACCOUNT. Gli alias vengono utilizzati per distinguere i namespace impiegati per il valore di ritorno di GET_ACCOUNT. Un esempio completo è disponibile negli esempi dell'SDK. Per altre informazioni sugli esempi dell'SDK, vedere Esempi nell'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();  
            }  
  
        }  
    }  
}  

Vedere anche

Sviluppare applicazioni di database Oracle usando il modello di servizio WCF