设为首页 收藏本站
查看: 779|回复: 0

[经验分享] 向Oracle数据库blob图片字段写入图片流

[复制链接]
YunVN网友  发表于 2016-8-14 06:09:21 |阅读模式
资料一:
//--------------ORACLE   保存图片   
  grant   create   any   directory   to   scott;   
  grant   create   any   library   to   scott;   
  create   or   replace   directory   utllobdir   as   'd: oracle';   
  create   table   bfile_tab   (bfile_column   BFILE);   
  create   table   utl_lob_test   (blob_column   BLOB);   
  set   serveroutput   on   
  然后执行下面语句就将d: oracle目录下的Azul.jpg存入到utl_lob_test   
  表中的blob_column字段中了。   
  declare   
        a_blob     BLOB;   
        a_bfile   BFILE   :=   BFILENAME('UTLLOBDIR','Azul.jpg');   
  begin   
        insert   into   bfile_tab   values   (a_bfile)   
            returning   bfile_column   into   a_bfile;   
        insert   into   utl_lob_test   values   (empty_blob())   
            returning   blob_column   into   a_blob;   
        dbms_lob.fileopen(a_bfile);   
        dbms_lob.loadfromfile(a_blob,   a_bfile,   dbms_lob.getlength(a_bfile));   
        dbms_lob.fileclose(a_bfile);   
        commit;   
  end;   
  /
