.NET Framework Developer's Guide 
Working with Oracle LOBs 

The .NET Framework Data Provider for Oracle includes the OracleLob class, which is used to work with Oracle LOB data types.

An OracleLob may be one of these OracleType data types:

Data type Description

Blob

An Oracle BLOB data type that contains binary data with a maximum size of 4 gigabytes. This maps to an Array of type Byte.

Clob

An Oracle CLOB data type that contains character data, based on the default character set on the server, with a maximum size of 4 gigabytes. This maps to String.

NClob

An Oracle NCLOB data type that contains character data, based on the national character set on the server with a maximum size of 4 gigabytes. This maps to String.

An OracleLob differs from an OracleBFile in that the data is stored on the server instead of in a physical file in the operating system. It can also be a read-write object, unlike an OracleBFile, which is always read-only.

Creating, Retrieving, and Writing to a LOB

The following C# example demonstrates how you can create LOBs in an Oracle table, and then retrieve and write to them in the form of OracleLob objects. The example demonstrates using the OracleDataReader object and the OracleLob Read and Write methods. The example uses Oracle BLOB, CLOB, and NCLOB data types.

[C#]

using System;
using System.IO;            
using System.Text;           
using System.Data;            
using System.Data.OracleClient;

// LobExample
public class LobExample
{
   public static int Main(string[] args)
   {
      //Create a connection.
      OracleConnection conn = new OracleConnection(
         "Data Source=Oracle8i;Integrated Security=yes");
      using(conn)
      {
         //Open a connection.
         conn.Open();
         OracleCommand cmd = conn.CreateCommand();

         //Create the table and schema.
         CreateTable(cmd);

         //Read example.
         ReadLobExample(cmd);

         //Write example
         WriteLobExample(cmd);
      }

      return 1;
   }

   // ReadLobExample
   public static void ReadLobExample(OracleCommand cmd)
   {
      int actual = 0;

      // Table Schema:
      // "CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)";
      // "INSERT INTO tablewithlobs values (1, 'AA', 'AAA', N'AAAA')";
      // Select some data.
      cmd.CommandText = "SELECT * FROM tablewithlobs";
      OracleDataReader reader = cmd.ExecuteReader();
      using(reader)
      {
         //Obtain the first row of data.
         reader.Read();
         
         //Obtain the LOBs (all 3 varieties).
         OracleLob blob = reader.GetOracleLob(1);
         OracleLob clob = reader.GetOracleLob(2);
         OracleLob nclob = reader.GetOracleLob(3);

         //Example - Reading binary data (in chunks).
         byte[] buffer = new byte[100];
         while((actual = blob.Read(buffer, 0, buffer.Length)) >0)
            Console.WriteLine(blob.LobType + ".Read(" + buffer + ", " + 
              buffer.Length + ") => " + actual);

         // Example - Reading CLOB/NCLOB data (in chunks).
         // Note: You can read character data as raw Unicode bytes 
         // (using OracleLob.Read as in the above example).
         // However, because the OracleLob object inherits directly 
         // from the .Net stream object, 
         // all the existing classes that manipluate streams can 
         // also be used. For example, the 
         // .Net StreamReader makes it easier to convert the raw bytes 
         // into actual characters.
         StreamReader streamreader = 
           new StreamReader(clob, Encoding.Unicode);
         char[] cbuffer = new char[100];
         while((actual = streamreader.Read(cbuffer, 
           0, cbuffer.Length)) >0)
            Console.WriteLine(clob.LobType + ".Read(
              " + new string(cbuffer, 0, actual) + ", " + 
              cbuffer.Length + ") => " + actual);

         // Example - Reading data (all at once).
         // You could use StreamReader.ReadToEnd to obtain 
         // all the string data, or simply
         // call OracleLob.Value to obtain a contiguous allocation 
         // of all the data.
         Console.WriteLine(nclob.LobType + ".Value => " + nclob.Value);
      }
   }

   // WriteLobExample
   public static void WriteLobExample(OracleCommand cmd)
   {
      //Note: Updating LOB data requires a transaction.
      cmd.Transaction = cmd.Connection.BeginTransaction();
      
      // Select some data.
      // Table Schema:
      // "CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)";
      // "INSERT INTO tablewithlobs values (1, 'AA', 'AAA', N'AAAA')";
      cmd.CommandText = "SELECT * FROM tablewithlobs FOR UPDATE";
      OracleDataReader reader = cmd.ExecuteReader();
      using(reader)
      {
         // Obtain the first row of data.
         reader.Read();

         // Obtain a LOB.
         OracleLob blob = reader.GetOracleLob(1/*0:based ordinal*/);

         // Perform any desired operations on the LOB 
         // (read, position, and so on).

         // Example - Writing binary data (directly to the backend).
         // To write, you can use any of the stream classes, or write
         // raw binary data using 
         // the OracleLob write method. Writing character vs. binary 
         // is the same;
         // however note that character is always in terms of 
         // Unicode byte counts
         // (for example, even number of bytes - 2 bytes for every
         // Unicode character).
         byte[] buffer = new byte[100];
         buffer[0] = 0xCC;
         buffer[1] = 0xDD;
         blob.Write(buffer, 0, 2);
         blob.Position = 0;
         Console.WriteLine(blob.LobType + ".Write(
           " + buffer + ", 0, 2) => " + blob.Value);
         
         // Example - Obtaining a temp LOB and copying data 
         // into it from another LOB.
         OracleLob templob = CreateTempLob(cmd, blob.LobType);
         long actual = blob.CopyTo(templob);
         Console.WriteLine(blob.LobType + ".CopyTo(
            " + templob.Value + ") => " + actual);

         // Commit the transaction now that everything succeeded.
         // Note: On error, Transaction.Dispose is called 
         // (from the using statement)
         // and will automatically roll back the pending transaction.
         cmd.Transaction.Commit();
      }
   }

   // CreateTempLob
   public static OracleLob CreateTempLob(
     OracleCommand cmd, OracleType lobtype)
   {
      //Oracle server syntax to obtain a temporary LOB.
      cmd.CommandText = "DECLARE A " + lobtype + "; "+
                     "BEGIN "+
                        "DBMS_LOB.CREATETEMPORARY(A, FALSE); "+
                        ":LOC := A; "+
                     "END;";
      
      //Bind the LOB as an output parameter.
      OracleParameter p = cmd.Parameters.Add("LOC", lobtype);
      p.Direction = ParameterDirection.Output;

      //Execute (to receive the output temporary LOB).
      cmd.ExecuteNonQuery();

      //Return the temporary LOB.
      return (OracleLob)p.Value;
   }

   // CreateTable
   public static void CreateTable(OracleCommand cmd)
   {
      // Table Schema:
      // "CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)";
      // "INSERT INTO tablewithlobs VALUES (1, 'AA', 'AAA', N'AAAA')";
      try
      {
         cmd.CommandText   = "DROP TABLE tablewithlobs";
         cmd.ExecuteNonQuery();
      }
      catch(Exception)
      {
      }
      
      cmd.CommandText = 
        "CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)";
      cmd.ExecuteNonQuery();
      cmd.CommandText = 
        "INSERT INTO tablewithlobs VALUES (1, 'AA', 'AAA', N'AAAA')";
      cmd.ExecuteNonQuery();
   }
}

Creating a Temporary LOB

The following C# example demonstrates how to create a temporary LOB.

[C#]

OracleConnection conn = new OracleConnection(
  "server=test8172; integrated security=yes;");
conn.Open();

OracleTransaction tx = conn.BeginTransaction();

OracleCommand cmd = conn.CreateCommand();
cmd.Transaction = tx;
cmd.CommandText = 
  "declare xx blob; begin dbms_lob.createtemporary(
  xx, false, 0); :tempblob := xx; end;";
cmd.Parameters.Add(new OracleParameter("tempblob",
  OracleType.Blob)).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
OracleLob tempLob = (OracleLob)cmd.Parameters[0].Value;
tempLob.BeginBatch(OracleLobOpenMode.ReadWrite);
tempLob.Write(tempbuff,0,tempbuff.Length);
tempLob.EndBatch();
cmd.Parameters.Clear();
cmd.CommandText = "myTable.myProc";
cmd.CommandType = CommandType.StoredProcedure;  
cmd.Parameters.Add(new OracleParameter(
  "ImportDoc", OracleType.Blob)).Value = tempLob;
cmd.ExecuteNonQuery();

tx.Commit();

See Also



Community Content

Dan Wygant
cannot create a Binary Large Object (BLOB) from a byte array

Using the code above, I get the error:
"invalid operation. the connection is closed"

http://support.microsoft.com/default.aspx?scid=kb;en-us;322796

the key: "declare xx blob; begin dbms_lob.createtemporary(xx, false, 0); :tempblob := xx; end;"

It is a misnomer to assume we will pre-populate using "INSERT INTO tablewithlobs values (1, 'AA', 'AAA', N'AAAA')";

Here is the VB.NET code from the Microsoft site that worked for me, followed by a C# example I had found first from Experts Exchange:

Dim conn As New OracleConnection("server=Oracle;Uid=uid;pwd=pwd")
Dim filePath As String
Dim bigData As Byte()
Dim t As Date

t = Now

filePath = "C:\mytest.bmp" 'Add the path to the file you want to insert
If Not File.Exists(filePath) Then
' handle error
End If


Dim fs As Stream = File.OpenRead(filePath)
Dim tempBuff(fs.Length) As Byte

fs.Read(tempBuff, 0, fs.Length)
fs.Close()
conn.Open()

Dim tx As OracleTransaction
tx = conn.BeginTransaction()

Dim cmd As New OracleCommand()
cmd = conn.CreateCommand()

cmd.Transaction = tx

cmd.CommandText = "declare xx blob; begin dbms_lob.createtemporary(xx, false, 0); :tempblob := xx; end;"
cmd.Parameters.Add(New OracleParameter("tempblob", OracleType.Blob)).Direction = ParameterDirection.Output
cmd.ExecuteNonQuery()



Dim tempLob As OracleLob
tempLob = cmd.Parameters(0).Value
tempLob.BeginBatch(OracleLobOpenMode.ReadWrite)
tempLob.Write(tempBuff, 0, tempBuff.Length)
tempLob.EndBatch()

cmd.Parameters.Clear()
cmd.CommandText = "InsertBlob.TestBlobInsert"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New OracleParameter("BlobParam", OracleType.Blob)).Value = tempLob

