Teilen über


Abschließen von Vorgängen für Tabellen mit großen Datentypen in Oracle Database mithilfe des WCF-Dienstmodells

Dieser Abschnitt enthält Informationen zum Aufrufen der Vorgänge ReadLOB und UpdateLOB aus dem WCF-Dienstmodell. Die Vorgänge ReadLOB und UpdateLOB werden für Tabellen und Sichten angezeigt, die LOB-Spalten enthalten. Dies sind Spalten, die zum Speichern von Oracle-Lob-Daten (Large Object) verwendet werden. Eine Übersicht über die Oracle LOB-Datentypen, die vom Microsoft BizTalk-Adapter für Oracle-Datenbank unterstützt werden, sowie zu den Vorgängen ReadLOB und UpdateLOB finden Sie unter Vorgänge für Tabellen und Sichten, die LOB-Daten in Oracle Database enthalten.

Wichtig

Lob-Datenspalten können große Datenmengen enthalten – bis zu 4 GB. Eine erhebliche Einschränkung bei der Verwendung eines WCF-Clients zum Arbeiten mit LOB-Spalten besteht darin, dass das WCF-Dienstmodell nur Datenstreaming für den ReadLOB-Vorgang unterstützt, nicht für den UpdateLOB-Vorgang. Dies liegt daran, dass WCF erfordert, dass der zu streamende Parameter der einzige Parameter in seiner Richtung sein muss, damit das Streaming aus dem Dienstmodell funktioniert. Der UpdateLOB-Vorgang verfügt zusätzlich zu den LOB-Daten über zwei weitere IN-Parameter (spaltenname und Zeilenfilter). Aus diesem Grund wird das Streaming im WCF-Dienstmodell nicht unterstützt. Wenn Sie eine LOB-Spalte mit einer großen Datenmenge aktualisieren, sollten Sie daher das WCF-Kanalmodell verwenden. Weitere Informationen zur Verwendung des WCF-Kanalmodells zum Streamen von LOB-Daten mithilfe des UpdateLOB-Vorgangs finden Sie unter Streamen von Oracle LOB-Datentypen mithilfe des WCF-Kanalmodells.

Informationen zu den in diesem Thema verwendeten Beispielen

In den Beispielen in diesem Thema wird die Tabelle /SCOTT/CUSTOMER verwendet. Diese Tabelle enthält eine BLOB-Spalte namens PHOTO. Ein Skript zum Generieren dieser Tabelle wird mit den SDK-Beispielen bereitgestellt. Weitere Informationen zu den SDK-Beispielen finden Sie unter Beispiele im SDK.

Die WCF-Clientklasse

Das folgende Beispiel zeigt die Methodensignaturen für eine WCF-Clientklasse, die für die Vorgänge ReadLOB und UpdateLOB in der Tabelle /SCOTT/CUSTOMER generiert wurden.

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

Hinweis

Beachten Sie, dass ReadLOB einen Datenstrom zurückgibt, UpdateLOB jedoch nicht für einen Datenstrom ausgeführt wird.

Aufrufen der ReadLOB- und UpdateLOB-Vorgänge

Sowohl die ReadLOB - als auch die UpdateLOB-Methode können nur für eine einzelne LOB-Spalte in einer einzelnen Datenbankzeile ausgeführt werden. Sie legen die folgenden Parameter fest, um die Zielspalte/-zeile zu identifizieren.

Parameter Definition
LOB_COLUMN Der Name der Zielspalte in der Zeile, die durch den FILTER-Parameter identifiziert wird; beispiel: "PHOTO".
FILTER Der Inhalt einer WHERE-Klausel einer SQL SELECT-Anweisung, die die Zielzeile angibt; beispiel: "NAME='Kim Ralls'". Der Filter muss nur eine Zeile angeben. Wenn der Filter mit mehr als einer Zeile übereinstimmt:

- ReadLOB gibt LOB-Daten für die erste übereinstimmende Zeile zurück.
- UpdateLOB löst eine Ausnahme aus.

Hinweis

Der von ReadLOB zurückgegebene Stream unterstützt Seek nicht. Dies bedeutet, dass Eigenschaften wie Length auch nicht unterstützt werden.

Achtung

Der UpdateLOB-Vorgang muss innerhalb eines Transaktionsbereichs ausgeführt werden. Außerdem muss die UseAmbientTransaction-Bindungseigenschaft auf TRUE festgelegt werden, bevor der UpdateLOB-Vorgang ausgeführt wird.

Der folgende Code zeigt, wie Sie mithilfe eines WCF-Clients die Spalte BLOB PHOTO in der Tabelle /SCOTT/CUSTOMER aus einer Datei aktualisieren und die neuen Spaltendaten in eine Datei zurücklesen. Ein vollständiges Beispiel finden Sie in den SDK-Beispielen. Weitere Informationen zu den SDK-Beispielen finden Sie unter Beispiele im 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);  
            }  
        }  
    }  
}  

Weitere Informationen

Entwickeln von Oracle-Datenbankanwendungen mithilfe des WCF-Dienstmodells