ORACLE中有个表结构如下:
employee_id:varchar2(10)
employee_photo:Blob1)我想把BMP图片的数据存入employee_photo字段中该怎么做?
PS:我用ADOQUERY连接此表,但每回我用下面的代码打开数据表时出错,为什么啊?
//--------------
adoquery1.close;
adoquery1.sql.text := 'select * from employee';
adoquery1.open;
//--------------
错误信息: "data type is not supported".
2)我现在怎么浏览表中的BOLB数据呢?3)我又该怎么更新employee_photo中的数据呢?各位,请帮忙解答啊。高分送……

解决方案 »

  1.   

    BLOB数据类型使用方法谈林 琪  在实现数据库管理时,根据设计需要,我们往往会设置BLOB类型的字段,BLOB字段的处理直接影响到系统的灵活性,下面笔者将简单介绍在PowerBuilder和Delphi编程环境下使用BLOB字段的方法。  1.BLOB数据类型  BLOB全称为Binary Large Objects,即大型二进制对象。实际上,在一些数据库系统中并不将其称之为BLOB字段,如Access中的OLE对象和备注类型、VFP中的MEMO类型、Oracle中的LONG BINARY类型、Sybase中的 LONG VARCHAR、SQL Server中的IMAGE等等,但从广义上讲,它们都属于BLOB类型。我们可以把BLOB区别为三种形式:声像数据、二进制数据和大文本数据。因此,最常见的应用就是存储图形、声音等对象,此外大型的二进制对象、OLE对象也可以通过BLOB类型存入数据库,如果文本对象过大,超出了文本类型的规定长度,则必须用BLOB字段进行存储。我们在经常使用的编程环境中并不能直接支持BLOB字段,因此需要调用相应的函数完成BLOB的使用。  2. PowerBuilder环境下的BLOB使用  (1)设计BLOB字段  PowerBuilder的主要特点是它的数据窗口,因此首先我们要了解在数据窗口中使用BLOB字段的方法,值得注意的是在数据窗口设置界面中指定数据源的名称时,BLOB类型是不能被选中的,因此需要特别设计。  在数据窗口设计时,先选择Object选单,再选OLE Database BLOB子选单,会出现一个定义BLOB属性的窗口。  (2)操纵BLOB字段  在PowerScript中提供了对BLOB操作的函数如:Blob()、BlobEdit()和BlobMid(),但更为常见的是使用SELECTBLOB和UPDATEBLOB语句。  首先利用SetPicture等函数可以设置BLOB数据,如果BLOB数据已经存在于一个BLOB变量中,可以使用SELECTBLOB和UPDATEBLOB语句将数据写入数据库中。为了保证读入BLOB数据时不会发生混乱,每个含有BLOB字段的表必须建有主键,BLOB数据必须在主键内容存在的条件下写入,因此只能以修改数据表的方式完成。  例如在Oracle数据库中的mytable表中有两个字段,设置分别为:字段名
     类型
     备注
     
    id
     整型
     主键
     
    content
     long binary
     允许为空
       将BLOB写入数据库之前,必须将记录的id字段值写入,再执行下面的语句:  UPDATEBLOB mytable SET content = :blob_var WHERE id = :id USING SQLCA;  IF sqlca.sqlcode=0 then    messagebox("UPDATEBLOB 失 败", sqlca.sqlerrtext)  END IF  这里blob_var为存储有BLOB数据的变量,id为需要写入BLOB数据的记录主键值。与UPDATEBLOB相对应的是SELECTBLOB,使用SELECTBLOB与使用SELECTINTO语句基本相同,但操纵的对象是BLOB数据类型。  3.Delphi环境下的BLOB使用  实现文字材料的数据库管理时,经常会遇到特殊字符的输入和显示问题,如在档案管理中,档案文件名中经常会出现类似于 C3I 这样的上下标形式或其它特殊形式和字符,虽然特殊字符部分可以在编辑控件中显示或浏览,但大多数格式字符如上下标、根号等的显示是不允许的,因此可以利用BLOB字段解决特殊字符输入和显示问题。下面以PARADOX数据库环境为例简单介绍在Delphi环境下的BLOB使用方法。  首先考虑到BLOB字段的性质是不可能直接进行显示的,即不能用类型转化之类的方法,但作为数据集字段可以调用诸如LOADFROMFILE或SAVETOFILE之类的函数,这与OLE控件的方法完全类似,因此可以在原文件表中建立一个新的字段,其类型为BLOB,并为此字段生成一个显示的全局变量。  (1)录入  首先完成OLE控件的编辑工作,按下录入按钮后将其内容保存到当前记录的NEW字段中,由于目前是处理编辑状态,所以标识当前字段的批示符为“I”。其实现方法是先利用SaveToFile将OLE控件中内容保存在临时文件TEMPOLE.NNN中,再将此文件内容调入到表中的NEW字段中(即BLOB字段),在调入前必须保证表处理为可编辑状态。  procedure TForm1.Button1Click(Sender: TObject);  //录入按钮的响应事件  begin   ole1.SaveToFile('tempole.nnn');  //保存OLE控件中内容到临时文件中   table1.edit; //设置表的编辑状态   table1new.LoadFromFile('tempole.nnn');  //调整表中NEW字段的内容为临时文件的内容  DBGrid1.Fields[5].AsString:='1';  //调整表中特殊标志字段的内容为1  end;  (2)显示  下面的事件处理是将当前记录的NEW字段内容读出到OLE控件中,以便用户查看。按下显示按钮的作用就是将当前记录对应的特殊文件名在下面的OLE控件中进行显示。  procedure TForm1.Button2Click(Sender: TObject);  begin  if DBGrid1.Fields[5].AsString='1' then  //若含特殊字符  begin   table1new.SaveToFile('tempole.nnn');  //将表NEW字段的内容保存为临时文件   ole1.LoadFromFile('tempole.nnn');  //将OLE控件的内容调整为临时文件内容   end;  end;  (3)浏览  实际上浏览的实现所采用的方法就是前面的录入和显示方法。  在以上方法基础上就可以方便地实现带特殊字符的表格式浏览了。这里用到了动态创建OleContainer方法,并根据是否有特殊字符将内容调入。  procedure TForm1.Button3Click(Sender: TObject);  var  temp:Array[1..100]of TOleContainer;  i:integer;  begin   showole:=not showole;  //是否浏览   table1.First;   i:=0;   while not table1.eof do   begin   i:=i+1;   if showole=true then   begin   temp[i]:=TOleContainer.Create(self);  //动态创建OLE控件   temp[i].parent:=form1;   temp[i].width:=200;  //设置每个动态生成的OLE控件的大小、位置   temp[i].height:=25;   temp[i].left:=DBGrid1.Left-200;   temp[i].top:=temp[i].Height*(i-1)+DBGrid1.Top+20;   if(table1ole.AsString='1') then //若含特殊字符   begin   table1new.SaveToFile('tempole.nnn');//取字段内容,保存为临时文件   temp[i].LoadFromFile('tempole.nnn');  //将内容调入到动态生成的OLE控件中   end   end   else //取消浏览   temp[i].visible:=false;  //撤消动态生成的OLE控件的显示状态   table1.Next;   end;  end;  这里只利用按钮方式切换浏览状态,要求在浏览和取消浏览操作之间不要有其它操作,但在实际应用中我们是利用多页面的切换自动完成浏览状态的切换的。  (4)补充  在以上的作法中,需要声明一个table1new变量,即根据表中的NEW字段(BLOB类型)所声明的一个长久变量table1new:TblobField,在查询中不可能提前定义好所有可能的字段变量,因此可以用强制类型的方法实现。假设存在查询控件query1和OLE控件filename2,则显示时可以采用以下语句:  with query1.fields.FieldByName('NEW') as TBlobField do savetofile('tempole.nnn');  form1.filename2.LoadFromFile('tempole.nnn');  以上简要介绍了在PB环境和Delphi环境下BLOB数据类型的使用方法,希望大家在今后的编程中用好BLOB数据类型。
      

  2.   

    输入图片到blob字段 
     procedure TForm1.Button1Click(Sender: TObject); 
    var 
    C: TClipboard; 
    begin 
    C := TClipboard.Create; 
    try 
    if Clipboard.HasFormat(CF_BITMAP) then DBImage1.PasteFromClipboard 
    else 
    ShowMessage('Clipboard does not contain a bitmap!'); 
    finally 
    C.Free; 
    end; 
    end; 
    procedure TForm1.Button2Click(Sender: TObject); 
    begin 
    Table1Bitmap.LoadFromFile( 
    'c:\delphi\images\splash\16color\construc.bmp'); 
    end; procedure TForm1.Button3Click(Sender: TObject); 
    var 
    B: TBitmap; 
    begin 
    B := TBitmap.Create; 
    try 
    B.LoadFromFile('c:\delphi\images\splash\16color\athena.bmp'); 
    DBImage1.Picture.Assign(B); 
    finally 
    B.Free; 
    end; 
    end; 
    /////////////////////////////////////////////////////////// 
    var 
    st: TStringStream; 
    begin 
    st := tstringstream.create(''); 
    bitmap.savetostream(st); 
    query1.sql.text := 'insert into table Image_field values :bmp'; 
    query1.parambyname('bmp').asblob := st.datastring; 
    query1.execsql; 
    st.free; 
    end; 
    //////////////////////////////////////////////////////////////////////// 
    unit Unit1; interface {$IFDEF WIN32} 
    uses 
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, ExtCtrls, DBCtrls, Grids, DBGrids, Db, 
    DBTables; 
    {$ELSE} 
    uses 
    SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, 
    Forms, Dialogs, DBTables, DB, Grids, DBGrids, ExtCtrls, StdCtrls; 
    {$ENDIF} type 
    TForm1 = class(TForm) 
    Table1: TTable; 
    DataSource1: TDataSource; 
    DBGrid1: TDBGrid; 
    Image1: TImage; 
    Button1: TButton; 
    Table1Name: TStringField; 
    Table1WMF: TBlobField; 
    OpenDialog1: TOpenDialog; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure DataSource1DataChange(Sender: TObject; Field: TField); 
    private 
    { Private declarations } 
    FileName : string; {Used to hold a temp file name} 
    procedure LoadWMFFromDatabase; {loads a WMF from the database} 
    public 
    { Public declarations } 
    end; var 
    Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); 
    begin 
    {Used for loading metafiles} 
    OpenDialog1.Filter := 'Metafiles (*.wmf)|*.wmf'; 
    OpenDialog1.Options := [ofHideReadOnly, ofNoChangeDir]; 
    Image1.Stretch := true; 
    end; procedure TForm1.FormDestroy(Sender: TObject); 
    begin 
    {Erase the temp file if it exists} 
    if FileName <> '' then 
    DeleteFile(FileName); 
    end; {This function gets a temporary file name form the system} 
    function GetTemporaryFileName : string; 
    {$IFNDEF WIN32} 
    const MAX_PATH = 144; 
    {$ENDIF} 
    var 
    {$IFDEF WIN32} 
    lpPathBuffer : PChar; 
    {$ENDIF} 
    lpbuffer : PChar; 
    begin 
    {Get the file name buffer} 
    GetMem(lpBuffer, MAX_PATH); 
    {$IFDEF WIN32} 
    {Get the temp path buffer} 
    GetMem(lpPathBuffer, MAX_PATH); 
    {Get the temp path} 
    GetTempPath(MAX_PATH, lpPathBuffer); 
    {Get the temp file name} 
    GetTempFileName(lpPathBuffer, 
    'tmp', 
    0, 
    lpBuffer); 
    {Free the temp path buffer} 
    FreeMem(lpPathBuffer, MAX_PATH); 
    {$ELSE} 
    {Get the temp file name} 
    GetTempFileName(GetTempDrive('C'), 
    'tmp', 
    0, 
    lpBuffer); 
    {$ENDIF} 
    {Create a pascal string containg} 
    {the temp file name and return it} 
    result := StrPas(lpBuffer); 
    {Free the file name buffer} 
    FreeMem(lpBuffer, MAX_PATH); 
    end; procedure TForm1.LoadWMFFromDatabase; 
    var 
    FileStream: TFileStream; {a temp file} 
    BlobStream: TBlobStream; {the WMF Blob} 
    begin 
    Image1.Picture.Metafile.Assign(nil); 
    {Create a blob stream for the WMF blob} 
    BlobStream := TBlobStream.Create(Table1WMF, bmRead); 
    if BlobStream.Size = 0 then begin 
    BlobStream.Free; 
    Exit; 
    end; 
    {if we have a temp file then erase it} 
    if FileName <> '' then 
    DeleteFile(FileName); 
    {Get a temp file name} 
    FileName := GetTemporaryFileName; 
    {Create a temp file stream} 
    FileStream := TFileStream.Create(FileName, 
    fmCreate or fmOpenWrite); 
    {Copy the blob to the temp file} 
    FileStream.CopyFrom(BlobStream, BlobStream.Size); 
    {Free the streams} 
    FileStream.Free; 
    BlobStream.Free; 
    {Dispaly the image} 
    Image1.Picture.Metafile.LoadFromFile(FileName); 
    end; {Save a wmf file to the database} 
    procedure TForm1.Button1Click(Sender: TObject); 
    var 
    FileStream: TFileStream; {to load the wmf file} 
    BlobStream: TBlobStream; {to save to the blob} 
    begin 
    {Allow the button to repaint} 
    Application.ProcessMessages; 
    if OpenDialog1.Execute then begin 
    {Turn off the button} 
    Button1.Enabled := false; 
    {Assign the avi file name to read} 
    FileStream := TFileStream.Create(OpenDialog1.FileName, 
    fmOpenRead); 
    Table1.Edit; 
    {Create a BlobStream for the field Table1WMF} 
    BlobStream := TBlobStream.Create(Table1WMF, bmReadWrite); 
    {Seek to the Begginning of the stream} 
    BlobStream.Seek(0, soFromBeginning); 
    {Delete any data that may be there} 
    BlobStream.Truncate; 
    {Copy from the FileStream to the BlobStream} 
    BlobStream.CopyFrom(FileStream, FileStream.Size); 
    {Free the streams} 
    FileStream.Free; 
    BlobStream.Free; 
    {Post the record} 
    Table1.Post; 
    {Load the metafile in to a TImage} 
    LoadWMFFromDatabase; 
    {Enable the button} 
    Button1.Enabled := true; 
    end; 
    end; procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField); 
    begin 
    if (Sender as TDataSource).State = dsBrowse then 
    LoadWMFFromDatabase; 
    end; end. 
      

  3.   

    从blob字段中提取图片 
     procedure TForm1.Button1Click(Sender: TObject); 
    begin 
    Image1.Picture.Bitmap.Assign(Table1Bitmap); 
    end; procedure TForm1.Button2Click(Sender: TObject); 
    var 
    B: TBitmap; 
    begin 
    B := TBitmap.Create; 
    try 
    B.Assign(Table1Bitmap); 
    Image1.Picture.Bitmap.Assign(B); 
    finally 
    B.Free; 
    end; 
    end; 
      

  4.   

    首先感谢楼上的帮忙,从BOLB字段中存入图片取出图片的方法我已知晓。但是现在的关键问题是我根本无法用数据集来打开这个数据表,出错信息为“data type is not supported”。只要这个问题解决,其他的就OK了。烦各位再次帮忙。(偶用的ORACLE9)
    PS:【绝对送分】
      

  5.   

    我也遇到和你一样的问题,每次用ADO连ORACLE的带图片的表就显示错误信息“数据类型不支持”。现在我改用BDE就没有这个问题了。
      

  6.   

    //写入
    var
     MS: TMemoryStream;
    begin
     MS:=TMemoryStream.create;
     Image1.Picture.Bitmap.SaveToStream(MS);
     MS.Position:=0;
     Table1.Append; 
     //在数据库中添加一条记录
     TBlobField(Table1.FieldbyName(’image’)).LoadFromStream(MS);
     Table1.Post; 
     //将所作的更新写入数据库
    end;
    //读取
    var
     MS: TStream;
    begin
     with Table1 do
      MS:=CreateBlobStream(FieldbyName(’image’),bmRead);
     Image1.Picture.Bitmap.
     LoadFromStream(MS);
     MS.Free;
    end;读入
      ADOTable1.Append;
      TBlobField(ADOTable1.FieldByName('image')).LoadFromFile('C:\WINNT\Web\Wallpaper\Windows 2000.jpg');
      ADOTable1.Post;读出
    var
      Jpg:TJPEGImage;
      Buf:TMemoryStream;
    begin
      Jpg:=TJPEGImage.Create;  Buf:=TMemoryStream.Create;
      TBlobField(ADOTable1.FieldByName('image')).SaveToStream(Buf);
      Buf.Position:=0;
      Jpg.LoadFromStream(Buf);
      Image1.Picture.Assign(jpg);  Buf.Free;
      Jpg.Free;
      

  7.   

    将ADOCONNECTION的PROVIDER改一下,改成:Oracle Provider For OLE DB