关于Oracle中大对象的一些处理方法和实例.docx

上传人:b****1 文档编号:23210897 上传时间:2023-05-15 格式:DOCX 页数:19 大小:20.73KB
下载 相关 举报
关于Oracle中大对象的一些处理方法和实例.docx_第1页
第1页 / 共19页
关于Oracle中大对象的一些处理方法和实例.docx_第2页
第2页 / 共19页
关于Oracle中大对象的一些处理方法和实例.docx_第3页
第3页 / 共19页
关于Oracle中大对象的一些处理方法和实例.docx_第4页
第4页 / 共19页
关于Oracle中大对象的一些处理方法和实例.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

关于Oracle中大对象的一些处理方法和实例.docx

《关于Oracle中大对象的一些处理方法和实例.docx》由会员分享,可在线阅读,更多相关《关于Oracle中大对象的一些处理方法和实例.docx(19页珍藏版)》请在冰豆网上搜索。

关于Oracle中大对象的一些处理方法和实例.docx

关于Oracle中大对象的一些处理方法和实例

在oracle中,有4个大对象(lobs)类型可用,分别是blob,clob,bfile,nclob。

下面是对lob数据类型的简单介绍。

blob:

二进制lob,为二进制数据,最长可达4GB,存贮在数据库中。

clob:

字符lob,字符数据,最长可以达到4GB,存贮在数据库中。

bfile:

二进制文件;存贮在数据库之外的只读型二进制数据,最大长度由操作系统限制。

nclob:

支持对字节字符集合(nultibytecharacterset)的一个clob列。

对于如何检索和操作这些lob数据一直是oracle数据库开发者经常碰到的问题。

下面我将在oracle对lob数据处理的一些方法和技巧,介绍给读者,希望能够对读者以后的开发有所帮助。

oracle中可以用多种方法来检索或操作lob数据。

通常的处理方法是通过dbms_lob包。

其他的方法包括使用api(applicationprogramminginterfaces)应用程序接口和oci(oraclecallinterface)oracle调用接口程序。

一、在oracle开发环境中我们可以用dbms_lob包来处理!

dbms_lob包功能强大,简单应用。

既可以用来读取内部的lob对象,也可以用来处理bfile对象。

但处理两者之间,还有一点差别。

处理内部lob对象(blob,clob)时,可以进行读和写,但处理外部lob对象bfile时,只能进行读操作,写的操作可以用pl/sql处理。

另外用sql也可以处理lob,但要注意sql仅可以处理整个lob,不能操作lob的数据片。

在dbms_lob包中内建了read(),append,write(),erase(),copy(),getlength(),substr()等函数,可以很方便地操作lob对象。

这里不做深入讨论,读者可以参看相关的书籍。

对于pl/sql,下面介绍一种技巧,用动态的pl/sql语句处理clob对象来传替表名!

example1.

动态PL/SQL,对CLOB字段操作可传递表名table_name,表的唯一标志字段名field_id,clob字段名field_name记录号v_id,开始处理字符的位置v_pos,传入的字符串变量v_clob

修改CLOB的PL/SQL过程:

updateclob

createorreplaceprocedureupdateclob(

table_nameinvarchar2,

field_idinvarchar2,

field_nameinvarchar2,

v_idinnumber,

v_posinnumber,

v_clobinvarchar2)

is

loblocclob;

c_clobvarchar2(32767);

amtbinary_integer;

posbinary_integer;

query_strvarchar2(1000);

begin

pos:

=v_pos*32766+1;

amt:

=length(v_clob);

c_clob:

=v_clob;

query_str:

=''select''||field_name||''from''||table_name||''where''||field_id||''=:

idforupdate'';

--initializebufferwithdatatobeinsertedorupdated

  EXECUTEIMMEDIATEquery_strINTOloblocUSINGv_id;

  --fromposposition,write32766varchar2intolobloc

  dbms_lob.write(lobloc,amt,pos,c_clob);

  commit;

  exception

  whenothersthen

  rollback;

  end;

  l/用法说明:

  在插入或修改以前,先把其它字段插入或修改,CLOB字段设置为空empty_clob(),

  然后调用以上的过程插入大于2048到32766个字符。

  如果需要插入大于32767个字符,编一个循环即可解决问题。

  查询CLOB的PL/SQL函数:

getclob

  createorreplacefunctiongetclob(

  table_nameinvarchar2,

  field_idinvarchar2,

  field_nameinvarchar2,

  v_idinnumber,

  v_posinnumber)returnvarchar2

  is

  loblocclob;

  buffervarchar2(32767);

  amountnumber:

=2000;

  offsetnumber:

=1;

  query_strvarchar2(1000);

  begin

  query_str:

=''select''||field_name||''from''||table_name||''where''||field_id||''=:

