procedure TMainForm.btnInputPhotoInfoClick(Sender: TObject);
var
  bRst: Boolean;
  msStream: TMemoryStream;
  iSize: Int64;
begin
  if img111.Picture.Graphic = nil then
  begin
    ShowMsg('照片不能为空');
    Exit;
  end;
  msStream := TMemoryStream.Create;
  img111.Picture.Graphic.SaveToStream(msStream);
  msStream.Position := 0;
  bRst := SaveReaderPhoto(Trim(edtCode112.Text),msStream);
  if bRst then
  begin
    ShowMsg('保存照片成功');
  end
  else ShowMsg('保存照片失败');
  FreeAndNil(msStream);
end;function SaveReaderPhoto(const A_sBarCode: string;
  A_msStream: TMemoryStream): Boolean;
begin
  Result := False;
    with SysDM.OraqryReaderInfoData do
    begin
      SQL.Text :=
        'update readerinfo set reader_photo= empty_blob()' +
        ' where reader_barcode = :BarCode';
      ParamByName('BarCode').AsString := Trim(A_sBarCode);
      ExecSQL;
      Close;
      SQL.Text :=
        'update readerinfo set reader_photo = :photo' +
        ' where reader_barcode = :BarCode';
      ParamByName('BarCode').AsString := Trim(A_sBarCode);
      A_msStream.Position := 0;
      ParamByName('photo').LoadFromStream(A_msStream,ftBlob);
      try
        ExecSQL;
           Result := True;
      except
        on E:Exception do
        begin
          WriteLog('Melinets_SaveReaderPhoto/' + E.Message);
        end;
      end;
      Close;
    end;
end;
以上是源码,但是存入到库以后,是空的,谁能帮我看看啊,

