使用blob类型的TParam执行TClientDataSet错误(ftBlob)

时间:2016-02-20 11:40:06

标签: delphi blob params tclientdataset

我们正在使用MSSQL 2012。

尝试使用存储过程更新客户端照片

spui_SetClientPhoto
int ClientID
VarBinary(Max) Photo

程序在纯ADO下运行良好:

ADO.ProcedureName:='spui_SetClientPhoto';
ADO.Parameters.CreateParameter('@ClientsID',ftInteger,pdInput,0,95075);
ADO.Parameters.CreateParameter('@Photo',ftBlob,pdInput,0,NULL);
ADO.Parameters[1].LoadFromFile('C:\Photo.png',ftBlob);
ADO.ExecProc;

但是使用CDS会导致错误:

不允许从数据类型Varchar(max)到Varbinary(max)的隐式转换。

 ADO.ProcedureName:='spui_SetClientPhoto';
 cds.SetProvider(ADO);
 cds.Params.CreateParam(ftInteger,'@ClientsID',ptInput).AsInteger:=95075;
 cds.Params.CreateParam(ftBlob,'@Photo',ptInput).LoadFromFile('C:\Photo.png', ftBlob);
 cds.Execute;

e.g。无法使用BLOB类型的参数运行CDS。对此有何解决方案?

1 个答案:

答案 0 :(得分:1)

以下对我来说很好,AdoQuery中的Picture字段类型和 CDS设置为ftGraphic,存储过程的DDL设置为

CREATE PROCEDURE [dbo].[SetClientPhoto](@ClientID int, @Picture Image)
AS
BEGIN
    SET NOCOUNT ON;
    update table_2 
      set picture = @Picture
    where
      ID = @ClientID
END

代码

procedure TForm1.SavePictureViaStoredProc;
var
  PrvCommandText,
  PrvSql : String;
  ID : Integer;
const
  scTestImage = 'D:\TestPictures\TestBMP.BMP';
begin
  //  First, save the text of the AdoQuery's Sql and the CDS's CommandText
  PrvCommandText := CDS1.CommandText;
  PrvSql := AdoQuery1.SQL.Text;

  //  Save the iD of the row we want to use
  ID := CDS1.FieldByName('ID').AsInteger;
  try
    //  Allow CommandText changes on the DSP
    DataSetProvider1.Options := DataSetProvider1.Options + [poAllowCommandText];
    CDS1.Close;

    // construct a Sql statement to invoke the Stored Proc
    CDS1.CommandText := 'exec dbo.SetClientPhoto @ClientID = :' + IntToStr(ID) + ',  @Picture = :Picture';

    // Set up parameters
    CDS1.Params.Clear;
    CDS1.Params.CreateParam(ftInteger, '@ClientID', ptInput);
    CDS1.Params.CreateParam(ftGraphic, '@Picture', ptInput);
    CDS1.Params.ParamByName('@ClientID').Value := ID;
    CDS1.Params.ParamByName('@Picture').LoadFromFile(scTestImage, ftGraphic);

    AdoQuery1.Close;
    AdoQuery1.SQL.Text := '';
    CDS1.Execute;  // This executes the stored proc
    CDS1.Params.Clear;
  finally
    ADoQuery1.SQL.Text := PrvSql;
    CDS1.CommandText := PrvCommandText;
    CDS1.Open;
  end;

end;

注意:我很少将图像存储在数据库中,并且尚未设法将其与.Jpg和.Png文件一起使用。我隐约记得,将数据存储在数据库中时需要额外的步骤,而不会出现"流读取错误"或"图像无效"例外,我会看看以后是否可以提醒自己。