Condividi tramite


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

L'adapter Microsoft BizTalk per Oracle Database esegue le procedure, le funzioni e i pacchetti come operazioni. Nel modello di servizio WCF queste operazioni vengono rappresentate come metodi in un client WCF. Modello di servizio WCF e 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 visualizzati come parametri (con la direzione appropriata definita di seguito) al 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 definita di seguito) al metodo client WCF.

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

  • Supportare funzioni e procedure di overload.

  • Supportare i parametri IN, OUT e IN OUT per i tipi di dati Oracle di base per 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 ref .

  • Supportare i parametri IN, OUT e IN OUT REF CURSOR per le procedure e le funzioni, nonché i valori RETURN delle funzioni. Per altre informazioni, vedere Esecuzione di operazioni tramite REF CURSORS nel database Oracle usando 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 delle funzioni. Per altre informazioni, vedere Esecuzione di operazioni tramite tipi RECORD nel database Oracle usando il modello di servizio WCF.

Informazioni sugli esempi usati in questo argomento

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

Classe client WCF

Nella tabella seguente viene illustrato il nome del client WCF e il metodo generato per le procedure, le funzioni e i 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 procedure in un pacchetto.

Artefatto Oracle Nome operazione client WCF Esempio
Procedura [SCHEMA] ProcedureClient. [PROC_NAME] SCOTTProcedureClient.MYPROC
Funzione [SCHEMA] FunctionClient. [FUNC_NAME] SCOTTProcedureClient.MYFUNC
Pacchetto (procedura o funzione) [SCHEMA] Pacchetto[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'adapter Oracle Database rappresenta parametri di tipo Oracle RECORD e valori restituiti, nonché i set di risultati restituiti dai parametri REF CURSOR come tipi XML complessi che contengono i dati di riga (o campi) di un record Oracle. Nel modello di servizio WCF ognuno di questi tipi XML viene rappresentato come classe .NET; le proprietà della classe rappresentano i campi del set di risultati RECORD o REF CURSOR. I tipi DI RECORD Oracle sono sempre rappresentati come classi .NET fortemente tipizzata. Un set di risultati REF CURSOR, tuttavia, può essere rappresentato come record fortemente tipizzato o con tipizzato debole in base al fatto che il cursore REF stesso sia dichiarato come fortemente tipizzato o debole. Le classi che rappresentano i parametri di tipo REF CURSOR o RECORD (o restituiti) vengono generate in uno spazio dei nomi univoco in base alla procedura, alla funzione o al pacchetto. La tabella seguente mostra questi spazi dei nomi.

Artefatto Oracle Spazio dei nomi Esempio
Procedura [BASE_NS]. [SCHEMA]. Procedura. [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]. Pacchetto. [PACKAGE_NAME]. [PROC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYPROC
Pacchetto (funzione) [BASE_NS]. [SCHEMA]. Pacchetto. [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 sul modo in cui vengono usati questi spazi dei nomi per i parametri RECORD, vedere Esecuzione di operazioni tramite tipi RECORD nel database Oracle usando il modello di servizio WCF. Per informazioni sul modo in cui vengono usati questi spazi dei nomi per i parametri REF CURSOR, vedere Esecuzione di operazioni tramite CURSORI REF nel database Oracle usando il modello di servizio WCF.

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

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

  • I parametri Oracle OUT vengono mappati ai parametri di uscita .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 sono suddivisi in una stringa di input e in un set di record di output (out). Ciò avviee perché l'adapter 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. Questo è il comportamento WCF standard.

    Nell'esempio seguente viene illustrata una semplice procedura Oracle (caricata nello schema SCOTT) e la firma del metodo client WCF generato per richiamarlo. La procedura Oracle include 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 al 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 di overload

L'adapter Oracle Database supporta procedure, funzioni e pacchetti di overload aggiungendo una stringa univoca all'ID nodo e allo spazio dei nomi che viene visualizzato per ogni artefatto di overload. 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. Ciò è diverso dal caso non di overload 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. Nella tabella seguente viene illustrato il nome e il metodo client WCF generati per le procedure, le funzioni e i pacchetti di overload.

Artefatto Oracle Nome client WCF Esempio
Pacchetto di overload (procedura) [SCHEMA] Package[PACKAGE_NAME][PROC_NAME] ][OVERLOAD_ID]Client. [PROC_NAME] SCOTTPackageMYPACKAGEMYPROCoverload1Client.MYPROC
Pacchetto di overload (funzione) [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 overload; "overload1", "overload2" e così via.

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

Elemento Oracle Spazio dei nomi Esempio
Pacchetto (procedura) [BASE_NS]. [SCHEMA]. Pacchetto. [PACKAGE_NAME]. [PROC_NAME] [OVERLOAD_ID] microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYPROC.overload1
Package (Function) [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 di overload; "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 del metodo generate per la routine di GET_ACCOUNT di overload nel pacchetto ACCOUNT_PKG. Le dichiarazioni Oracle sono incluse. In questo esempio viene illustrato 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 usando 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.

    Nota

    Nella casella Aggiungi riferimento al servizio adapter di Visual Studio, le funzioni e le procedure di overload vengono visualizzate nella casella Categorie e operazioni disponibili come [NAME].1, [NAME].2, [NAME].3 e così via, dove [NAME] è il nome dell'artefatto di overload e il valore numerico è l'ID di overload 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 le operazioni sull'adapter 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 usato 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 routine /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT di overload per ottenere i record dell'account 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 overload diversi 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 usati per distinguere tra gli spazi dei nomi usati per il valore restituito 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