本人写了一个存储过程,可是当在SQL 查询分析器中运行时,没有问题,但是当通过delphi传递参数运行此存储过程时,却问题多多:
1、当clientdataset中只有一条记录时,传递各参数运行时,有一个参数(备注栏)的值不能插入到表中;
2、当clientdataset中有两条记录时,如果参数(备注栏)为空,则第一条记录完全正确,第二条记录的一个必输字段(收料单号)为空,所以不能插入;如果第二条记录的参数(备注栏)不为空,则运行后,会把必输字段与备注栏字段的内容相互交换。
不知为什么会发生这样的情况,请高手们指教!
谢谢

解决方案 »

  1.   

    存储过程如下:
    CREATE PROCEDURE  create_rec  
    @comid char(4),
    @receipter char(5),
    @receiptdate datetime,
    @memoh varchar(50),
    @matno char(8),
    @receiptq numeric(10,2),
    @unit varchar(4),
    @veridate datetime,
    @lgpbe char(8),
    @veriresult varchar(1),
    @bz int,
    @id char(11),
    @memoi varchar(50) ,
    @receiptno  char(11)  output
    AS
    declare @max_id char(11), @year char(4),@month char(2),@day char(2),@temp_id char(11),@temp_id1 char(3)
    --根据@bz判断是否生成新的入库单号
    if @bz=0 
    begin
    --生成新的入库单号
    select  @temp_id=datename(yy, getdate())+datename(mm,getdate())+datename(dd,getdate())
    select @temp_id1=substring(max(receiptno),9,3) from rec_head where substring(receiptno,1,8)=rtrim(@temp_id )
      if @temp_id1=null
      select @max_id=rtrim(@temp_id)+'001'
    else
    begin
     select @temp_id1=@temp_id1+1 
     if len(@temp_id1)=1
     select @temp_id1='00'+@temp_id1
    if len(@temp_id1)=2
    select @temp_id1='0'+@temp_id1
     select @max_id=rtrim(@temp_id)+(@temp_id1)
    end
    select @receiptno=@max_id
    --把记录插入到rec_head表中
    insert into rec_head(comid,receiptno,receipter,receiptdate,memo) values(@comid,@max_id,@receipter,@receiptdate,@memoh)
    end
    else
    begin
    select @max_id=@id
    select @receiptno=@max_id
    end
    --把记录插入到rec_item表中
    --print @receiptno
    insert into rec_item(comid,receiptno,matno,receiptq,unit,veridate,lgpbe,veriresult,memo) values(@comid,@max_id,@matno,@receiptq,@unit,@veridate,@lgpbe,@veriresult,@memoi)
    --根据检验结果,更改库存表lgpbe
    if not exists(select comid,matno,lgpbe from lgpbe where comid=@comid and matno=@matno and lgpbe=@lgpbe)
    --不存在,则新增
    begin
     if @veriresult=0
    insert into lgpbe(comid,matno,lgpbe,stocks,useableq) values(@comid,@matno,@lgpbe,@receiptq,@receiptq)
    else
      insert into lgpbe(comid,matno,lgpbe,stocks,useableq) values(@comid,@matno,@lgpbe,@receiptq,0)
    end
    else
    --存在,则修改
    begin
     if @veriresult=0 
    update lgpbe set stocks=stocks+@receiptq,useableq=useableq+@receiptq where comid=@comid and matno=@matno and lgpbe=@lgpbe
    else
    update lgpbe set stocks=stocks+@receiptq where comid=@comid and matno=@matno and lgpbe=@lgpbe
    end
    GO
      

  2.   

    delphi中调用语句:
    cdsmat.First;            ---clientdataset
     bz:=0;   
     id:='';
     while not cdsmat.Eof do
     begin
      if cdsmat.FieldByName('cdsreceiptq').AsFloat>0 then
      begin
       if cdsmat.FieldByName('cdslgpbe').AsString='' then
       begin
       application.MessageBox('ÇëÊäÈëʵ¼Ê¿âλ£¡','Ìáʾ',mb_ok);----提示信息
       exit;
       end
       else
       begin
     adospcreat_rec.Close;
     adospcreat_rec.Parameters.ParamByName('@comid').Value:='aaaa';
     adospcreat_rec.Parameters.ParamByName('@receipter').Value:='10000';
     adospcreat_rec.Parameters.ParamByName('@receiptdate').Value:=dtprecdate.DateTime;
     adospcreat_rec.Parameters.ParamByName('@memoh').Value:=edtmemo.Text;
     adospcreat_rec.Parameters.ParamByName('@matno').Value:=cdsmat.fieldbyname('cdsmatno').AsString;
    adospcreat_rec.Parameters.ParamByName('@receiptq').Value:=cdsmat.fieldbyname('cdsreceiptq').AsFloat;
    adospcreat_rec.Parameters.ParamByName('@unit').Value:=cdsmat.fieldbyname('cdsunit').AsString;
     if cdsmat.FieldByName('cdsveriresult').AsString='2' then
      adospcreat_rec.Parameters.ParamByName('@veridate').Value:=null
      else
     adospcreat_rec.Parameters.ParamByName('@veridate').Value:=cdsmat.fieldbyname('cdsveridate').AsDateTime;
     adospcreat_rec.Parameters.ParamByName('@lgpbe').Value:=cdsmat.fieldbyname('cdslgpbe').AsString ;
     adospcreat_rec.Parameters.ParamByName('@veriresult').Value:=cdsmat.fieldbyname('cdsveriresult').AsString;
      adospcreat_rec.Parameters.ParamByName('@memoi').Value:=cdsmat.fieldbyname('cdsmemo').AsString;----就是这个参数,参数有值,但运行存储过程后,插入不进去
       adospcreat_rec.Parameters.ParamByName('@bz').Value:=bz;
      adospcreat_rec.Parameters.ParamByName('@id').Value:=id;
       adospcreat_rec.ExecProc;
       bz:=bz+1;
       id:=adospcreat_rec.Parameters.Parambyname('@receiptno').Value;---传出参数
       cdsmat.Next;
       end;
      end
      else
      cdsmat.Next;
     end;
      

  3.   

    在另外一个clientdataset中运行exec create_rec '','','','',....这样,看看行不行。
    可以的话那就是clientdataset的问题啦。
    如果是D6的话还是先装补丁包吧。
      

  4.   

    宽度都够了吧?
    如:@memoi varchar(50)你可以调试的啊
      

  5.   

    宽度绝对够!
    当我只有一条记录时,不管输入什么,参数@memoi传递过去后,都没有被插入
    当有两条记录时,第二条的参数@memoi放到了字段@id对应的字段中了
      

  6.   

    现在把clinetdataset换成adoquery试了一遍,结果还是一样!我也快要晕了!
      

  7.   

    你用的一定是ADO连接数据库的,这个问题是ADO的一个Bug!!!
    你可以试一下,将这个存储过程的参数都使用静态的存储过程控件处理,肯定不会出错!!!但是只要是参数是动态产生的就会出错!!!
    我也遇到过这样的问题,最后换了一个数据库引擎就没有问题了(我使用的是Oracle数据库),你可以试一试加上Prapare语句,说不定有用!!!
      

  8.   

    啊,这样!
    那怎么办?参数肯定要动态传入的!
    加了prepare,没用!
      

  9.   

    TO:Delphi_Li(Delphi Li)
    "将这个存储过程的参数都使用静态的存储过程控件处理"这句话什么意思?
    有这么一个控件吗?在哪里?
    谢谢告之!
      

  10.   

    用DBEXPRESS试试吧,尽量不用ADO了,他有时让人受不了了。
      

  11.   

    问题已经解决!原因很简单,在adostoredproc的参数顺序与存储过程中定义的参数顺序不一致!
    不过还是有疑问,我传递参数时是使用paramerbyname,怎么会和顺序有关呢?
    先不管了,能解决就OK了!
    谢谢大家的回答!结贴了。
    下午休息去!