当前位置:七道奇文章资讯数据防范Oracle防范
日期:2011-01-25 22:55:00  来源:本站整理

Oracle中操纵BLOB字段存储4GB以下视频数据[Oracle防范]

赞助商链接



  本文“Oracle中操纵BLOB字段存储4GB以下视频数据[Oracle防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

很长时间没亲身写写东西了,只是汇集转载了一些好资料,其实,真正静下心总结一下,可以写的知识点很多.与艰难做斗争,挑衅技术难关,总会有些感受心得的.

本日想和网友分享一下“Oracle中BLOB大字段若何读写视频数据”,这个话题起因是我在利用ORACLE备份数据时,误删了数据库实例的掌握文件,招致项目数据需求重新入库.也就是我在补偿这个错误时,发现之前的数据入库功效,都没有把200M以上的视频数据导入ORACLE的BLOB字段里,也就是之前的写入BLOB字段数据的办法失效了.这是个惊人的发现,我发现因为这个程序BUG我遗漏掉近300G的视频数据,某些单个视频文件数据量到达3.6G.

我研究基于ORACLE Text的全文检索功效,开始接触ORACLE的BLOB字段,3年多了,自认为已经熟知BLOB字段的操作.但这次的难题迫使我更深化的熟习ORACLE的BLOB字段.

BLOB字段能以二进制情势存放4G数据,200M的视频数据当然应当没问题,可以出错了?!本来的办法会报“Out of memory”错误,PLSQL Developer工具导入大视频数据,一样会报“Out of memory”错误.3.6G的视频数据又该若何导入?本来写入大字段的办法,导入普通的图片和文档一点问题没有.

  1. /// <summary>  
  2. /// 写大字段内容  
  3. /// (新办法,2010.2.4)  
  4. /// </summary>  
  5. /// <param name="pDbConn"></param>  
  6. /// <param name="strTable"></param>  
  7. /// <param name="strBlobField"></param>  
  8. /// <param name="strFile"></param>  
  9. /// <param name="strWhereClause"></param>  
  10. /// <returns></returns>  
  11. public bool WriteBlobField(System.Data.OleDb.OleDbConnection pDbConn,  
  12.     string strTable,  
  13.     string strBlobField,  
  14.     string strFile,  
  15.     string strWhereClause)  
  16. {  
  17.     if (strWhereClause == "")  
  18.     {  
  19.         return false;  
  20.     }  
  21.     try 
  22.     {  
  23.         string strSQL = "UPDATE " + strTable + " SET " + strBlobField + " =:blob WHERE " + strWhereClause;  
  24.  
  25.         OleDbCommand cmd = new OleDbCommand(strSQL, pDbConn);  
  26.         //无需阐明范例  
  27.         //cmd.Parameters.Add(new OleDbParameter("blob", SqlDbType.VarBinary));  
  28.         // cmd.Parameters.AddWithValue("blob", SqlDbType.Binary);  
  29.         FileInfo fileInfo = new FileInfo(strFile);  
  30.  
  31.         FileStream fsBlob = fileInfo.OpenRead();// new FileStream(strFile, FileMode.Open,FileAccess.Read);  
  32.         byte[] dataBlob = new byte[fsBlob.Length];//问题1所在  
  33.         fsBlob.Read(dataBlob, 0, System.Convert.ToInt32(fsBlob.Length));//问题2所在  
  34.         fsBlob.Close();  
  35.         //采取新的办法,AddWithValue();  
  36.         cmd.Parameters.AddWithValue("blob", dataBlob);  
  37.         //cmd.Parameters["blob"].Value = dataBlob;  
  38.         int result = cmd.ExecuteNonQuery();  
  39.         if (result < 1)  
  40.         {  
  41.             return false;  
  42.         }  
  43.     }  
  44.     catch (Exception ex)  
  45.     {  
  46.         //   MessageBox.Show(ex.Message, "写数据", MessageBoxButtons.OK);  
  47.         return false;  
  48.     }  
  49.  
  50.     return true;  
  51. }  
  52.  
  53.     /// <summary>  
  54.     /// 将字符串写成大字段内容  
  55.        /// (2010.2.4 改正)  
  56.     /// </summary>  
  57.     /// <param name="pDbConn"></param>  
  58.     /// <param name="strTable"></param>  
  59.     /// <param name="strBlobField"></param>  
  60.     /// <param name="strBlobContent"></param>  
  61.     /// <param name="strWhereClause"></param>  
  62.     /// <returns></returns>  
  63.     public bool WriteBlobField2(System.Data.OleDb.OleDbConnection pDbConn,  
  64.                   string strTable,  
  65.                  string strBlobField,  
  66.                  string strBlobContent,  
  67.                  string strWhereClause)  
  68.     {  
  69.         if (strWhereClause == "")  
  70.         {  
  71.             return false;  
  72.         }  
  73.  
  74.         try 
  75.         {  
  76.             string strSQL = "UPDATE " + strTable + " SET " + strBlobField + " =:blob " +  
  77.                 "WHERE " + strWhereClause;  
  78.  
  79.             OleDbCommand cmd = new OleDbCommand(strSQL, pDbConn);  
  80.             cmd.Parameters.Add(strBlobField, SqlDbType.Binary);  
  81.             //    byte[] dataBlob = new byte[strBlobContent.Length];  
  82.             byte[] dataBlob = System.Text.Encoding.Default.GetBytes(strBlobContent);  
  83.             cmd.Parameters["blob"].Value = dataBlob;  
  84.             int result = cmd.ExecuteNonQuery();  
  85.             if (result < 1)  
  86.             {  
  87.                 return false;  
  88.             }  
  89.         }  
  90.         catch (Exception ex)  
  91.         {  
  92.             MessageBox.Show(ex.Message, "写数据", MessageBoxButtons.OK);  
  93.             return false;  
  94.         }  
  95.  
  96.         return true;  
  97.     } 

问题1:无法一次性开辟充足大空间(如1G),写入大视频时,会招致报内存不足.

问题2:System.Convert.ToInt32()会使3G的视频时,会报范例转换失利,数值值过大.

上面两个问题在网络中全部的办法中都广泛存在的,城市招致无法导入700M以上的视频数据.

OLEDB办法对ORCLE 8今后的大字段操作不在支持,我在办理问题的历程中转向了OracleClient命名空间下的办法来操作BLOB大字段,主要参考微软官方http://msdn.microsoft.com/zh-cn/library/cydxhzhz(v=VS.90).aspx和博客园中的http://www.cnblogs.com/zhengmaoch/archive/2005/08/10/212014.html.这两份资料对我办理500M以下数据量的视频很有帮忙,但是1G乃至是3G以上视频数据是无法办理的.上面两处利用了事件处理在导500M以上数据时,会报“ORA-22297: warning: Open LOBs exist at transaction commit time ”错误,主要因为提交事件时数据文件没有读完.

经过试验和参考http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx办法,终于完好办理上面两个问题,实现大视频量数据导入BLOB字段.

  1. /// <summary>  
  2. /// 2010.10.22  
  3. /// 读取视频数据进入ORACLE大字段中  
  4. /// </summary>  
  5. /// <param name="fileToUpload"></param>  
  6. /// <param name="uploadSQL"></param>  
  7. /// <returns></returns>  
  8. public bool OracleUpload(string fileToUpload, string uploadSQL)  
  9. {  
  10.     /*  
  11.      * Get Connected  
  12.      */ 
  13.     string connection = strConn;  
  14.     OracleConnection conn;  
  15.     conn = new OracleConnection(connection);  
  16.     conn.Open();  
  17.     OracleCommand cmd = new OracleCommand(uploadSQL, conn);  
  18.     OracleTransaction transaction = conn.BeginTransaction();  
  19.     cmd.Transaction = transaction;  
  20.     OracleDataReader reader = cmd.ExecuteReader();  
  21.     using (reader)  
  22.     {  
  23.         try 
  24.         {  
  25.             reader.Read();  
  26.             OracleLob tmpBlob = reader.GetOracleLob(4);  
  27.             reader.Close();  
  28.             FileStream fsBlob = new FileStream(fileToUpload, FileMode.OpenOrCreate, FileAccess.Read);  
  29.             //BinaryReader br = new BinaryReader(fs);  
  30.             tmpBlob.BeginBatch(OracleLobOpenMode.ReadWrite);  
  31.             long length = fsBlob.Length;  
  32.  
  33.             int numBytesToRead = System.Convert.ToInt32(length / 10);//办理问题2  
  34.             int numBytesRead = 0;  
  35.             int n;  
  36.             byte[] Buffer = new byte[numBytesToRead];  
  37.             //2010.10.25  改正加 将文件分为10块 避免文件为3.3G以上  
  38.              //办理问题1  
  39.             for (int i = 0; i < 9; i++)   
  40.             {  
  41.                   
  42.                 n = 0;  
  43.                // numBytesToRead = length / 5;  
  44.                 Buffer = new byte[numBytesToRead];   
  45.                 numBytesRead = 0;  
  46.                 while ((n = fsBlob.Read(Buffer, numBytesRead, numBytesToRead)) > 0)  
  47.                 {  
  48.                     numBytesRead += n;  
  49.                     numBytesToRead -= n;  
  50.                 }  
  51.                 numBytesToRead = System.Convert.ToInt32(length / 10);  
  52.                 tmpBlob.Write(Buffer, 0, numBytesToRead);  
  53.             }  
  54.  
  55.  
  56.             numBytesToRead = System.Convert.ToInt32(length / 10+ length % 10);  
  57.             numBytesRead = 0;  
  58.             n = 0;  
  59.             int tmpLength = numBytesToRead;  
  60.             byte[] Buffer2 = new byte[tmpLength];  
  61.             while ((n = fsBlob.Read(Buffer2, numBytesRead, numBytesToRead)) > 0)  
  62.             {  
  63.                 numBytesRead += n;  
  64.                 numBytesToRead -= n;  
  65.             }  
  66.             //numBytesToRead = tmpLength;  
  67.             tmpBlob.Write(Buffer2, 0, tmpLength);  
  68.  
  69.             fsBlob.Close();  
  70.             tmpBlob.EndBatch();  
  71.             cmd.Parameters.Clear();  
  72.             Buffer = null;      
  73.         }  
  74.         catch(Exception ex)  
  75.         {  
  76.             MessageBox.Show("出错:"+ex.Message);  
  77.             //关闭  
  78.             reader.Close();  
  79.             transaction.Commit();  
  80.             conn.Close();  
  81.             return false;  
  82.         }  
  83.     }  
  84.  
  85.     reader.Close();  
  86.     transaction.Commit();  
  87.     conn.Close();  
  88.     return true;  

上面的办法完万能处理4G以下的视频数据的导入问题,已经经过考证的.PLSQL Developer工具一样无法读取BLOB字段中的大数据量的视频,如需读取请具体参照http://www.cnblogs.com/wuhenke/archive/2010/10/25/1860752.html

  1. /// <summary>  
  2. /// 从数据库中读出大字段到文件中  
  3. /// </summary>  
  4. /// <param name="uploadSQL"></param>  
  5. /// <returns></returns>  
  6. public bool OracleRead(string uploadSQL)  
  7. {  
  8.     string connection = strConn;  
  9.     OracleConnection conn;  
  10.     conn = new OracleConnection(connection);  
  11.     conn.Open();  
  12.  
  13.  
  14.     OracleCommand cmd = new OracleCommand(uploadSQL, conn);  
  15.     long readStartByte = 0;//从BLOB数据体的何处开始读取数据  
  16.     int hopeReadSize = 1024; //但愿每次从BLOB数据体中读取数据的大小  
  17.     long realReadSize = 0;//每次实际从BLOB数据体中读取数据的大小  
  18.     //CommandBehavior.SequentialAccess将使OracleDataReader以流的方法加载BLOB数据  
  19.     string filename = "F:\\Test"+DateTime.Now.Day+DateTime.Now.Minute+DateTime.Now.Second+".avi";  
  20.     OracleDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);  
  21.     while (dr.Read())  
  22.     {  
  23.         FileStream fs = new FileStream(filename, FileMode.Create);  
  24.         byte[] buffer = new byte[hopeReadSize];  
  25.         realReadSize = dr.GetBytes(0, readStartByte, buffer, 0, hopeReadSize);  
  26.         //循环,每次读取1024byte大小,并将这些字节写入流中  
  27.         while ((int)realReadSize == hopeReadSize)  
  28.         {  
  29.             fs.Write(buffer, 0, hopeReadSize);  
  30.             readStartByte += realReadSize;  
  31.             realReadSize = dr.GetBytes(0, readStartByte, buffer, 0, hopeReadSize);  
  32.         }  
  33.         //读取BLOB数据体最后剩余的小于1024byte大小的数据,并将这些字节写入流中  
  34.         realReadSize = dr.GetBytes(0, readStartByte, buffer, 0, hopeReadSize);  
  35.         fs.Write(buffer, 0, (int)realReadSize);  
  36.     }             
  37.     //transaction.Commit();  
  38.     conn.Close();  
  39.         return true;  
  以上是“Oracle中操纵BLOB字段存储4GB以下视频数据[Oracle防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • SQL Server中利用Linkserver衔接Oracle的办法
  • Oracle数据库网络与安全FAQ精辟堆积
  • Ubuntu 9.10下安装Oracle10g
  • Ubuntu 10.04 下安装Oracle 11g
  • oracle盲注报错语句和oracle提权语句汇总
  • oracle中to_char、to_number、to_date的用法
  • Python模拟Oracle的SQL/PLUS工具的实现办法
  • Oracle数据库访谈之最年青的OCM访谈
  • oracle表数据误删复原
  • Oracle数据库笔记--表空间
  • Oracle数据库树形查询的代码示例
  • oracle中记录和调集
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .