Oracle LOB

.NET Framework Data Provider for Oracle에는 Oracle LOB 데이터 형식 작업에 사용되는 OracleLob 클래스가 포함되어 있습니다.

OracleLob는 다음 OracleType 데이터 형식 중 하나일 수 있습니다.

데이터 형식

설명

Blob

최대 4GB의 이진 데이터가 포함된 Oracle BLOB 데이터 형식. 이 형식은 Byte 형식의 Array에 매핑됩니다.

Clob

서버의 기본 문자 집합을 기반으로 최대 4GB의 문자 데이터가 포함된 Oracle CLOB 데이터 형식. 이 형식은 String에 매핑됩니다.

NClob

서버의 국가별 문자 집합을 기반으로 최대 4GB의 문자 데이터가 포함된 Oracle NCLOB 데이터 형식. 이 형식은 String에 매핑됩니다.

OracleLob는 데이터가 운영 체제의 물리적 파일이 아닌 서버에 저장된다는 점에서 OracleBFile과 다릅니다. 또한 항상 읽기 전용인 OracleBFile과 달리 읽기/쓰기 개체일 수 있습니다.

LOB 만들기, 검색 및 쓰기

다음 C# 예제에서는 Oracle 테이블에 LOB를 만든 다음 이를 OracleLob 개체의 형태로 검색하고 쓰는 방법을 보여 줍니다. 이 예제에서는 OracleDataReader 개체와 OracleLob ReadWrite 메서드를 사용하는 방법도 설명합니다. 예제에서는 Oracle BLOB, CLOBNCLOB 데이터 형식을 사용합니다.

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

임시 LOB 만들기

다음 C# 예제에서는 임시 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();

참고 항목

기타 리소스

Oracle 및 ADO.NET