id'';

  --initializebufferwithdatatobefound

  EXECUTEIMMEDIATEquery_strINTOloblocUSINGv_id;

  offset:

=offset+(v_pos-1)*2000;

  --read2000varchar2fromthebuffer

  dbms_lob.read(lobloc,amount,offset,buffer);

  returnbuffer;

  exception

  whenno_data_foundthen

  returnbuffer;

  end;

  l用法说明:

  用selectgetclob(table_name,field_id,field_name,v_id,v_pos)aspartstrfromdual;

  可以从CLOB字段中取2000个字符到partstr中,

  编一个循环可以把partstr组合成dbms_lob.getlength(field_name)长度的目标字符串。

   

  二、对于在其他不同的开发环境,例如vc,vb,pb,java等环境下对lob的处理,处理方法不尽相同,在这里将简要举几个例子来说明不在oracle开发环境下对lob的处理。

  

(一)在pb中的处理

  exampler2.

  stringls_path,ls_filename,ls_jhdh

  longll_num,ll_count,rtn

  blobole_blob

  ll_num=dw_lb.getrow()

  ifll_num>0thenls_jhdh=dw_lb.object.ct_njhdh[ll_num]

  selectcount(*)into:

ll_countfromsj_jh_jhfjbwherect_jhdlxbh=''1''andct_jhdh=:

ls_jhdhandct_jdlxbh=:

is_jdlx;

  ifll_count>0then

  rtn=messagebox("提示","是否要修改此附件",question!

yesno!

1)

  ifrtn=1then

  SELECTBLOBct_jhfjnrINTOle_blobfromsj_jh_jhfjbwherect_jhdlxbh=''1''andct_jhdh=:

ls_jhdhandct_jdlxbh=:

is_jdlx;

  ole_1.objectdata=ole_blob

  Ifole_1.activate(offsite!

)<>0Then

  Messagebox("OLEActivate","不能激活")

  Return-1

  endIf

  endif

  else

  messagebox("提示","没有附件")

  endif

  endif

  

(二)在vb中的处理

  在vb中处理大对象,一般可以用OO4O(oracleobjectsforole)来处理大对象。