解决方案 »

  1.   

    代码找不出错看下msStream值是否正确, 数据表字段是否blob
      

  2.   

    msStrema.size的值大于0。我就真的不明白了。网上好多帖子都这样的,但是我的代码就是存不进去照片。
      

  3.   

    数据表字段类型没问题吧
    我没用过oracle, mssql, mysql之类都是用blob字段存放
      

  4.   

    字符串还是字符集的问题?可是库是unicode的要用al32utf8.
      

  5.   

    不是字符集,是连接字符串的事。Provider=OraOLEDB.Oracle.1;Password=;Persist Security Info=True;User ID=;Data Source=
    用这个字符串就没有问题,关键是驱动OraOLEDB.Oracle.1这个东西
      

  6.   

    我用的不是这个链接。是ODAC的链接方式。
      

  7.   

    Delphi7 中使用ODAC存取图片 
    说明:ODAC组件我不熟悉,在使用它存取图片的时候,特别注意sql的写法。(转载)
    ODAC 组件支持 Oracle8 的 BLOB 和 CLOB 数据类型。
    你可以使用TOraQuery 组件来获取 LOB 字段的值,BLOB 和 CLOB 数据类型通过 LOB 定位器(指定数据地址) 存储在表列中;实际的 BLOB 和 CLOB 数据存储在独立的表空间中。
    当存取 LOB 列时,返回的是定位器。
    要初始化LOB 定位器,你必须使用EMPTY_BLOB 或 EMPTY_CLOB Oracle 函数。
    要返回初始化后的定位器,应在同样的语句中使用RETURNING 子句。
    ODAC 写LOB 数据到Oracle 且返回初始值字段,需使用:值参数. 对 ODAC 来说,在LOB 操作中使用 ParamType 属性是非常重要的。如果 ParamType 是 ptInput , ODAC 写数据到服务器,如果ParamType 是 ptOutput,它则读取数据。
    以下两个例子是从Oracle10g中存/取jpg和bmp图片,需要注意的是在存图片的时候
    SQL语句的写法。
     (1)存图片
     procedure TNewStamp.BitBtn3Click(Sender:TObject); 
    var 
    pic:TMemoryStream; 
    pjpg:tjpegimage; 
    pjpeg:tjpegimage; 
    bmp:tbitmap; 
    begin 
    {//jpg图片
     pjpeg:=tjpegimage.Create; 
    pjpg:=tjpegimage.Create; 
    pjpg.LoadFromFile(‘C:\1112.jpg’);
     pic:=TMemoryStream.Create;
     pjpg.SaveToStream(pic); 
    pic.Position:=0; 
    pjpeg.LoadFromStream(pic); 
    image1.Picture.Assign(pjpeg);
     login.SmartQuery1.Close; 
    login.SmartQuery1.SQL.Clear; 
    login.SmartQuery1.SQL.Add(‘insert into TEST(TEST1,TEST2) VALUES(:t1,EMPTY_BLOB()) returning TEST2 into:TEST2′);
     login.SmartQuery1.ParamByName(‘t1′).AsString:=’123′;
     login.SmartQuery1.ParamByName(‘TEST2′).ParamType:=ptInput;
     login.SmartQuery1.ParamByName(‘TEST2′).AsOraBlob.LoadFromStream(pic);
     login.SmartQuery1.Prepare; 
    login.SmartQuery1.ExecSQL;
     } 
    //bmp图片
    bmp:=tbitmap.Create; 
    pic:=TMemoryStream.Create; 
    bmp.LoadFromFile(‘C:\122.bmp’);
    bmp.SaveToStream(pic); 
    pic.Position:=0;
    login.SmartQuery1.Close; 
    login.SmartQuery1.SQL.Clear;
    login.SmartQuery1.SQL.Add(‘insert into TEST(TEST1,TEST2) VALUES(:t1,EMPTY_BLOB()) returning TEST2 into:TEST2′);
    login.SmartQuery1.ParamByName(‘t1′).AsString:=’124′;
    login.SmartQuery1.ParamByName(‘TEST2′).ParamType:=ptInput;
    login.SmartQuery1.ParamByName(‘TEST2′).AsOraBlob.LoadFromStream(pic);
    login.SmartQuery1.Prepare; 
    login.SmartQuery1.ExecSQL; 
    end;
     (2)取图片
     procedure TNewStamp.BitBtn2Click(Sender:TObject); 
    var 
    pic:TMemoryStream; 
    pjpeg:tjpegimage;//jpg格式图片
     bmp:tbitmap;//bmp格式图片
     begin
     login.OraQuery1.SQL.Clear; 
    login.OraQuery1.SQL.Add(‘select * from TEST ‘);
    login.OraQuery1.AutoCommit:= false; 
    login.OraQuery1.FetchAll:= true; 
    login.OraQuery1.Open;
     if login.OraQuery1.RecordCount = 0 then 
    begin 
    showmessage(‘没有记录’);
     exit; 
    end;
     bmp:=tbitmap.Create; 
    pjpeg:=tjpegimage.Create; 
    pic:=TMemoryStream.Create;
    TBlobField(login.OraQuery1.fieldbyname(‘TEST2′)).savetostream(pic);
    pic.Position:=0; 
    bmp.LoadFromStream(pic); 
    bmp.SaveToFile(‘C:\122.bmp’);
    image1.Picture.Assign(bmp); 
    pic.Free; 
    end;
    ODAC 组件支持Oracle 8 的BLOB 和 CLOB 数据类型。你可以使用TOraQuery 组件来获取LOB 字段的值,使用同样的方法,你也可以获取 LONG 或LONG ROW 字段。
    当你需要使用 SQL DML 及 PL/SQL 语句存取这些字段时,你就会发现 LOB 数据类型的用法有明显的不同。 BLOB 和CLOB 数据类型通过LOB 定位器(指定数据地址) 存储在表列中;实际的 BLOB 和 CLOB 数据存储在独立的表空间中。
    与之不同的是,LONG 或LONG RAW 类型存储在数据库中,表中存放着它们的实际值。
    当存取LOB 列时,返回的是定位器,而不像LONG 或LONG RAW 数据类型那样返回它的
    实际值。
    例如,分析这个表的定义:
    CREATE TABLE ClobTable ( Id NUMBER, Name VARCHAR2(30), Value CLOB ) 
    如果我们不通过值参数初始化LOB 定位器,Oracle 将不允许使用下面的语句来更新数据表:
     UPDATE ClobTable SET Name = :Name, Value = :Value  WHERE Id = :Id  要初始化LOB 定位器,你必须使用EMPTY_BLOB 或EMPTY_CLOB Oracle 函数。
    要返回初始化后的定位器,应在同样的语句中使用 RETURNING 子句。
    例如: 
    UPDATE ClobTable SET Name = :Name, Value = EMPTY_CLOB() WHERE Id = :Id RETURNING Value INTO :Value  
    ODAC 写 LOB 数据到 Oracle 且返回初始值字段,需使用:值参数。
     存储过程允许自动初始化 LOB 值,方法如下: 
    CREATE OR REPLACE 
    PROCEDURE ClobTableUpdate (p_Id NUMBER, p_Name VARCHAR2, p_Value OUT CLOB) 
    is begin 
    UPDATE ClobTable 
    SET   Name = p_Name, Value = EMPTY_CLOB() 
    WHERE Id = p_Id RETURNING Value INTO p_Value; 
    end; 
    注意:值参数被声明为OUT。同时,设置LOB 数据类型的参数的ParamType 属性为ptInput 
    ,且指定它到所需的数据前来实际调用存储过程。我们可以这样调用前面声明的存储过程: 
    OraStroredProc1.StoredProcName := ’ClobTableUpdate’;
    OraStroredProc1.Prepare; 
    OraStroredProc1.ParamByName(’p_Id’).AsInteger := Id;
    OraStroredProc1.ParamByName(’p_Name’).AsString := Name;
    OraStroredProc1.ParamByName(’Value’).ParamType := ptInput;
    OraStroredProc1.ParamByName(’Value’).AsCLOBLocator.LoadFromFile(FileName); 
    OraStroredProc1.Execute; 
    对ODAC 来说,在LOB 操作中使用 ParamType 属性是非常重要的。
    如果 ParamType 是 ptInput , ODAC 写数据到服务器,
    如果 ParamType 是 ptOutput,它则读取数据。
    你可以使用 LOB 参数的dtBlob 和dtMemo 数据类型来编写普通的DML 语句。
    在这种情况下,Oracle 自动将 LONG 和 LONG ROW 类型的值转换为 CLOB 或BLOB 数据。 以上就是问题解决方法