熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

向Oracle數據庫blob圖片字段寫入圖片流

2013-11-13 22:18:34  來源: Oracle 

  資料一

  //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目錄下的Azuljpg存入到utl_lob_test

  表中的blob_column字段中了

  declare

  a_blob     BLOB;

  a_bfile   BFILE   :=   BFILENAME(UTLLOBDIRAzuljpg);

  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_lobfileopen(a_bfile);

  dbms_lobloadfromfile(a_blob   a_bfile   dbms_lobgetlength(a_bfile));

  dbms_lobfileclose(a_bfile);

  commit;

  end;

  /

  資料二

  ORACLE中LOB字段的使用和維護

  

  摘要本文通過實例介紹了在ORACLE數據庫中通過DBMS_LOB包使用和維護LOB數據類型的基本方法

  關鍵詞ORACLE     DBMS_LOB     LOB     維護

  中圖分類號TP

  引言

  隨著社會的發展在現代信息系統的開發中需要存儲的已不僅僅是簡單的文字信息同時還包括一些圖片和音像資料或者是超長的文本比如開發一套旅游信息系統每一個景點都有豐富的圖片音像資料和大量的文字介紹這就要求後台數據庫要有存儲這些數據的能力ORACLE公司在其Oraclei中通過提供LOB字段實現了該功能

  為了便於讀者的理解我們先介紹一些基本的概念

  在ORACLE數據庫中LOB(Large   Objects—大對象)是用來存儲大量的二進制和文本數據的一種數據類型(一個LOB字段可存儲可多達GB的數據)目前它又分為兩種類型內部LOB和外部LOB內部LOB將數據以字節流的形式存儲在數據庫的內部因而內部LOB的許多操作都可以參與事務也可以像處理普通數據一樣對其進行備份和恢復操作Oraclei支持三種類型的內部LOBBLOB(二進制數據)CLOB(單字節字符數據)NCLOB(多字節國家字符數據)其中CLOB和NCLOB類型適用於存儲超長的文本數據BLOB字段適用於存儲大量的二進制數據如圖像視頻音頻等目前Oraclei只支持一種外部LOB類型即BFILE類型在數據庫內該類型僅存儲數據在操作系統中的位置信息而數據的實體以外部文件的形式存在於操作系統的文件系統中因而該類型所表示的數據是只讀的不參與事務該類型可幫助用戶管理大量的由外部程序訪問的文件

  為了方便下文的敘述我們假定使用如下語句在數據庫中創建了一張表

  CREATE   TABLE   view_sites_info

  (

  site_id               NUMBER()

  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)

  );

  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=;

  END;

  /

  存儲在AUDIO_INFO變量中的就是LOB定位器而不是LOB的值而要對某一LOB的值進行訪問和維護操作必需通過其定位器來進行DBMS_LOB包中提供的所有函數和過程都以LOB定位器作為參數

  內部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             VARCHAR   CHARACTER   SET   lob_loc%CHARSET);

  各參數的含義為

  lob_loc要寫入的LOB定位器

  amount寫入LOB中的字節數

  offset指定開始操作的偏移量

  buffer   指定寫操作的緩沖區

  下面的代碼就是運用該過程向LOB字段寫入數據的示例

  DECLARE

  lobloc   CLOB;

  buffer   VARCHAR();

  amount   NUMBER   :=   ;

  offset   NUMBER   :=   ;

  BEGIN

  初始化要寫入的數據

  buffer   :=   This   is   a   writing   example;

  amount   :=   length(buffer);

  SELECT   document   INTO   lobloc        獲取定位器並鎖定行

  FROM     view_sites_info

  WHERE   site_id   =      FOR   UPDATE;

  dbms_lobwrite(loblocamountbuffer);

  COMMIT;

  END;

  /

  需要特別指出的是

  I                         在調用寫過程前一定要使用SELECT語句檢索到定位器且用   FOR   UPDATE   子句鎖定行否則不能更新LOB

  II                   寫過程從offset指定的位置開始向LOB中寫入長度為amount的數據原LOB中在這個范圍內的任何數據都將被覆蓋

  III               緩沖區的最大容量為字節因此在寫入大量數據時需多次調用該過程

  下面再來介紹一下讀過程

  該過程的語法為

  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       VARCHAR   CHARACTER   SET   lob_loc%CHARSET);

  各參數的含義為

  lob_loc要讀取的LOB定位器

  amount要讀取的字節數

  offset開始讀取操作的偏移量

  buffer   存儲讀操作結果的緩沖區

  下面的代碼演示了如何使用該過程讀取LOB字段中的數據

  DECLARE

  lobloc   CLOB;

  buffer   VARCHAR();

  amount   NUMBER   :=   ;

  offset   NUMBER   :=   ;

  BEGIN

  SELECT   document   INTO   lobloc     獲取定位器

  FROM   lob_store

  WHERE   lob_id   =   ;

  dbms_lobread(loblocamountoffsetbuffer);讀取數據到緩沖區

  dbms_outputput_line(buffer);顯示緩沖區中的數據

  COMMIT;

  END;

  /

  資料三java實現

  Java代碼

  import   javasql*;

  import   javaio*;

  import   javautil*;

  //   Importing   the   Oracle   Jdbc   driver   package   makes   the   code   more   readable

  import   oraclejdbcdriver*;

  //needed   for   new   CLOB   and   BLOB   classes

  import   oraclesql*;

  public   class   LobExample

  {

  public   static   void   main   (String   args   [])

  throws   Exception

  {

  //   Register   the   Oracle   JDBC   driver

  DriverManagerregisterDriver(new   oraclejdbcdriverOracleDriver());

  //   Connect   to   the   database

  //   You   can   put   a   database   name   after   the   @   sign   in   the   connection   URL

  Connection   conn   =

  DriverManagergetConnection   (jdbc:oracle:oci:@   scott   tiger);

  //   Its   faster   when   auto   commit   is   off

  connsetAutoCommit   (false);

  //   Create   a   Statement

  Statement   stmt   =   conncreateStatement   ();

  try

  {

  stmtexecute   (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

  stmtexecute   (create   table   basic_lob_table   (x   varchar   ()   b   blob   c   clob));

  //   Populate   the   table

  stmtexecute   (insert   into   basic_lob_table   values   (one      onetwothreefour));

  stmtexecute   (insert   into   basic_lob_table   values   (two      twothreefourfivesix));

  Systemoutprintln   (Dumping   lobs);

  //   Select   the   lobs

  ResultSet   rset   =   stmtexecuteQuery   (select   *   from   basic_lob_table);

  while   (rsetnext   ())

  {

  //   Get   the   lobs

  BLOB   blob   =   ((OracleResultSet)rset)getBLOB   ();

  CLOB   clob   =   ((OracleResultSet)rset)getCLOB   ();

  //   Print   the   lob   contents

  dumpBlob   (conn   blob);

  dumpClob   (conn   clob);

  //   Change   the   lob   contents

  fillClob   (conn   clob   );

  fillBlob   (conn   blob   );

  }

  Systemoutprintln   (Dumping   lobs   again);

  rset   =   stmtexecuteQuery   (select   *   from   basic_lob_table);

  while   (rsetnext   ())

  {

  //   Get   the   lobs

  BLOB   blob   =   ((OracleResultSet)rset)getBLOB   ();

  CLOB   clob   =   ((OracleResultSet)rset)getCLOB   ();

  //   Print   the   lobs   contents

  dumpBlob   (conn   blob);

  dumpClob   (conn   clob);

  }

  //   Close   all   resources

  rsetclose();

  stmtclose();

  connclose();

  }

  //   Utility   function   to   dump   Clob   contents

  static   void   dumpClob   (Connection   conn   CLOB   clob)

  throws   Exception

  {

  //   get   character   stream   to   retrieve   clob   data

  Reader   instream   =   clobgetCharacterStream();

  //   create   temporary   buffer   for   read

  char[]   buffer   =   new   char[];

  //   length   of   characters   read

  int   length   =   ;

  //   fetch   data

  while   ((length   =   instreamread(buffer))   !=   )

  {

  Systemoutprint(Read      +   length   +      chars:   );

  for   (int   i=;   i<length;   i++)

  Systemoutprint(buffer[i]);

  Systemoutprintln();

  }

  //   Close   input   stream

  instreamclose();

  }

  //   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   =   blobgetBinaryStream();

  //   Create   temporary   buffer   for   read

  byte[]   buffer   =   new   byte[];

  //   length   of   bytes   read

  int   length   =   ;

  //   Fetch   data

  while   ((length   =   instreamread(buffer))   !=   )

  {

  Systemoutprint(Read      +   length   +      bytes:   );

  for   (int   i=;   i<length;   i++)

  Systemoutprint(buffer[i]+   );

  Systemoutprintln();

  }

  //   Close   input   stream

  instreamclose();

  }

  //   Utility   function   to   put   data   in   a   Clob

  static   void   fillClob   (Connection   conn   CLOB   clob   long   length)

  throws   Exception

  {

  Writer   outstream   =   clobgetCharacterOutputStream();

  int   i   =   ;

  int   chunk   =   ;

  while   (i   <   length)

  {

  outstreamwrite(i   +   hello   world      chunk);

  i   +=   chunk;

  if   (length      i   <   chunk)

  chunk   =   (int)   length      i;

  }

  outstreamclose();

  }

  //   Utility   function   to   put   data   in   a   Blob

  static   void   fillBlob   (Connection   conn   BLOB   blob   long   length)

  throws   Exception

  {

  OutputStream   outstream   =   blobgetBinaryOutputStream();

  int   i   =   ;

  int   chunk   =   ;

  byte   []   data   =   {                                 };

  while   (i   <   length)

  {

  data   []   =   (byte)i;

  outstreamwrite(data      chunk);

  i   +=   chunk;

  if   (length      i   <   chunk)

  chunk   =   (int)   length      i;

  }

  outstreamclose();

  }

  }

  給你這個例子看看一看就明白了

  資料四C#實現

  比如

  FileStream   fs=FileOpenRead(path);

  long   len=fsLength;

  byte[]     tempBuff=     new     byte[len];

  fsRead(tempBuff   ConvertToInt(len));

  fsClose();

  OracleConnection   conn=new   OracleConnection();

  connOpen();

  OracleCommand   cmd=connCreateCommand();

  cmdCommandText=SpName;//存儲過程名

  cmdCommandType=CommandTypeStoredProcedure;

  cmdParametersAdd(p_filenameOracleTypeVarchar);

  cmdParameters[p_filename]Value=;

  

  cmdParametersAdd(p_contentOracleTypeBloblen);

  cmdParameters[p_content]Value=tempBuff;//一個byte類型的數組

  try

  {

  cmdExecuteNonQuery();

  }

  catch

  {

  //

  }


From:http://tw.wingwit.com/Article/program/Oracle/201311/18734.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.