Try
cmd.ExecuteNonQuery()
Catch myex As Exception
MsgBox(myex.Message)
End Try

tx.Commit()

--------------------------------------

From "ofaniel" on Experts Exchange where I found it first...

Here is a similar method in C# ... at the veeeery bottom of this Experts Exchange page:

http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_24230043.html

private void UpdateCaseNotes(string SchemaReference, string DefectId, string Comments)
{
using (OracleConnection conn = new OracleConnection(ConfigurationSettings.AppSettings["DBConnStr"]))
{
conn.Open();

OracleCommand cmd = new OracleCommand();
cmd = conn.CreateCommand();

OracleTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;

cmd.CommandText = "declare xx clob; begin dbms_lob.createtemporary(xx, false, 0); :tempclob := xx; end;";
cmd.Parameters.Add(new OracleParameter("tempclob", OracleType.Clob)).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();

byte[] cbComments = Encoding.Unicode.GetBytes(Comments);

OracleLob tmpClob = default(OracleLob);
tmpClob = (OracleLob)cmd.Parameters[0].Value;
tmpClob.BeginBatch(OracleLobOpenMode.ReadWrite);
tmpClob.Write(cbComments, 0, cbComments.Length);
tmpClob.EndBatch();

cmd.Parameters.Clear();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "UPDATE " + SchemaReference + ".BUG SET " + colCaseComment + " = :clb WHERE BG_BUG_ID = " + DefectId;
cmd.Parameters.Add(new OracleParameter("clb", OracleType.Clob)).Value = tmpClob;

try
{
cmd.ExecuteNonQuery();
tx.Commit();
}
catch (OracleException ex)
{
throw new Exception("Error updating case comment.", ex);
}
finally
{
cmd.Dispose();
tx.Dispose();
conn.Close();
}
}
}


Very Respectfully,
Daniel Wygant, Soft Where Developer, See the Possibilities
Founder HUNTUG.org VSdotNetUG.org HowToVS.NET
Co-Founder Culminis.com
INETA.org Mentor Al/Ms/La/Tn/Ky on 05/12/2009


Page view tracker