Ejecutar operaciones mediante CURSORES REF en la base de datos de Oracle mediante el modelo de servicio WCF
Un CURSOR REF es un tipo de datos PL/SQL de Oracle que representa un puntero a un conjunto de resultados en la base de datos de Oracle. El adaptador de Microsoft BizTalk para oracle Database admite parámetros REF CURSOR en procedimientos, funciones y paquetes. Los parámetros REF CURSOR pueden estar fuertemente tipados o débilmente tipados en función de cómo se declaren en el procedimiento o la función. Para obtener una explicación detallada de cómo se representan los parámetros REF CURSOR mediante el adaptador de oracle Database, vea Esquemas de mensaje para CURSORES REF. En la tabla siguiente se resume cómo se representan los parámetros REF CURSOR en el modelo de servicio WCF.
Dirección del parámetro | CURSOR REF fuertemente tipado | CURSOR REF débilmente tipado |
---|---|---|
IN | string [PARAM_NAME] Cadena que contiene un bloque PL/SQL. El bloque PL/SQL debe devolver un CURSOR REF abierto ejecutando una instrucción "OPEN FOR SELECT" o invocando una función o un procedimiento. Un signo de interrogación (?) indica la posición del CURSOR REF que devuelve el parámetro . Por ejemplo, "BEGIN OPEN ? FOR SELECT * FROM MY_TABLE; END" o "BEGIN MY_PROC(PARM1, ?, PARM2); END;". |
Igual que fuertemente tipado |
OUT | out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME] Un conjunto de registros fuertemente tipado. |
out [GENERIC_NS].GenRecordRow[] [PARAM_NAME] Un conjunto de registros genérico débilmente tipado. |
IN OUT | Los parámetros IN OUT REF CURSOR se dividen en un parámetro IN y OUT. El parámetro IN se anexa con "_IN" en la firma del método para distinguirlo del parámetro OUT. El parámetro OUT se representa mediante un conjunto de registros fuertemente tipado.string [PARAM_NAME]_IN out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME] |
Los parámetros IN OUT REF CURSOR se dividen en un parámetro IN y OUT. El parámetro IN se anexa con "_IN" para distinguirlo del parámetro OUT. El parámetro OUT se representa mediante un conjunto de registros débilmente tipado.string [PARAM_NAME]_IN out [GENERIC_NS].GenRecordRow[] [PARAM_NAME] |
[PARAM_NAME] = el nombre del parámetro en la definición de función o procedimiento en la base de datos de Oracle; por ejemplo, MYREFCURSOR.
[PROC_NS] = El espacio de nombres único generado para contener parámetros del paquete, procedimiento o función; por ejemplo, "microsoft.lobservices.oracledb._2007._03.SCOTT. Package.ACCOUNT_PKG. GET_ACTIVITY".
[GENERIC_NS] = Espacio de nombres en el que se define el conjunto de registros genérico, "microsoft.lobservices.oracledb._2007._03".
Acerca de los ejemplos usados en este tema
En los ejemplos de este tema se usa /SCOTT/Package/ACCOUNT_PKG Paquete de Oracle. El siguiente procedimiento se usa desde ACCOUNT_PKG:
PROCEDURE get_activity(inrecs IN SYS_REFCURSOR, status OUT NUMBER, inoutrecs IN OUT activity_ref_type, outrecs OUT SYS_REFCURSOR);
Se proporciona un script para generar este paquete con los ejemplos del SDK. Para obtener más información sobre los ejemplos del SDK, consulte Ejemplos en el SDK.
Parámetros REF CURSOR en el modelo de servicio WCF
En los ejemplos siguientes se muestran las clases y el cliente WCF generados para el procedimiento /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY. Este procedimiento tiene parámetros IN y OUT REF CURSOR de tipo débil y un parámetro IN OUT REF CURSOR fuertemente tipado.
Esta es la firma del método que se genera en el cliente WCF para invocar 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);
En el método GET_ACTIVITY , el parámetro IN OUT INOUTRECS se divide en dos parámetros:
INOUTRECS_IN es una cadena que representa un parámetro IN REF CURSOR.
INOUTRECS es un conjunto de registros fuertemente tipado que representa un parámetro OUT REF CURSOR.
El parámetro OUT débilmente tipado, OUTRECS, se representa como un conjunto de registros genérico. El parámetro IN débilmente tipado, INRECS, se representa como una cadena.
Strongly-Typed PARÁMETROS REF CURSOR
Los parámetros OUT (o IN OUT) REF CURSOR fuertemente tipados se generan en un espacio de nombres único basado en el esquema, paquete y nombre del procedimiento o función en el que se usan. Para el procedimiento /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY, este espacio de nombres es microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY
. El nombre de clase se forma anexando el nombre del parámetro con "RECORD" y la clase se compone de propiedades que representan los campos de Oracle. A continuación se muestra una parte de la clase que representa los registros fuertemente tipados generados para el parámetro 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;
}
}
...
}
}
Weakly-Typed PARÁMETROS REF CURSOR
Los parámetros OUT (o IN OUT) REF CURSOR de tipo débil se representan mediante la clase de registro genérica. El conjunto de registros genérico siempre se genera en el mismo espacio de nombres y con el mismo nombre de clase independientemente de la función o procedimiento. El código siguiente muestra la clase de registro genérica, microsoft.lobservices.oracledb._2007._03.GenRecordRow, que representa los registros del parámetro OUTRECS OUT SYS_REFCURSOR (débilmente tipado).
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;
}
}
}
}
Usar parámetros REF CURSOR con un cliente WCF
Para invocar un procedimiento o una función con parámetros REF CURSOR mediante un cliente WCF, haga lo siguiente:
Pase una cadena para cada parámetro IN o IN OUT REF CURSOR que contenga el bloque PL/SQL para abrir el CURSOR REF. Este bloque puede ejecutar una instrucción OPEN FOR SELECT o invocar una función o procedimiento que devuelva un CURSOR REF abierto en un parámetro OUT.
Cuando se devuelve el procedimiento o la función, opera en los datos de los conjuntos de registros devueltos para cualquier parámetro OUT o IN OUT REF CURSOR. El conjunto de registros será un conjunto de registros genérico para parámetros REF CURSOR de tipo débil o un conjunto de registros fuertemente tipado para parámetros REF CURSOR fuertemente tipados.
Para obtener más información sobre cómo invocar procedimientos y funciones mediante el modelo de servicio WCF, vea Invoke Functions and Procedures in Oracle Database using the WCF Service Model.
En el ejemplo siguiente se llama al procedimiento GET_ACTIVITY. Muestra ambas formas de especificar un parámetro IN REF CURSOR:
Para el parámetro IN REF CURSOR, se especifica una instrucción OPEN FOR SELECT para devolver la actividad de ACCOUNT 100001.
Para el parámetro IN OUT REF CURSOR, se invoca el procedimiento /SCOTT/Package/ACCOUNT_PKG/GET_ALL_ACTIVITY. Este procedimiento abre un CURSOR REF que contiene toda la actividad de la tabla ACCOUNTACTIVITY y la devuelve como un parámetro OUT.
En el ejemplo también se muestra cómo leer los datos del conjunto de registros devueltos para los parámetros REF CURSOR ref fuertemente tipados y débilmente tipados.
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();
}
}
}
}
Consulte también
Desarrollo de una aplicación de base de datos de Oracle mediante el modelo de servicio WCF