create or replace procedure proc_updateclob (p_clob clob, p_column varchar2, p_tableName varchar2, p_where varchar2) is
lobloc clob; c_clob varchar2(32767); amt binary_integer; pos binary_integer; query_str varchar2(1000); v_pos number; fullen number; begin v_pos:=0; query_str :='select '||p_column||' from '||p_tableName||' where '||p_where||' for update '; dbms_output.put_line(query_str); EXECUTE IMMEDIATE query_str INTO lobloc; if p_clob is null then begin
对于pl/sql,下面介绍一种技巧,用动态的pl/sql语句处理clob对象来传替表名! example 1. 动态PL/SQL,对CLOB字段操作可传递表名table_name,表的唯一标志字段名field_id,clob字段名field_name记录号v_id,开始处理字符的位置v_pos,传入的字符串变量v_clob
修改CLOB的PL/SQL过程:updateclob create or replace procedure updateclob( table_name in varchar2, field_id in varchar2, field_name in varchar2,v_id in number, v_pos in number, v_clob in varchar2) is lobloc clob; c_clob varchar2(32767); amt binary_integer; pos binary_integer; query_str varchar2(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||'= :id for update '; --initialize buffer with data to be inserted or updated EXECUTE IMMEDIATE query_str INTO lobloc USING v_id; --from pos position, write 32766 varchar2 into lobloc dbms_lob.write(lobloc, amt, pos, c_clob); commit; exception when others then rollback; end; l /用法说明: 在插入或修改以前,先把其它字段插入或修改,CLOB字段设置为空empty_clob(), 然后调用以上的过程插入大于2048到32766个字符。 如果需要插入大于32767个字符,编一个循环即可解决问题。 查询CLOB的PL/SQL函数:getclob create or replace function getclob( table_name in varchar2, field_id in varchar2, field_name in varchar2, v_id in number, v_pos in number) return varchar2 is lobloc clob; buffer varchar2(32767); amount number := 2000; offset number := 1; query_str varchar2(1000); begin query_str :='select '||field_name||' from '||table_name||' where '||field_id||'= :id '; --initialize buffer with data to be found EXECUTE IMMEDIATE query_str INTO lobloc USING v_id; offset:=offset+(v_pos-1)*2000; --read 2000 varchar2 from the buffer dbms_lob.read(lobloc,amount,offset,buffer); return buffer; exception when no_data_found then return buffer; end; l 用法说明: 用select getclob(table_name,field_id,field_name,v_id,v_pos) as partstr from dual; 可以从CLOB字段中取2000个字符到partstr中, 编一个循环可以把partstr组合成dbms_lob.getlength(field_name)长度的目标字符串。 二、对于在其他不同的开发环境,例如vc,vb,pb,java等环境下对lob的处理,处理方法不尽相同,在这里将简要举几个例子来说明不在oracle开发环境下对lob的处理。
(一) 在pb中的处理 exampler 2. string ls_path,ls_filename,ls_jhdh long ll_num,ll_count,rtn blob ole_blob ll_num=dw_lb.getrow() if ll_num>0 then ls_jhdh=dw_lb.object.ct_njhdh[ll_num] select count(*) into :ll_count from sj_jh_jhfjb where ct_jhdlxbh='1' and ct_jhdh=:ls_jhdh and ct_jdlxbh=:is_jdlx; if ll_count>0 then rtn=messagebox("提示","是否要修改此附件",question!,yesno!,1) if rtn=1 then SELECTBLOB ct_jhfjnr INTO le_blob from sj_jh_jhfjb where ct_jhdlxbh='1' and ct_jhdh=:ls_jhdh and ct_jdlxbh=:is_jdlx; ole_1.objectdata =ole_blob If ole_1.activate(offsite!) <> 0 Then Messagebox("OLE Activate","不能激活") Return -1 end If end if else messagebox("提示","没有附件") end if end if (二)在vb中的处理 在vb中处理大对象,一般可以用OO4O(oracle objects for ole)来处理大对象。这里介绍一种不用0040处理大对象blob的方法。 下面这段程序可以将一个文件(文本文件,doc文件,图象文件等)保存到数据库中,并可以将其从数据库读出 需要两个commandbutton cmd1 名称 cmdsave caption 保存 cmd2 名称 cmdread caption 读取 一个cmddialog控件 同时需要创建一张表t_demo(字段id 类型 number,;字段text 类型 blob;) exmple 3. Option Explicit Dim rn As ADODB.Connection Public Function CreateDataSource(DataSource As String, UserID As String, Password As String) As Boolean On Error GoTo DbConErr: Set rn = New ADODB.Connection With rn .ConnectionString = "Provider=OraOledb.Oracle.1;" & _ "password=" & Password & ";" & _ "User ID =" & UserID & ";" & _ "Data Source=" & DataSource & ";" & _ "Locale Identifier=2052" .Open End With CreateDataSource = True Exit Function DbConErr: CreateDataSource = False End Function
Private Sub cmdRead_Click() Dim rs As New ADODB.Recordset rs.ActiveConnection = rn rs.LockType = adLockOptimistic rs.CursorLocation = adUseClient rs.Source = "select * from t_demo" rs.Open ComDlgDir.DialogTitle = "保存文件" ComDlgDir.Filter = "*.*" ComDlgDir.ShowSave Call BlobToFile(rs.Fields("text"), ComDlgDir.filename) Set rs = Nothing Exit Sub Set rs = Nothing End Sub
Private Sub cmdsave_Click() Dim rs As New ADODB.Recordset rs.ActiveConnection = rn rs.LockType = adLockOptimistic rs.CursorLocation = adUseClient rs.Source = "select * from t_demo" rs.Open rs.AddNew ComDlgDir.DialogTitle = "选取文件" ComDlgDir.ShowOpen rs.Fields("id").Value = 1 If ComDlgDir.filename <> "" Then Call FileToBlob(rs.Fields("text"), ComDlgDir.filename) rs.Update End If Set rs = Nothing Exit Sub Set rs = Nothing End Sub
Private Sub Form_Load() If Not CreateDataSource("sid", "systemp", "manager") Then MsgBox "Connection failure!" End If End Sub
fld As ADODB.Field, filename As String, Optional ChunkSize As Long = 8192) Dim fnum As Integer, bytesleft As Long, bytes As Long Dim tmp() As Byte If (fld.Attributes And adFldLong) = 0 Then Err.Raise 1001, , "field doesn't support the GetChunk method."
End If If Dir$(filename) = "" Then Err.Raise 53, , "File not found" fnum = FreeFile Open filename For Binary As fnum bytesleft = LOF(fnum) Do While bytesleft bytes = bytesleft If bytes > ChunkSize Then bytes = ChunkSize ReDim tmp(1 To bytes) As Byte Get fnum, , tmp fld.AppendChunk tmp bytesleft = bytesleft - bytes Loop Close #fnum End Sub