这里介绍一种不用0040处理大对象blob的方法。

  下面这段程序可以将一个文件(文本文件,doc文件,图象文件等)保存到数据库中,并可以将其从数据库读出

  需要两个commandbutton

  cmd1名称cmdsavecaption保存

  cmd2名称cmdreadcaption读取

  一个cmddialog控件

  同时需要创建一张表t_demo(字段id类型number,;字段text类型blob;)

  exmple3.

  OptionExplicit

  DimrnAsADODB.Connection

  PublicFunctionCreateDataSource(DataSourceAsString,UserIDAsString,PasswordAsString)AsBoolean

  OnErrorGoToDbConErr:

  Setrn=NewADODB.Connection

  Withrn

  .ConnectionString="Provider=OraOledb.Oracle.1;"&_

  "password="[$Password&"]"&_

  "UserID="[$UserID&"]"&_

  "DataSource="[$DataSource&"]"&_

  "LocaleIdentifier=2052"

  .Open

  EndWith

  CreateDataSource=True

  ExitFunction

  DbConErr:

  CreateDataSource=False

  EndFunction

PrivateSubcmdRead_Click()

  DimrsAsNewADODB.Recordset

  rs.ActiveConnection=rn

  rs.LockType=adLockOptimistic

  rs.CursorLocation=adUseClient

  rs.Source="select*fromt_demo"

  rs.Open

  ComDlgDir.DialogTitle="保存文件"

  ComDlgDir.Filter="*.*"

  ComDlgDir.ShowSave

  CallBlobToFile(rs.Fields("text"),ComDlgDir.filename)

  Setrs=Nothing

  ExitSub

  Setrs=Nothing

  EndSub

  PrivateSubcmdsave_Click()

  DimrsAsNewADODB.Recordset

  rs.ActiveConnection=rn

  rs.LockType=adLockOptimistic

  rs.CursorLocation=adUseClient

  rs.Source="select*fromt_demo"

  rs.Open

  rs.AddNew

  ComDlgDir.DialogTitle="选取文件"

  ComDlgDir.ShowOpen

  rs.Fields("id").Value=1

  IfComDlgDir.filename<>""Then

  CallFileToBlob(rs.Fields("text"),ComDlgDir.filename)

  rs.Update

  EndIf

  Setrs=Nothing

  ExitSub

  Setrs=Nothing

  EndSub

  PrivateSubForm_Load()

  IfNotCreateDataSource("sid","systemp","manager")Then

  MsgBox"Connectionfailure!

"

  EndIf

  EndSub

fldAsADODB.Field,filenameAsString,OptionalChunkSizeAsLong=8192)

  DimfnumAsInteger,bytesleftAsLong,bytesAsLong

  Dimtmp()AsByte

  If(fld.AttributesAndadFldLong)=0Then

  Err.Raise1001,,"fielddoesn''tsupporttheGetChunkmethod."

  EndIf

  IfDir$(filename)=""ThenErr.Raise53,,"Filenotfound"

  fnum=FreeFile

  OpenfilenameForBinaryAsfnum

  bytesleft=LOF(fnum)

  DoWhilebytesleft

  bytes=bytesleft

  Ifbytes>ChunkSizeThenbytes=ChunkSize

  ReDimtmp(1Tobytes)AsByte

  Getfnum,,tmp

  fld.AppendChunktmp

  bytesleft=bytesleft-bytes

  Loop

  Close#fnum

  EndSub

  SubBlobToFile(fldAsADODB.Field,filenameAsString,OptionalChunkSizeAsLong=8192)

  DimfnumAsInteger,bytesleftAsLong,bytesAsLong

  Dimtmp()AsByte

  If(fld.AttributesAndadFldLong)=0Then

  Err.Raise1001,,"fielddoesn''tsupporttheGetChunkmethod."

  EndIf

  IfDir$(filename)<>""ThenKillfilename

  fnum=FreeFile

  OpenfilenameForBinaryAsfnum

  bytesleft=fld.ActualSize

  DoWhilebytesleft

  bytes=bytesleft

  Ifbytes>ChunkSizeThenbytes=ChunkSize

  tmp=fld.GetChunk(bytes)

  Put#fnum,,tmp

  bytesleft=bytesleft-bytes

  Loop

  Close#fnum

  EndSub

(三)用jdbc处理lob

  exmple4.

  首先是GettingBLOBandCLOBLocatorsfromaResultSet

  //SelectLOBlocatorintostandardresultset.

  ResultSetrs=stmt.executeQuery("SELECTblob_col,clob_colFROMlob_table");

  while(rs.next())

  {//GetLOBlocatorsintoJavawrapperclasses.

  oracle.jdbc2.Blobblob=(oracle.jdbc2.Blob)rs.getObject

(1);

  oracle.jdbc2.Clobclob=(oracle.jdbc2.Clob)rs.getObject

(2);

  [...process...]

  }

  然后是ReadBLOBdatafromBLOBlocator.

  InputStreambyte_stream=my_blob.getBinaryStream();

  byte[]byte_array=newbyte[10];

  intbytes_read=byte_stream.read(byte_array);

  和WritingBLOBData

  java.io.OutputStreamoutstream;

  //readdataintoabytearray

  byte[]data={0,1,2,3,4,5,6,7,8,9};

  //writethearrayofbinarydatatoaBLOB

  outstream=((BLOmy_blob).getBinaryOutputStream();

  outstream.write(data);

  还有PassingaBLOBLocatortoaPreparedStatement

  OraclePreparedStatementops=(OraclePreparedStatement)conn.prepareStatement

  "INSERTINTOblob_tableVALUES(?

)");

  ops.setBLOB(1,my_blob);

  ops.execute();

  最后应该注意:

  insert的时候一定要用empty_blob()初始化

  stmt.execute("insertintomy_blob_tablevalues(''row1'',empty_blob()");

  (四)在pro*c中的处理

  PRO*C可以用三种方式对LOB字段处理。

  1、TheDBMS_LOBpackageinsidePL/SQLblocks.

  2、OCI(OracleCallInterface)functioncalls.

  3、EmbeddedSQLstatements.

  EmbeddedSQLstatements.的方式简单而且比较灵活。

OTN上提供一个例子:

  InthisexamplewewillbereadingdatafromaBLOBwithanunknownarbitrarylengthintoabufferandthenwritingthedatafromthebufferintoanexternalfile.

  Ourbufferissmall,sodependingonthesizeoftheBLOBwearereading,wemay

  beabletoreadtheBLOBvalueintothebufferinasingleREADstatementorwe

  mayberequiredtoutilizeastandardpollingmethodinstead.

  Firstwestartoffwithoci.handsomesimplelocalvariabledeclarations

  example5.

  #include

  OCIBlobLocator*blob;

  FILE*fp;

  unsignedintamt,offset=1;

  NowweneedabuffertostoretheBLOBvalueandthenwritetothefilefrom:

  #defineMAXBUFLEN5000

  unsignedcharbuffer[MAXBUFLEN];

  EXECSQLVARbufferISRAW(MAXBUFLEN);

  AllocatetheBLOBhostvariableandselectaBLOBwhichwewillREAD:

  EXECSQLALLOCATE:

blob;

  EXECSQLSELECTa_blobINTO:

blobFROMlob_tableWHERE...;

  WecanthenopentheexternalfiletowhichwewillwritetheBLOBvalue:

  fp=fopen((constchar*)"image.gif",(constcha

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 唐诗宋词

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1