【问题标题】:How to insert image into database using TADOQuery Component Only如何仅使用 TADOQuery 组件将图像插入数据库
【发布时间】:2016-11-11 18:06:32
【问题描述】:

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

由于代码已经由某人编写,因此我想在此处放一些虚拟示例代码,以供您对各个步骤进行澄清。

请注意,这与TQuery 组件一起工作正常,因为我用TADOQuery 组件替换TQuery,我必须只使用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. 使用TQuery 组件的SetBlobdata 属性插入数据库。

    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; 
    

现在使用 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; 
    

请告诉我,用这种方法我应该如何克服这个问题。

【问题讨论】:

  • 你确定这是二进制 blob,而不是文本 blob?将图像覆盖到 base64 中会有帮助吗?
  • 您是否尝试用谷歌搜索错误? google.ru/… 它告诉您的数据列在服务器级别或 ADO 级别有长度/大小限制。试试小图,合适吗?仔细检查您将图片放入的位置。

标签: delphi


【解决方案1】:

保存:

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;

【讨论】:

    【解决方案2】:

    当您使用参数时,我认为您必须为它提供额外的设置,例如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;
    

    【讨论】:

    • 问题已解决,因为我在执行插入语句之前编写了以下语句:代码:sSql := 'INSERT INTO Table_Name(Column1, Column2, Column_Image) VALUES (''' + Value1 + ' '', ''' + 值2 + ''', :pBlob)'; qryADOQuery.SQL.Add(sSQL); qryADOQuery.Parameters.ParamByName('pBlob').Value := TBytesField(msBinImgStream).AsVariant; qryADOQuery.ExecSQL;但是当我查看数据库时,我存储图像的列显示为空,但是当我运行应用程序时,图像正确显示。这有什么原因吗?最诚挚的问候。维沙尔
    猜你喜欢
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2020-07-20
    • 2015-02-20
    • 2011-07-22
    • 2017-05-09
    相关资源
    最近更新 更多