Delphi与Oracle中BLOB字段的操作

首先:先了解一下Oracle中的clob与blob字段
Oracle将LOB分为两种:内部LOB和外部LOB。内部LOB包括CLOB,BLOB和NCLOB三种类型,它们的数据存储在数据库中,并且支持事务操作(提交,回滚,保存点);外部LOB只有BFILE一种类型,该类型的数据被存储在操作系统(OS)文件中,并且不支持事务操作。
其中,CLOB/NCLOB用于存储大批量字符数据,BLOB用于存储大批量二进制数据,而BFILE则存储着指向OS文件的指针.

其次:Delphi连接Oracle数据库
1.如果使用ADO方式进行联接, 需要使用Oracle提供的驱动"oracle provider for ole DB",如果使用"microsoft ole db provider for oracle"在处理时会出现问题(提示无效的字段类型等)
2.最好使用ODAC进行与oracle数据库进行关联,虽然这是第三方控件,但它最大的优点是,在程序发布时不需要任何dll文件,相比ADO,BDE要简便很多,而且ODAC的使用还是很广的。

第三:用delphi编写clob,blob字段的读写等操作
1.建立测试表
  create table ttt(id integer primary key,b blob,c clob);
2.存入测试数据(我为了方便直接插入一条)
  insert into ttt values(1,'','');   //****注意,虽然这里可以正常执行,但我犯一个严重的错误为以后的操作埋下隐患*****//
  commit;
3.打开delphi开在桌面上放置一上memo控件用来显示clob,与blob的内容(我这里只对blob进行说明)
插入数据Insert:
procedure TForm1.Button3Click(Sender: TObject);
var
  vstream: TMemoryStream;
begin
  vstream := TMemoryStream.Create;
  memo1.Lines.SaveToStream(vstream);
  adoquery1.SQL.Text := 'select * from TTT';
  adoquery1.Open;
  adoquery1.Append;   //   写BLOB字段之前使   处于编辑状态。
  adoquery1.FieldByName('ID').Value := 2;
  TBlobField(adoquery1.FieldByName('b')).LoadFromStream(vstream);
  adoquery1.Post;
end;
修改数据Edit:
procedure TForm1.Button1Click(Sender: TObject);
var
  vstream: TMemoryStream;
begin
  orasession1.StartTransaction;
  vstream := TMemoryStream.Create;
  memo1.Lines.SaveToStream(vstream);
  with oraquery2 do
  begin
    close;
    sql.text := ' select * from TTT where id=1';
    open;
    oraquery2.Edit;
    TBlobField(FieldByName('b')).LoadFromStream(vstream);
    post;
  end;
  orasession1.Commit;
end;

在这里出现的问题,在POST时提示字段类型等错误,在经过反复测试后,觉得代码上没有问题,不知其原因所在,唉...一点点查吧
将select * from TTT where id=1 换成select * from TTT where id=2;却没有问题,这样就想到了,id=1的记录是我手工insert的,
而id=2是程序保存的于时查了一下oracle中对于blob与clob字段的说明:对于clob与blob字段要利用DBMS包进行初始化,如这样:
insert into ttt values(1,empty_clob(),empty_blob())
删除id=1重新insert后,一切正常了。

总结:在网上也有相关的贴子讨论clob,blob字段显示数据不全的问题,其实都是因为对于oracle的字段有些不理解,进行数据库应用开发,常握数据库知识也很重要。


修改代码

var
  ms,ms1: TMemoryStream;     //Memory Stream for blob insert
  t :tfilestream;
begin
      //创建内存流并保存图片框中位图
      ms := TMemoryStream.Create;
      ms1 := TMemoryStream.Create;
      ms1.LoadFromFile('d:\ABEJ12024111D802355Z.pdf');
      ms1.Position:=0;
      ms1.SaveToStream(ms);
      //Image1.Picture.Graphic.SaveToStream(ms);
      ms.Position:=0;
      with   adoquery1   do
        begin
            close;
            sql.Clear;
            sql.Add( 'update eygle_blob set FPIC=:sfz1 where FID=:xh1');
            parameters.ParamByName('xh1').Value:= 1;
            parameters.ParamByName('sfz1').LoadFromStream(ms,ftBlob);
            ExecSQL;
        end;
        ms.Free;
        ms1.free;


end



----查找文件夹下某种类型的文件  

     --- FindFileName---目录名    Filetpye==文件类型     Tstr --返回值

procedure TForm1.FindFile(FindFileName, Filetpye: string; Tstr: TStrings);
var
  FSearchRec,
  DSearchRec: TSearchRec;
  FindResult: integer;
  function IsDirNotation(ADirName: String): Boolean;
  begin
    Result := (ADirName = '.') or (ADirName = '..');
  end;
begin
  if FindFileName[Length(FindFileName)]<> '\' then
    FindFileName:=FindFileName+'\';
  FindResult := FindFirst(FindFileName+'*.*', faDirectory, DSearchRec);
  //tstr.Add(FindFileName+fsearchrec.Name);
  while FindResult = 0 do
  begin
    if ((DSearchRec.Attr and faDirectory) = faDirectory) and not
      IsDirNotation(DSearchRec.Name) then
    begin
      FindFile(FindFileName+DSearchRec.Name,Filetpye,Tstr);
     // tstr.Add(FindFileName+fsearchrec.Name);
    end;
    FindResult := FindNext(DSearchRec);
  end;
  FindResult := FindFirst(FindFileName+'*.*',faAnyFile+faHidden+
                          faSysFile,FSearchRec);
 // tstr.Add(FindFileName+fsearchrec.Name);
  try
    while FindResult = 0 do
    begin
      //ShowMessage(FindFileName+fsearchrec.Name);
      if  Pos(Filetpye,FindFileName+fsearchrec.Name)>0 then
      begin
        tstr.Add(fsearchrec.Name+'='+FindFileName+fsearchrec.Name);
      end;
      FindResult := FindNext(FSearchRec);


    end;
  finally
    FindClose(FSearchRec);
  end;
  Findclose(DSearchRec);
end;




你可能感兴趣的:(oracle,数据库,Microsoft,Integer,insert,Delphi)