Realización de operaciones en tablas con tipos de datos de gran tamaño en Oracle Database mediante el modelo de servicio WCF

Esta sección contiene información sobre cómo invocar las operaciones ReadLOB y UpdateLOB desde el modelo de servicio WCF. Las operaciones ReadLOB y UpdateLOB se exponen para tablas y vistas que contienen columnas LOB; que es columnas que se usan para almacenar datos de objetos grandes (LOB) de Oracle. Para obtener información general sobre los tipos de datos loB de Oracle admitidos por el adaptador de Microsoft BizTalk para oracle Database y de las operaciones ReadLOB y UpdateLOB, vea Operaciones en tablas y vistas que contienen datos de LOB en oracle Database.

Importante

Las columnas de datos loB pueden contener grandes cantidades de datos, hasta 4 gigabytes (GB). Una limitación significativa del uso de un cliente WCF para operar en columnas LOB es que el modelo de servicio WCF solo admite el streaming de datos en la operación ReadLOB, no en la operación UpdateLOB. Esto se debe a que WCF requiere que el streaming funcione desde el modelo de servicio, el parámetro que se va a transmitir debe ser el único parámetro en su dirección. La operación UpdateLOB tiene otros dos parámetros IN (un nombre de columna y un filtro de fila) además de los datos loB; por este motivo, el streaming no se admite en él en el modelo de servicio WCF. Por lo tanto, si va a actualizar una columna LOB con una gran cantidad de datos, es posible que desee usar el modelo de canal WCF. Para obtener más información sobre cómo usar el modelo de canal WCF para transmitir datos LOB mediante la operación UpdateLOB, vea Streaming oracle LOB Data Types by Using the WCF Channel Model.

Acerca de los ejemplos usados en este tema

En los ejemplos de este tema se usa la tabla /SCOTT/CUSTOMER. Esta tabla contiene una columna BLOB denominada PHOTO. Se proporciona un script para generar esta tabla con los ejemplos del SDK. Para obtener más información sobre los ejemplos del SDK, consulte Ejemplos en el SDK.

La clase de cliente WCF

En el ejemplo siguiente se muestran las firmas de método para una clase de cliente WCF generada para las operaciones ReadLOB y UpdateLOB en la tabla /SCOTT/CUSTOMER.

public partial class SCOTTTableCUSTOMERClient : System.ServiceModel.ClientBase<SCOTTTableCUSTOMER>,   
                                                SCOTTTableCUSTOMER   
{  
    public System.IO.Stream ReadLOB(string LOB_COLUMN, string FILTER);   
  
    public void UpdateLOB(string LOB_COLUMN, string FILTER, byte[] Stream);  
}  

Nota

Tenga en cuenta que ReadLOB devuelve un flujo de datos, pero que UpdateLOB no funciona en una secuencia.

Invocación de las operaciones ReadLOB y UpdateLOB

Los métodos ReadLOB y UpdateLOB solo pueden funcionar en una sola columna LOB en una sola fila de base de datos. Establezca los parámetros siguientes para identificar la columna o fila de destino.

Parámetro Definición
LOB_COLUMN Nombre de la columna de destino dentro de la fila identificada por el parámetro FILTER; por ejemplo, "PHOTO".
FILTER El contenido de una cláusula WHERE de instrucción SELECT de SQL que especifica la fila de destino; por ejemplo, "NAME='Kim Ralls'". El filtro debe especificar una y solo una fila. Si el filtro coincide con más de una fila:

- ReadLOB devuelve datos loB para la primera fila coincidente.
- UpdateLOB produce una excepción.

Nota

La secuencia devuelta por ReadLOB no admite Seek. Esto significa que tampoco se admiten propiedades como Length .

Precaución

La operación UpdateLOB debe realizarse dentro de un ámbito de transacción. Además, la propiedad de enlace UseAmbientTransaction debe establecerse en true antes de realizar la operación UpdateLOB .

En el código siguiente se muestra cómo usar un cliente WCF para actualizar la columna BLOB PHOTO en la tabla /SCOTT/CUSTOMER de un archivo y leer los nuevos datos de columna en un archivo. Puede encontrar 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;  
using System.Transaction;  
  
// Include for file streaming  
using System.IO;  
  
// 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 the WCF channel model  
using System.ServiceModel.Channels;  
  
// Include this namespace for the WCF LOB Adapter SDK and Oracle Database adapter exceptions  
using Microsoft.ServiceModel.Channels.Common;  
  
using CustomerTablens = microsoft.lobservices.oracledb._2007._03;  
  
namespace OracleLobOpsSnippetSM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            try  
            {  
                OracleDBBinding binding = new OracleDBBinding();  
                binding.UseAmbientTransaction = true; //set this to true for UpdateLOB operation  
  
                EndpointAddress endpointAddress = new EndpointAddress("oracleDB://ADAPTER");  
  
                using (SCOTTTableCUSTOMERClient customerTableClient =  
                    new SCOTTTableCUSTOMERClient(binding, endpointAddress))  
                {  
                    customerTableClient.ClientCredentials.UserName.UserName = "SCOTT";  
                    customerTableClient.ClientCredentials.UserName.Password = "TIGER";  
  
                    // Open the client to read the LOB data back  
                    customerTableClient.Open();  
  
                    // Add a photo to the customer record    
                    using (FileStream fs = new FileStream("SamplePhoto.jpg", FileMode.Open))  
                    {  
                        Console.WriteLine("Updating photo");  
                        int count = 0;  
                        byte[] photo = new byte[fs.Length];  
                        while ((count += fs.Read(photo, count, (int) (((fs.Length-count)>4096)? 4096:fs.Length-count))) \< fs.Length) ;  
  
                        // UpdateLOB operation must be performed within a transaction scope  
                        using(TransactionScope tx = new TransactionScope())  
                        {  
                           customerTableClient.UpdateLOB("PHOTO", "NAME='Kim Ralls'", photo);  
                           Console.WriteLine("Photo updated");  
                           tx.Complete();  
                        }  
                    }  
  
                    // Read the data back and store it to another file  
                    using (FileStream fs = new FileStream("PhotoCopy.jpg", FileMode.Create))  
                    {  
                        Console.WriteLine("Reading photo data");  
                        Stream photoStream = customerTableClient.ReadLOB("PHOTO", "NAME='Kim Ralls'");  
                        Console.WriteLine("Photo data read -- writing to PhotoCopy.jpg");  
  
                        int count;  
                        int length = 0;  
                        byte[] buffer = new byte[4096];  
                        while ((count = photoStream.Read(buffer, 0, 4096)) > 0)  
                        {  
                            fs.Write(buffer, 0, count);  
                            length+=count;  
                        }  
                        Console.WriteLine("{0} bytes written to PhotoCopy.jpg", length);  
                    }  
  
                }  
  
                Console.WriteLine("Photo updated and read back -- Hit <RETURN> to end");  
                Console.ReadLine();  
  
            }  
            catch (Exception ex)  
            {  
                // handle exception  
                Console.WriteLine("Exception caught: " + ex.Message);  
            }  
        }  
    }  
}  

Consulte también

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