资料二:
ORACLE中LOB字段的使用和维护     
  --------------------------------------------------------------------------------   
  摘要:本文通过实例介绍了在ORACLE数据库中通过DBMS_LOB包使用和维护LOB数据类型的基本方法。     
   
  关键词:ORACLE     DBMS_LOB     LOB     维护      
   
          中图分类号:TP31      
   
  1、引言      
  随着社会的发展,在现代信息系统的开发中,需要存储的已不仅仅是简单的文字信息,同时还包括一些图片和音像资料或者是超长的文本。比如开发一套旅游信息系统,每一个景点都有丰富的图片、音像资料和大量的文字介绍。这就要求后台数据库要有存储这些数据的能力。ORACLE公司在其Oracle8i中通过提供LOB字段实现了该功能。     
   
  为了便于读者的理解,我们先介绍一些基本的概念:     
   
  在ORACLE数据库中,LOB(Large   Objects—大对象)是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的数据)。目前,它又分为两种类型:内部LOB和外部LOB。内部LOB将数据以字节流的形式存储在数据库的内部。因而,内部LOB的许多操作都可以参与事务,也可以像处理普通数据一样对其进行备份和恢复操作。Oracle8i支持三种类型的内部LOB:BLOB(二进制数据)、CLOB(单字节字符数据)、NCLOB(多字节国家字符数据)。其中CLOB和NCLOB类型适用于存储超长的文本数据,BLOB字段适用于存储大量的二进制数据,如图像、视频、音频等。目前,Oracle8i只支持一种外部LOB类型,即BFILE类型。在数据库内,该类型仅存储数据在操作系统中的位置信息,而数据的实体以外部文件的形式存在于操作系统的文件系统中。因而,该类型所表示的数据是只读的,不参与事务。该类型可帮助用户管理大量的由外部程序访问的文件。     
   
  为了方便下文的叙述,我们假定使用如下语句在数据库中创建了一张表。     
   
  CREATE   TABLE   view_sites_info         
        (        
  site_id               NUMBER(3),
              audio                     BLOB     DEFAULT   empty_blob(),  
              document       CLOB     DEFAULT   empty_clob(),     
  video_file       BFILE     DEFAULT   NULL,     
  constraint   PK_TAB_view_sites_info   primary   key   (site_id)     
  );         
  2、LOB的使用和维护      
  ORACL提供了多种使用和维护LOB的方式,如使用PL/SQL   DBMS_LOB包、调用OCI(Oracle   Call   Interface)、使用Proc   *   C/C++、使用JDBC等。其中最为方便有效的是使用PL/SQL调用DBMS_LOB包,本文就将介绍该方法。     
  在Oracle中,存储在LOB中数据称为LOB的值,如使用Select   对某一LOB字段进行选择,则返回的不是LOB的值,而是该LOB字段的定位器(可以理解为指向LOB值的指针)。如执行如下的SQL语句:   
  DELCARE     
                AUDIO_INFO     BLOB;     
  BENGIN     
                SELECT   audio   INTO   AUDIO_INFO   FROM   view_sites_info  
                WHERE   site_id=100;      
  END;     
  /         
  存储在AUDIO_INFO变量中的就是LOB定位器,而不是LOB的值。而要对某一LOB的值进行访问和维护操作,必需通过其定位器来进行。DBMS_LOB包中提供的所有函数和过程都以LOB定位器作为参数。         
  2.1内部LOB      
  DBMS_LOB包中主要提供了以下几个过程供用户对内部LOB字段进行维护。      
  APPEND()                       将源LOB中的内容加到目的LOB中     
  COPY()                         从源LOB中复制数据到目的LOB     
  ERASE()                                       删除LOB中全部或部分内容     
  TRIM()                                           将LOB值减少到指定的长度   
  WRITE()                                       向LOB   中写入数据     
  COMPARE()                 比较两个同种数据类型的LOB的部分或全部值是否相同
  GETLENGTH()                             获取LOB的长度     
  READ()                                           从LOB中读出数据     
  下面我们以最为常用的读和写为例详细介绍这些过程的用法。     
   
  首先介绍一下写过程。该过程的语法为:     
   
  PROCEDURE   WRITE   (        
            lob_loc     IN   OUT     BLOB,     
            amount       IN             BINARY_INTEGER,     
            offset       IN             INTEGER,     
            buffer       IN             RAW);     
                      PROCEDURE   WRITE   (     
            lob_loc     IN   OUT     CLOB       CHARACTER   SET   ANY_CS,   
            amount       IN             BINARY_INTEGER,     
            offset       IN             INTEGER,     
            buffer       IN             VARCHAR2   CHARACTER   SET   lob_loc%CHARSET);     
   
  各参数的含义为:         
                lob_loc:要写入的LOB定位器     
                amount:写入LOB中的字节数     
                  offset:指定开始操作的偏移量     
                buffer:   指定写操作的缓冲区     
  下面的代码就是运用该过程向LOB字段写入数据的示例。     
   
  DECLARE     
            lobloc   CLOB;     
            buffer   VARCHAR2(2000);     
            amount   NUMBER   :=   20;     
            offset   NUMBER   :=   1;     
        BEGIN     
            --初始化要写入的数据         
            buffer   :=   'This   is   a   writing   example';     
            amount   :=   length(buffer);     
           SELECT   document   INTO   lobloc     --   获取定位器并锁定行     
                FROM     view_sites_info     
                WHERE   site_id   =   100   FOR   UPDATE;     
                dbms_lob.write(lobloc,amount,1,buffer);     
            COMMIT;     
        END;     
        /     
   
   
  需要特别指出的是:   
  I.                         在调用写过程前一定要使用SELECT语句检索到定位器且用   FOR   UPDATE   子句锁定行,否则不能更新LOB;     
  II.                   写过程从offset指定的位置开始,向LOB中写入长度为amount的数据,原LOB中在这个范围内的任何数据都将被覆盖。     
  III.               缓冲区的最大容量为32767字节,因此在写入大量数据时需多次调用该过程。     
     
  下面再来介绍一下读过程:     
   
  该过程的语法为:     
   
  PROCEDURE   READ   (  
            lob_loc       IN         BLOB,   
            amount         IN   OUT     BINARY_INTEGER,     
            offset         IN         INTEGER,     
            buffer         OUT       RAW);     
        PROCEDURE   READ   (     
                lob_loc       IN         CLOB           CHARACTER   SET   ANY_CS,   
            amount         IN   OUT     BINARY_INTEGER,     
            offset         IN         INTEGER,     
            buffer         OUT       VARCHAR2   CHARACTER   SET   lob_loc%CHARSET);     
   
  各参数的含义为:     
                lob_loc:要读取的LOB定位器     
                amount:要读取的字节数     
                  offset:开始读取操作的偏移量     
                buffer:   存储读操作结果的缓冲区     
  下面的代码演示了如何使用该过程读取LOB字段中的数据:     
   
        DECLARE     
            lobloc   CLOB;     
            buffer   VARCHAR2(2000);     
            amount   NUMBER   :=   2;     
            offset   NUMBER   :=   6;     
        BEGIN     
   
            SELECT   document   INTO   lobloc     --获取定位器      
                FROM   lob_store         
                WHERE   lob_id   =   100;         
            dbms_lob.read(lobloc,amount,offset,buffer);--读取数据到缓冲区   
   
            dbms_output.put_line(buffer);--显示缓冲区中的数据         
            COMMIT;   
   
        END;     
        /     
