C# 如何寫入和讀取Oracle大字段


如果你的應用程序時Oracle數據庫,那么將字符串寫入到大字段(Blob)列中是一種常見的操作,現作簡單介紹:

先建立一個簡單的表:

create  table EMRSIGNINFO
(
  ID         VARCHAR2( 1 0),
  ORIGNDATA BLOB
)

 ORIGNDATA 列為BLOB大字段數據類型.

然后直接上兩個方法:

View Code
   // 插入大字段數據 
         public  void InsertStringToClob()
        {
            System.Data.OracleClient.OracleConnection con =  new System.Data.OracleClient.OracleConnection();
            con.ConnectionString =  " Data Source=Orcl; User Id=gctest; Password=his; "; // 數據庫連接串 
            con.Open();
             using (OracleCommand cmd =  new OracleCommand())
            {
                cmd.CommandType = CommandType.Text;
                cmd.Connection = con;
                cmd.CommandText =  @"
                        insert into EMRSIGNINFO(ID,ORIGNDATA)  values(
                        '1',
                        :temp
                        )
                        
";
                OracleParameter param = cmd.Parameters.Add( " :temp ", OracleType.Blob);
                param.Direction = ParameterDirection.Input;
                 string strOriginText =  @" CzFe3B9mgc1kv3bYldRbMqp9AkCW84EPjBOZZYI+Y0yYgFaDRk4kjmvAuDyF3OAPbCyXoSdzLImG2Y956y/KJV8d3cS0sfjeBLFiFbUXdXfzzgZ23c
                                r44QlMreS9+lIOV0jyd+yX3Spse34rNJwa/aD8i6LTXRCFxfb6Tx1GRj4=CzFe3B9mgc1kv3bYldRbMqp9AkCW84EPjBOZZYI+Y0yYgFaDRk4kjmvAuDyF3OAPbCyXoSdzLImG2Y956y
                                /KJV8d3cS0sfjeBLFiFbUXdXfzzgZ23cr44QlMreS9+lIOV0jyd+yX3Spse34rNJwa/aD8iCzFe3B9mgc1kv3bYldRbMqp9AkCW84EPjBOZZYI+Y0yYgFaDRk4kjmvAuDyF3OA
                                PbCyXoSdzLImG2Y956y/KJV8d3cS0sfjeBLFiFbUXdXfzzgZ23cr44QlMreS9+lIOV0jyd+yX3Spse34rNJwa/aD8i6LTXRCFxfb6Tx1GRj4=6LTXRCFxfb6Tx1GRj4=
";
                param.Value = CompressString(strOriginText);
                 try
                {
                    cmd.ExecuteNonQuery();
                }
                 catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }
            con.Close();
        }

         // 讀取大字段中存儲的字符串 
         public  string ReadClobToString()
        {
             string strSql =  " select * from  EMRSIGNINFO where id='1' ";
             string result= string.Empty;
            System.Data.OracleClient.OracleConnection con =  new System.Data.OracleClient.OracleConnection();
            con.ConnectionString =  " Data Source=Orcl; User Id=gctest; Password=his; ";
            con.Open();
             using (OracleCommand cmd =  new OracleCommand())
            {
                cmd.CommandType = CommandType.Text;
                cmd.Connection = con;
                cmd.CommandText = strSql;
                 try
                {
                    OracleDataReader reader = cmd.ExecuteReader();
                     while (reader.Read())
                    {
                         result = DecompressString(( byte[])reader[ 1]);
                    }
                }
                 catch (Exception ex)
                {
                }
            }
            con.Close();
             return result;
        } 

 

針對以上的幾點說明:

1、大字段數據列在sql語句中使用冒號(:)加一個任意名稱進行占位,如以上第一個方法中的sql語句中的:temp 。然后為Command添加參數,參數名稱也為:temp,參數類型為OracleType.Blob

2、參數的值(Value)應該是 一個 Byte[]類型。在第一個方法中,對參數賦值時采用了一個方法CompressString將字符串轉換為Byte[]類型數據。

如果上面直接將字符串對參數賦值 param.Value = strOriginText;將產生如下錯誤:

 

3、第二個方法中讀取大字段的時候:使用Read(),當讀取到大字段的數據時,先將數據轉換為byte[]類型,然后使用一個方法將字節數組解壓縮為字符串。

4、微軟已經不推薦使用OracleConnection OracleCommand 等,而是推薦使用Oracle開發的ODP.NET,這會比微軟為Oracle開發的適配器強大。此處為演示,使用大家熟知的了。

