Invocar funciones y procedimientos en oracle Database mediante el modelo de servicio WCF

El adaptador de Microsoft BizTalk para oracle Database muestra procedimientos, funciones y paquetes como operaciones. En el modelo de servicio WCF, estas operaciones se representan como métodos en un cliente WCF. El modelo de servicio WCF y el adaptador de base de datos de Oracle:

  • Funciones de soporte técnico. El valor RETURN de la función de Oracle se muestra como el valor devuelto del método de cliente WCF. Los parámetros de Oracle se muestran como parámetros (con la dirección adecuada según se define a continuación) al método de cliente WCF.

  • Procedimientos de soporte técnico. El primer parámetro OUT del procedimiento de Oracle se muestra como el valor devuelto del método de cliente WCF. Todos los demás parámetros de Oracle se muestran como parámetros (con la dirección adecuada según se define a continuación) al método de cliente WCF.

  • Admite paquetes de Oracle. El nombre de la operación y el espacio de nombres de sus tipos de parámetros se califican mediante el nombre del paquete.

  • Admitir funciones y procedimientos sobrecargados.

  • Admite parámetros IN, OUT e IN OUT para tipos de datos básicos de Oracle para procedimientos y funciones. Los parámetros OUT se exponen como parámetros out en el método de cliente WCF y los parámetros IN OUT se muestran como parámetros ref .

  • Admite parámetros IN, OUT e IN OUT REF CURSOR para procedimientos y funciones, así como valores RETURN de función. Para obtener más información, vea Performing Operations Using REF CURSORS in Oracle Database using the WCF Service Model.

  • Admite parámetros de tipo IN, OUT e IN OUT RECORD para procedimientos y funciones, así como valores RETURN de función. Para obtener más información, vea Performing Operations Using RECORD Types in Oracle Database using the WCF Service Model.

Acerca de los ejemplos usados en este tema

En los ejemplos de este tema se usa el procedimiento sobrecargado /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT. Este procedimiento lee un registro de la tabla SCOTT/ACCOUNT en función de un identificador de cuenta o un nombre de cuenta. Se proporciona un script para generar este procedimiento y tabla con los ejemplos del SDK. Para obtener más información sobre los ejemplos del SDK, consulte Ejemplos en el SDK.

Clase de cliente WCF

En la tabla siguiente se muestra el nombre del cliente WCF y el método generado para procedimientos, funciones y paquetes que muestra el adaptador de Oracle Database. A menos que se sobrecargue una función o un procedimiento, se usa un único cliente WCF para invocar todas las funciones de un esquema, todos los procedimientos de un esquema o todas las funciones y procedimientos de un paquete.

Artefacto de Oracle Nombre de la operación del cliente WCF Ejemplo
Procedimiento [SCHEMA] ProcedureClient. [PROC_NAME] SCOTTProcedureClient.MYPROC
Función [SCHEMA] FunctionClient. [FUNC_NAME] SCOTTProcedureClient.MYFUNC
Paquete (procedimiento o función) [SCHEMA] Package[PACKAGE_NAME]Client. [PROC_NAME o FUNC_NAME] SCOTTPackageMYPACKAGEClient.MYPROC

[SCHEMA] = Colección de artefactos de Oracle; por ejemplo, SCOTT.

[PROC_NAME] = El nombre de un procedimiento de Oracle; por ejemplo, MYPROC.

[FUNC_NAME] = El nombre de una función de Oracle; por ejemplo, MYFUNC.

[PACKAGE_NAME] = El nombre de un paquete de Oracle.

El adaptador de Oracle Database representa parámetros de tipo RECORD de Oracle y valores devueltos, así como los conjuntos de resultados devueltos por parámetros REF CURSOR como tipos XML complejos que contienen los datos de fila (o campos) de un registro de Oracle. En el modelo de servicio WCF, cada uno de estos tipos XML se representa como una clase .NET; las propiedades de la clase representan los campos del conjunto de resultados RECORD o REF CURSOR. Los tipos RECORD de Oracle siempre se representan como clases de .NET fuertemente tipadas. Sin embargo, un conjunto de resultados REF CURSOR se puede representar como registros fuertemente tipados o débilmente tipados en función de si el CURSOR REF se declara fuertemente tipado o débilmente tipado. Las clases que representan parámetros de tipo REF CURSOR o RECORD (o valores devueltos) se generan en un espacio de nombres único basado en el procedimiento, la función o el paquete. En la tabla siguiente se muestran estos espacios de nombres.

Artefacto de Oracle Espacio de nombres Ejemplo
Procedimiento [BASE_NS]. [SCHEMA]. Procedimiento. [PROC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT. Procedure.MYPROC
Función [BASE_NS]. [SCHEMA]. Función. [FUNC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT. Function.MYFUNC
Paquete (procedimiento) [BASE_NS]. [SCHEMA]. Paquete. [PACKAGE_NAME]. [PROC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYPROC
Paquete (función) [BASE_NS]. [SCHEMA]. Paquete. [PACKAGE_NAME]. [FUNC_NAME] microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYFUNC
Conjunto de registros genérico (con tipo débil) [BASE_NS] microsoft.lobservices.oracledb._2007._03

[BASE_NS] = Espacio de nombres del adaptador base; microsoft.lobservices.oracledb._2007._03.

[SCHEMA] = Colección de artefactos de Oracle; por ejemplo, SCOTT.

[PROC_NAME] = El nombre de un procedimiento de Oracle; por ejemplo; MYPROC.

[FUNC_NAME] = El nombre de una función de Oracle; por ejemplo, MYFUNC.

[PACKAGE_NAME] = El nombre de un paquete de Oracle.

Para obtener información sobre cómo se usan estos espacios de nombres para los parámetros RECORD, vea Performing Operations Using RECORD Types in Oracle Database using the WCF Service Model. Para obtener información sobre cómo se usan estos espacios de nombres para los parámetros REF CURSOR, vea Performing Operations Using REF CURSORS in Oracle Database using the WCF Service Model.

En general, los parámetros de Oracle y los valores devueltos se asignan de la siguiente manera en el método de cliente WCF:

  • Los parámetros IN de Oracle se asignan a los parámetros de .NET (entrada).

  • Los parámetros OUT de Oracle se asignan a los parámetros de salida de .NET.

  • Los parámetros in out de Oracle se asignan a los parámetros ref de .NET.

  • Los valores RETURN de la función se asignan al valor devuelto del método.

    Sin embargo, existen dos excepciones importantes:

  • Los parámetros DE ORACLE IN OUT REF CURSOR se dividen en una cadena de entrada y un conjunto de registros de salida (out). Esto se debe a que el adaptador de base de datos de Oracle representa parámetros IN REF CUSROR como cadenas y parámetros OUT REF CURSOR como tipos complejos (conjuntos de registros), no se pueden combinar en un solo parámetro.

  • El primer parámetro OUT de un procedimiento de Oracle se asigna al valor devuelto del método de cliente WCF. Este es el comportamiento estándar de WCF.

    En el ejemplo siguiente se muestra parte de un procedimiento de Oracle simple (cargado en el esquema SCOTT) y la firma del método de cliente WCF que se genera para invocarlo. El procedimiento oracle tiene tres parámetros IN, tres parámetros IN OUT y tres parámetros OUT; sin embargo, el método de cliente WCF no asigna un parámetro para el primer parámetro OUT. En su lugar, se asigna al valor devuelto del método.

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

Compatibilidad con procedimientos sobrecargados, funciones y paquetes

El adaptador de Oracle Database admite procedimientos, funciones y paquetes sobrecargados anexando una cadena única al identificador de nodo y el espacio de nombres que expone para cada artefacto sobrecargado. Esta cadena es "overload1" para la primera sobrecarga, "overload2" para la siguiente sobrecarga, etc.

En el modelo de servicio WCF, cada procedimiento o función sobrecargado se representa mediante un cliente WCF único. Esto es diferente del caso no sobrecargado en el que todas las funciones de un SCHEMA, todos los procedimientos de un SCHEMA, o todos los procedimientos y funciones de un PAQUETE son invocados por el mismo cliente WCF. En la tabla siguiente se muestra el nombre de cliente y el método WCF generados para procedimientos sobrecargados, funciones y paquetes.

Artefacto de Oracle Nombre del cliente WCF Ejemplo
Paquete sobrecargado (procedimiento) [SCHEMA] Package[PACKAGE_NAME][PROC_NAME] ][OVERLOAD_ID]Client. [PROC_NAME] SCOTTPackageMYPACKAGEMYPROCoverload1Client.MYPROC
Paquete sobrecargado (función) [SCHEMA] Package[PACKAGE_NAME][FUNC_NAME] ][OVERLOAD_ID]Client. [FUNC_NAME] SCOTTPackageMYPACKAGEMYFUNCoverload1Client.MYFUNC

[SCHEMA] = Colección de artefactos de Oracle; por ejemplo, SCOTT.

[PROC_NAME] = El nombre de un procedimiento de Oracle; por ejemplo; MYPROC.

[FUNC_NAME] = El nombre de una función de Oracle; por ejemplo, MYFUNC.

[PACKAGE_NAME] = El nombre de un paquete de Oracle.

[OVERLOAD_ID] = La cadena única que identifica el artefacto sobrecargado; "overload1", "overload2", etc.

En la tabla siguiente se muestra el espacio de nombres generado para procedimientos sobrecargados, funciones y paquetes.

Artefacto de Oracle Espacio de nombres Ejemplo
Paquete (procedimiento) [BASE_NS]. [SCHEMA]. Paquete. [PACKAGE_NAME]. [PROC_NAME] [OVERLOAD_ID] microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYPROC.overload1
Paquete (función) [BASE_NS]. [SCHEMA]. Paquete. [PACKAGE_NAME]. [FUNC_NAME]. [OVERLOAD_ID] microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYFUNC.overload1
Conjunto de registros genérico (con tipo débil) [BASE_NS] microsoft.lobservices.oracledb._2007._03

[BASE_NS] = Espacio de nombres del adaptador base; microsoft.lobservices.oracledb._2007._03.

[SCHEMA] = Colección de artefactos de Oracle; por ejemplo, SCOTT.

[PROC_NAME] = El nombre de un procedimiento de Oracle; por ejemplo; MYPROC.

[FUNC_NAME] = El nombre de una función de Oracle; por ejemplo, MYFUNC.

[PACKAGE_NAME] = El nombre de un paquete de Oracle.

[OVERLOAD_ID] = La cadena única que identifica el artefacto sobrecargado; "overload1", "overload2", etc. El valor numérico de la cadena es el identificador de sobrecarga del artefacto mantenido por la base de datos de Oracle.

En el ejemplo siguiente se muestran los clientes WCF y las firmas de método generadas para el procedimiento de GET_ACCOUNT sobrecargado en el paquete de ACCOUNT_PKG. (Se incluyen las declaraciones de Oracle). En este ejemplo se muestra cómo se genera un cliente WCF único para cada sobrecarga y cómo el método generado para cada cliente devuelve un conjunto de registros en un espacio de nombres único.

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

Invocar funciones y procedimientos

Para invocar una función o un procedimiento mediante un cliente WCF, realice los pasos siguientes.

  1. Genere una clase de cliente WCF para la función, procedimiento o paquete de destino. Esta clase debe contener métodos para las operaciones que invocará en el artefacto de destino.

    Nota

    En el complemento Agregar referencia de servicio de adaptador de Visual Studio, las funciones sobrecargadas y los procedimientos aparecen en el cuadro Categorías y operaciones disponibles como [NAME].1, [NAME].2, [NAME].3, etc., donde [NAME] es el nombre del artefacto sobrecargado y el valor numérico es el identificador de sobrecarga en la base de datos de Oracle.

  2. Cree una instancia de la clase de cliente WCF y llame a sus métodos para invocar la función o procedimiento.

    Para obtener información más detallada sobre cómo crear una clase de cliente WCF e invocar operaciones en el adaptador de base de datos de Oracle, vea Información general del modelo de servicio WCF con el adaptador de base de datos de Oracle.

    El adaptador de base de datos de Oracle ejecuta cada operación dentro de una transacción en la base de datos de Oracle.

Importante

Las clases que representan parámetros de tipo REF CURSOR y RECORD o valores devueltos en funciones o procedimientos (y paquetes) se declaran en un espacio de nombres único para cada función o procedimiento. Esto significa, por ejemplo, que un tipo PACKAGE REF CURSOR que se usa como valor devuelto en dos funciones diferentes se declarará en un espacio de nombres único para cada método de cliente WCF. Debe declarar variables independientes para contener estos valores devueltos diferentes o convertir correctamente la variable al invocar uno de los métodos de cliente WCF.

En el ejemplo siguiente se muestra cómo llamar al procedimiento sobrecargado /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT para obtener registros de cuenta de la tabla /SCOTT/ACCOUNT. En primer lugar, se crea un nuevo registro llamando al procedimiento /SCOTT/Package/ACCOUNT_PKG/CREATE_ACCOUNT. A continuación, el nuevo registro se vuelve a leer dos veces llamando a diferentes sobrecargas de GET_ACCOUNT. En este ejemplo se usan tres clientes WCF, uno para el procedimiento de CREATE_ACCOUNT y otro para las sobrecargas de GET_ACCOUNT. Los alias se usan para distinguir entre los espacios de nombres usados para el valor devuelto de GET_ACCOUNT. Hay disponible un ejemplo completo en los ejemplos del SDK. Para obtener más información sobre los ejemplos del SDK, consulte Ejemplos en el 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();  
            }  
  
        }  
    }  
}  

Consulte también

Desarrollo de aplicaciones de base de datos de Oracle mediante el modelo de servicio WCF