FireBird的两个误区:动态参数传递出错Incorrect values within SQLDA structure

来源:互联网 发布:windows关闭讲述人 编辑:程序博客网 时间:2024/06/06 03:33

有一个删除语句:delete from tb_customer where f_custno=22,不带参数可以真接删除,但用了参数后,delete from tb_customer where f_custno=:custno,老提示"Incorrect values within SQLDA structure"这个错,开始以为是动态库有问题,把VendorLib库GDS32.dll换为fbclient.dll后,还是一样的问题,用了两年多的FB,还没碰到过这种问题,最后G了一下,结果竟然是ExecSQL(ExecDirect: Boolean = False)的问题,这个我倒是看过它的Help,但现在看来还是没有真正理解,以前以为是用ExecDirect=True会快一点,就是不用准

备,直接执行SQL,后来用ExecSQL时都用ExecSQL(),没有指定其中的参数,而其中的参数ExecDirect 是有默认值False的,所以不今天无意间

把带参数的SQL用ExecSQL(True)时,就返回Incorrect values within SQLDA structure这样的错误,失败啊,看来以后得小心了。

 

 还有一个是多表修改、删除更新的误区,当使用了ClientDataSet后,是支技多表更新操作的,只是需要程序员自已判断处理更新的范围和

过程,一般ClientDateset配合DataSetProvider使用,在DataSetProvider的BeforeUpdateRecord事件里,有三个重要的东东就是:

DeltaDS和Applied,DeltaDS是本地缓存数据字段内容,是你更新的依据,UpdateKind是Midas所提供的增、删、改等三种行为机制的类型,Applied 是指告诉DataSetProvider,数据更改是否被落实了,如果为true,则不必再做另外的操作了。下面是其函数原型:

 

procedure TForm1.DataSetProvider1BeforeUpdateRecord(Sender: TObject; SourceDS:
  TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var
  Applied: Boolean);

begin

end;

 

这样,另外加三个TSQLQuer控件,分别处理增、删、改的三种行为,在其中写好SQL,在这个事件中处理就行了。下面是删除的处理,增加、修改同理。

procedure TForm1.DataSetProvider1BeforeUpdateRecord(Sender: TObject; SourceDS:
  TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var
  Applied: Boolean);
  procedure DeleteCust(sno:variant);
  begin
      try
        sqyDeleteCust.ParamByName('custno').Value :=sno;
        sqyDeleteCust.ExecSQL();
        Applied := True;
      except

        ;
      end;
  end;

begin

  if UpdateKind=ukDelete then
    DeleteCust( Copy(DeltaDS.FieldByName('KeyField').OldValue, 2, 2));
end;

然后在保存事件里还可以用异常捕获一下,判断是否有异常发生,再根据消息处理是否要回滚。

procedure TForm1.Button6Click(Sender: TObject);
var
  i: integer;
begin
  i := cdsTree2.ApplyUpdates(0);
  if i > 0 then
    ShowMessage('Failed ' + IntToStr(i));
end;

这样处理起来是不是很爽。