5、以上程序沒有添加任何其他考慮,比如:如果大字段中的數據可為空,那么在讀取的時候此處(byte[])reader[1]會報錯,因為reader[1]是一個System.DBNull類型,是不能轉換為byte[]類型的。這些都是沒有考慮到的哦。另外也沒有考慮如果是多個大字段的話如何處理,如果是一個sql語句中要寫入多個大字段列,可以使用params語法,具體不介紹。

6、每個公司自己的產品中都有一套框架來處理這種底層的數據庫才做,會對這些操作進行封裝,使之在易用性、安全性、復用性等等方面進行增強。可以肯定的是,不會有任何一個公司的代碼會寫成以上這樣。您在公司要操作大字段可能只是簡單的調用一個非常簡單的方法即可,但是如果有時間還是建議對里面的原理做些了解。如此才能吸取經驗、懂得原理,才不會為各種新技術、新工具所迷惑。

7、以上兩個方法中使用的DecompressStringDecompressString方法為網上找的輪子。也貼出來吧。要說明的是,需要引用ICSharpCode.SharpZipLib.dll。它的使用說明此處就不介紹了,有興趣的朋友找谷歌。

 

View Code
         ///   <summary>
        
///  用壓縮算法壓縮一個字符串
        
///   </summary>
        
///   <param name="input"> 輸入的字符串. </param>
        
///   <returns> 返回字節 </returns>
         public   byte[] CompressString( string input)
        {
             return CompressBytes(Encoding.UTF8.GetBytes(input));
        }
         ///   <summary>
        
///  Decompress a byte stream of a string that was formerly 
        
///  compressed with the CompressString() routine with the ZIP algorithm.
        
///   </summary>
        
///   <param name="input"> The buffer that contains the compressed
        
///  stream with the string. </param>
        
///   <returns> Returns the decompressed string. </returns>
         public  string DecompressString(
             byte[] input)
        {
             return Encoding.UTF8.GetString(DecompressBytes(input));
        }

         ///   <summary>
        
///  用壓縮算法壓縮字節
        
///   </summary>
        
///   <param name="input"> 需要壓縮的字節 </param>
        
///   <returns> 返回壓縮的字節 </returns>
         public   byte[] CompressBytes( byte[] input)
        {
             using (MemoryStream buf =  new MemoryStream())
             using (ZipOutputStream zip =  new ZipOutputStream(buf))
            {
                Crc32 crc =  new Crc32();
                zip.SetLevel( 9);     //  0..9.

                ZipEntry entry =  new ZipEntry( string.Empty);
                entry.DateTime = DateTime.Now;
                entry.Size = input.Length;

                crc.Reset();
                crc.Update(input);

                entry.Crc = crc.Value;

                zip.PutNextEntry(entry);

                zip.Write(input,  0, input.Length);
                zip.Finish();

                 //  --

                 byte[] c =  new  byte[buf.Length];
                buf.Seek( 0, SeekOrigin.Begin);
                buf.Read(c,  0, c.Length);

                 //  --

                zip.Close();

                 return c;
            }
        }

         ///   <summary>
        
///  Decompress a byte stream that was formerly compressed
        
///  with the CompressBytes() routine with the ZIP algorithm.
        
///   </summary>
        
///   <param name="input"> The buffer that contains the compressed
        
///  stream with the bytes. </param>
        
///   <returns> Returns the decompressed bytes. </returns>
         public   byte[] DecompressBytes(
             byte[] input)
        {
             using (MemoryStream mem =  new MemoryStream(input))
             using (ZipInputStream stm =  new ZipInputStream(mem))
             using (MemoryStream mem2 =  new MemoryStream())
            {
                ZipEntry entry = stm.GetNextEntry();
                 if (entry !=  null)
                {
                     byte[] data =  new  byte[ 4096];

                     while ( true)
                    {
                         int size = stm.Read(data,  0, data.Length);
                         if (size >  0)
                        {
                            mem2.Write(data,  0, size);
                        }
                         else
                        {
                             break;
                        }
                    }
                }

                 using (BinaryReader r =  new BinaryReader(mem2))
                {
                     byte[] c =  new  byte[mem2.Length];
                    mem2.Seek( 0, SeekOrigin.Begin);
                    r.Read(c,  0, ( int)mem2.Length);

                     return c;
                }
            }
        }

 

歡迎大家交換意見,歡迎拍磚。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM