【问题标题】:Insert/update TBlobfield (aka image) using sql parameters使用 sql 参数插入/更新 TBlobfield(又名图像)
【发布时间】:2013-10-07 14:11:35
【问题描述】:

我想使用 sql 将图像存储在数据库中,但似乎无法正常工作:

qry.SQL.Clear;
qry.Sql.Add('update tbl set pic = :blobVal where id = :idVal');   
qry.Parameters.ParamByName('idVal')._?:=1;

.Parameters 没有像 .Param 那样的 .asinteger,但 .Param 与 TADOquery 不兼容 - 我尝试了解决方法:

a_TParameter:=qry.Parameters.CreateParameter('blobval',ftBlob,pdinput,SizeOf(TBlobField),Null);
a_TParam.Assign(a_TParameter);
a_TParam.asblob:=a_Tblob;
qry.ExecSql; 

这也不起作用:

qry.SQL.Clear;
qry.Sql.Add('update tbl set pic = :blobVal where id = 1')
qry.Parameters.ParamByName('blobVal').LoadFromStream(img as a_TFileStream,ftGraphic);//ftblob 
//or 
qry.Parameters.ParamByName('blobVal').LoadFromFile('c:\sample.jpg',ftgrafic);//ftblob
qry.ExecSql;

【问题讨论】:

标签: sql image delphi parameters blob


【解决方案1】:

应该是这样的:

qry.Parameters.Clear; 
qry.Parameters.AddParameter.Name := 'blobVal';
qry.Parameters.ParamByName('blobVal').LoadFromFile('c:\sample.jpg', ftBlob);
// or load from stream: 
// qry.Parameters.ParamByName('blobVal').LoadFromStream(MyStream, ftBlob);
qry.Parameters.AddParameter.Name := 'idVal';
qry.Parameters.ParamByName('idVal').Value := 1;
qry.SQL.Text := 'update tbl set pic = :blobVal where id = :idVal';    
qry.ExecSQL;

从数据库中读回 BLOB:

qry.SQL.Text := 'select id, pic from tbl where id = 1';
qry.Open;
TBlobField(qry.FieldByName('pic')).SaveToFile('c:\sample_2.jpg');

【讨论】:

  • 试过了-错误:参数对象定义不正确。提供的信息不一致或不完整。
  • @user,我已经进行了编辑(您可能没有指定idVal 参数)。现在试试。对我来说效果很好。
【解决方案2】:

我使用的是 Lazarus,而不是 Delphi,但我猜它通常是相同的语法。如果是这样,以下是对 kobiks 建议的轻微改进:

如果在尝试为参数分配值之前分配了 SQL.Text,则会自动添加参数。像这样:

qry.Parameters.Clear; 

qry.SQL.Text := 'update tbl set pic = :blobVal where id = :idVal';    
qry.Parameters.ParamByName('blobVal').LoadFromFile('c:\sample.jpg', ftBlob);
qry.Parameters.ParamByName('idVal').Value := 1;
qry.ExecSQL;

【讨论】:

    【解决方案3】:

    我写这个是为了回答这个问题, Delphi save packed record as blob in a sql database 当前被标记为重复,可能是错误的,因为该技术 cmets 中描述的 OP 使用的似乎是正确的。因此,问题的原因可能在其他地方。

    如果 Duplicate 标志被删除,我将在此处重新发布此答案。

    以下代码对我来说适用于如下所示定义的 Sql Server 表。

    Rec1 中的数据保存到表中并正确读回 Rec2。

    (* MS Sql Server DDL
    CREATE TABLE [blobs] (
      [id] [int] NOT NULL ,
      [blob] [image] NULL ,
      CONSTRAINT [PK_blobs] PRIMARY KEY  CLUSTERED
      (
        [id]
      )  ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO
    *)
    
    TForm1 = class(TForm)
      ADOConnection1: TADOConnection;
      qBlobInsert: TADOQuery;
      qBlobRead: TADOQuery;
      Button1: TButton;
      procedure Button1Click(Sender: TObject);
     [...]
    
    
    type
      TMyRecord = packed record
        FontName: string[30];
        FontSize: word;
        FontColor: integer;
        FontStyle: word;
        Attachement: string[255];
        URL: string[255];
      end;
    
    const
      scInsert = 'insert into blobs(id, blob) values(:id, :blob)';
      scSelect = 'select * from blobs where id = %d';
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      TestInsert;
    end;
    
    procedure TForm1.TestInsert;
    var
      Rec1,
      Rec2 : TMyRecord;
      MS : TMemoryStream;
    begin
      FillChar(Rec1, SizeOf(Rec1), #0);
      FillChar(Rec2, SizeOf(Rec2), #0);
    
      Rec1.FontName := 'AName';
      Rec1.URL := 'AUrl';
    
      MS := TMemoryStream.Create;
      try
        // Save Rec1 using an INSERT statement
    
        MS.Write(Rec1, SizeOf(Rec1));
        MS.Seek(0, soFromBeginning);
        qBlobInsert.Parameters[0].Value := 1;
        qBlobInsert.Parameters[1].LoadFromStream(MS, ftBlob);
        qBlobInsert.SQL.Text := scInsert;
        qBlobInsert.ExecSQL;
    
    
        // Read saved data back into Rec2
    
        qBlobRead.SQL.Text := Format(scSelect, [1]);
        qBlobRead.Open;
        MS.Clear;
        TBlobField(qBlobRead.FieldByName('blob')).SaveToStream(MS);
        MS.Seek(0, soFromBeginning);
        MS.Read(Rec2, MS.Size - 1);
        Caption := Rec2.FontName + ':' + Rec2.URL;
      finally
        MS.Free;
      end;
    end;
    

    从 DFM 中提取

    object qBlobInsert: TADOQuery
      Connection = ADOConnection1
      Parameters = <
        item
          Name = 'id'
          DataType = ftInteger
          Value = Null
        end
        item
          Name = 'blob'
          DataType = ftBlob
          Value = Null
        end>
      Left = 56
      Top = 32
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      相关资源
      最近更新 更多