使用sql参数插入/更新TBlobfield(aka图像)

时间:2013-10-01 12:11:35

标签: sql image delphi parameters blob

我想使用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;

3 个答案:

答案 0 :(得分:6)

应该是这样的:

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;

从DB中读回BLOB:

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

我写这个作为这个q的答案, Delphi save packed record as blob in a sql database 目前标记为重复,可能是错误的,因为该技术 如评论中所述,OP使用似乎是正确的。因此,问题的原因可能在其他地方。

如果删除了复制标记,我会在那里重新发布此答案。

对于我定义的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