如何使用TADOQuery Component Only将图像插入数据库

时间:2012-08-02 08:47:06

标签: delphi

我有一个简单的基本问题,我正在尝试使用Insert语句将图像插入数据库,其他列值也使用TADOQuery组件。

由于代码已经由某人编写,我想在此提供一些虚拟样本代码,以便您通过各自的步骤进行说明。

请注意,这与TQuery组件一起运行正常,因为我将TQuery替换为TADOQuery组件,我必须仅使用TADOQuery组件执行相同操作。

相同的代码应该适用于SQL Server以及Oracle数据库。

我尝试插入图像的列的数据类型在SQL Server数据库中的类型为VarBinary

使用TQuery将图像插入表中

  1. 使用TImage创建图像。

    msBinImgStream := TMemoryStream.Create; 
    imgCustom := TImage.Create(self); 
    imgJpg := TJPEGImage.Create; 
    
  2. 将图片转换为TJpegImage并保存到TMemoryStream

    imgJpg.Assign(imgCustom.Picture.Bitmap); 
    imgJpg.SaveToStream(msBinImgStream);
    
  3. 使用SetBlobdata组件的TQuery属性插入数据库。

    sSql := 'INSERT INTO Table_Name(Column1, Column2, Column_Image) VALUES ( ''' + Value1 + ''', ''' + Value2 + ''', :pBlob)'; 
    qryTQuery.SQL.Add(sSQL); 
    qryTQuery.ParamByName('pBlob').SetBlobData(msBinImgStream.Memory, msBinImgStream.Size); 
    qryTQuery.ExecSQL; 
    
  4. 现在使用TADOQuery执行相同的操作:

    1. 能够创建图像。
    2. 将其转换为TJpeg并保存到TMemoryStream
    3. 尝试使用LoadFromStream(stream, ftBlob)将图像插入数据库,但收到错误“字符串或二进制值可能会被截断”

      sSql := 'INSERT INTO Table_Name(Column1, Column2, Column_Image) VALUES ( ''' + Value1 + ''', ''' + Value2 + ''', :pBlob)'; 
      qryADOQuery.SQL.Add(sSQL); 
      qryADOQuery.Parameters.ParamByName('pBlob').LoadFromStream(msBinImgStream, ftBlob); 
      qryADOQuery.ExecSQL; 
      
    4. 请告诉我,用这种方法我应该如何克服这个问题。

2 个答案:

答案 0 :(得分:11)

存储

var
  Field: TBlobField;
  Stream: TStream;
begin
  if ADOQuery.Active and (Image.Picture.Graphic <> nil) then
  begin
    ADOQuery.Insert;
    Field := TBlobField(ADOQuery.FieldByName('ImageData')); // ensure it ís a blob
    Stream := ADOQuery.CreateBlobStream(Field, bmWrite);
    try
      Image1.Picture.Graphic.SaveToStream(Stream);
    finally
      Stream.Free;
      ADOQuery.Post;
    end;
  end;
end;    

或使用TADOBlobStream代替TStream

var
  ...
  Stream: TADOBlobStream;
begin
  ...
    Stream := TADOBlobStream.Create(Field, bmWrite);
    ...

装载:

var
  Field: TBlobField;
  Stream: TStream;
  Jpg: TJPEGImage;
begin
  if ADOQuery.Active then
  begin
    Field := TBlobField(ADOQuery.FieldByName('ImageData'));
    Stream := ADOQuery.CreateBlobStream(Field, bmRead);
    Jpg := TJPEGImage.Create;
    try
      Jpg.LoadFromStream(Stream);
      Image1.Picture.Graphic := Jpg;
    finally
      Jpg.Free;
      Stream.Free;
    end;
  end;
end;

答案 1 :(得分:3)

当您使用参数时,我认为您必须为其提供其他设置,例如AttributesDataType,如下所示:

  sSql := 'INSERT INTO Table_Name (Column1, Column2, Column_Image) ' +
    'VALUES (''' + Value1 + ''', ''' + Value2 + ''', :pBlob)';

  qryADOQuery.SQL.Add(sSQL);
  qryADOQuery.Parameters[0].Attributes := [paLong];
  qryADOQuery.Parameters[0].DataType := ftBlob; // Or ftVarBytes
                                                // Or ftOraBlob (Oracle only)
  qryADOQuery.Parameters[0].LoadFromStream(msBinImgStream, ftBlob);
  qryADOQuery.ExecSQL;