资料三:java实现
   
  import   java.sql.*;   
import   java.io.*;   
import   java.util.*;   
//   Importing   the   Oracle   Jdbc   driver   package   makes   the   code   more   readable   
import   oracle.jdbc.driver.*;   
//needed   for   new   CLOB   and   BLOB   classes   
import   oracle.sql.*;   
public   class   LobExample   
{   
public   static   void   main   (String   args   [])   
throws   Exception   
{   
//   Register   the   Oracle   JDBC   driver   
DriverManager.registerDriver(new   oracle.jdbc.driver.OracleDriver());   
//   Connect   to   the   database   
//   You   can   put   a   database   name   after   the   @   sign   in   the   connection   URL.   
Connection   conn   =   
DriverManager.getConnection   ("jdbc:oracle:oci8:@",   "scott",   "tiger");   
//   It's   faster   when   auto   commit   is   off   
conn.setAutoCommit   (false);   
//   Create   a   Statement   
Statement   stmt   =   conn.createStatement   ();   
try   
{   
stmt.execute   ("drop   table   basic_lob_table");   
}   
catch   (SQLException   e)   
{   
//   An   exception   could   be   raised   here   if   the   table   did   not   exist   already.   
}   
//   Create   a   table   containing   a   BLOB   and   a   CLOB   
stmt.execute   ("create   table   basic_lob_table   (x   varchar2   (30),   b   blob,   c   clob)");   
//   Populate   the   table   
stmt.execute   ("insert   into   basic_lob_table   values   ('one',   '010101010101010101010101010101',   'onetwothreefour')");   
stmt.execute   ("insert   into   basic_lob_table   values   ('two',   '0202020202020202020202020202',   'twothreefourfivesix')");   
System.out.println   ("Dumping   lobs");   
//   Select   the   lobs         
ResultSet   rset   =   stmt.executeQuery   ("select   *   from   basic_lob_table");   
while   (rset.next   ())   
{   
//   Get   the   lobs   
BLOB   blob   =   ((OracleResultSet)rset).getBLOB   (2);   
CLOB   clob   =   ((OracleResultSet)rset).getCLOB   (3);   
//   Print   the   lob   contents   
dumpBlob   (conn,   blob);   
dumpClob   (conn,   clob);   
//   Change   the   lob   contents   
fillClob   (conn,   clob,   2000);   
fillBlob   (conn,   blob,   4000);   
}   
System.out.println   ("Dumping   lobs   again");   
rset   =   stmt.executeQuery   ("select   *   from   basic_lob_table");   
while   (rset.next   ())   
{   
//   Get   the   lobs   
BLOB   blob   =   ((OracleResultSet)rset).getBLOB   (2);   
CLOB   clob   =   ((OracleResultSet)rset).getCLOB   (3);   
//   Print   the   lobs   contents   
dumpBlob   (conn,   blob);   
dumpClob   (conn,   clob);   
}   
//   Close   all   resources   
rset.close();   
stmt.close();   
conn.close();     
}   
//   Utility   function   to   dump   Clob   contents   
static   void   dumpClob   (Connection   conn,   CLOB   clob)   
throws   Exception   
{   
//   get   character   stream   to   retrieve   clob   data   
Reader   instream   =   clob.getCharacterStream();   
//   create   temporary   buffer   for   read   
char[]   buffer   =   new   char[10];   
//   length   of   characters   read   
int   length   =   0;   
//   fetch   data      
while   ((length   =   instream.read(buffer))   !=   -1)   
{   
System.out.print("Read   "   +   length   +   "   chars:   ");   
for   (int   i=0;   i<length;   i++)   
System.out.print(buffer);   
System.out.println();   
}   
//   Close   input   stream   
instream.close();   
}   
//   Utility   function   to   dump   Blob   contents   
static   void   dumpBlob   (Connection   conn,   BLOB   blob)   
throws   Exception   
{   
//   Get   binary   output   stream   to   retrieve   blob   data   
InputStream   instream   =   blob.getBinaryStream();   
//   Create   temporary   buffer   for   read   
byte[]   buffer   =   new   byte[10];   
//   length   of   bytes   read   
int   length   =   0;   
//   Fetch   data      
while   ((length   =   instream.read(buffer))   !=   -1)   
{   
System.out.print("Read   "   +   length   +   "   bytes:   ");   
for   (int   i=0;   i<length;   i++)   
System.out.print(buffer+"   ");   
System.out.println();   
}   
//   Close   input   stream   
instream.close();   
}   
//   Utility   function   to   put   data   in   a   Clob   
static   void   fillClob   (Connection   conn,   CLOB   clob,   long   length)   
throws   Exception   
{   
Writer   outstream   =   clob.getCharacterOutputStream();   
int   i   =   0;   
int   chunk   =   10;   
while   (i   <   length)   
{   
outstream.write(i   +   "hello   world",   0,   chunk);   
i   +=   chunk;   
if   (length   -   i   <   chunk)   
chunk   =   (int)   length   -   i;   
}   
outstream.close();   
}   
//   Utility   function   to   put   data   in   a   Blob   
static   void   fillBlob   (Connection   conn,   BLOB   blob,   long   length)   
throws   Exception   
{   
OutputStream   outstream   =   blob.getBinaryOutputStream();   
int   i   =   0;   
int   chunk   =   10;   
byte   []   data   =   {   1,   2,   3,   4,   5,   6,   7,   8,   9,   10   };   
while   (i   <   length)   
{   
data   [0]   =   (byte)i;   
outstream.write(data,   0,   chunk);   
i   +=   chunk;   
if   (length   -   i   <   chunk)   
chunk   =   (int)   length   -   i;   
}   
outstream.close();   
}   
}   
  给你这个例子看看,一看就明白了
资料四:C#实现
比如   
  FileStream   fs=File.OpenRead(path);   
  long   len=fs.Length;   
  byte[]     tempBuff=     new     byte[len];   
  fs.Read(tempBuff,0,   Convert.ToInt32(len));   
  fs.Close();   
  OracleConnection   conn=new   OracleConnection(".....");   
  conn.Open();   
  OracleCommand   cmd=conn.CreateCommand();   
  cmd.CommandText=SpName;//存储过程名   
  cmd.CommandType=CommandType.StoredProcedure;   
  cmd.Parameters.Add("p_filename",OracleType.Varchar2,50);   
  cmd.Parameters["p_filename"].Value=...;   
  ...   
  cmd.Parameters.Add("p_content",OracleType.Blob,len);   
  cmd.Parameters["p_content"].Value=tempBuff;//一个byte类型的数组   
  try   
  {   
      cmd.ExecuteNonQuery();   
  }   
  catch   
  {   
      //   
  }

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-257251-1-1.html 上篇帖子: ssi整合(ibatis支持sqlserver2005、mysql和oracle物理分页) 下篇帖子: oracle调用java 使用socket监听端口测试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表