本人用delphi7 的TADOStoredProc调用mysql 的存储过程。在存储过程不需要传入参数的时候,能顺利获取到返回的数据集。
存储过程代码如下:
CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
begin
 DECLARE GoodsID int default 0;
 DECLARE no_more_products, quantity_in_stock INT DEFAULT 0;
 DECLARE cur_product CURSOR FOR select distinct goods_id from ecs_order_goods; 
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_products=1;  drop table if exists tmptable;
create TEMPORARY table tmptable
(
ID INT(11) NOT NULL AUTO_INCREMENT,
strInfo varchar(1000), 
strTotal varchar(500), 
primary key (ID)         
);
 
 OPEN cur_product;
 fetch cur_product into GoodsID;
 
 REPEAT
    INSERT INTO tmptable(strInfo) VALUES('123');

 fetch cur_product into GoodsID;
   UNTIL no_more_products=1
 END REPEAT;
 CLOSE cur_product; SELECT * FROM tmptable; 
 DROP TABLE tmptable;
end;delphi调用代码如下:
with spExec do
begin
      Close;
      ProcedureName:='ecs_test';
      Parameters.Clear;
      Prepared := false;
      //Parameters.CreateParameter('iUserID', ftInteger, pdInput, 4, iRow);
      prepared:=true;
      Open;
     ....
end;然后我在过程声明中添加传入参数,其它内容不变。
CREATE DEFINER=`root`@`localhost` PROCEDURE `test`(in iUserID int)
begin
  ...  /* 所有的代码不变。 */
end;delphi调用代码改为如下:
iRow := 1;
with spExec do
begin
      Close;
      ProcedureName:='test';
      Parameters.Clear;
      Prepared := false;
      Parameters.CreateParameter('iUserID', ftInteger, pdInput, 4, iRow);
      prepared:=true;
      Open;
     ....
end;
结果就执行报错,如图所示:
如果此时把存储过程的内容删除,随便添加一条 select语句返回一个数据集,又没有问题,说明参数传入应该没错。请诸位达人指点迷津,谢谢!

解决方案 »

  1.   


    with spExec do
    begin
          Close;
          ProcedureName:='test';
          Prepare;
          ParamByName('iUserID').Value := 4; //4还是iRow?不太明白
          //Parameters.CreateParameter('iUserID', ftInteger, pdInput, 4, iRow);
          Open;
         ....
    end;
      

  2.   


      with spExec do
      begin
        Close;
        ProcedureName:='test';
        Prepared := True;
        Parameters.ParamByName('iUserID').Value := iRow;
        //Parameters.CreateParameter('iUserID', ftInteger, pdInput, 4, iRow);
        Open;
      end;
      

  3.   


      with spExec do
      begin
        Close;
        ProcedureName:='test';
        Parameters.Clear;
        Parameters.CreateParameter('iUserID', ftInteger, pdInput, 4, iRow);
        Open;
      end;
      

  4.   

    ado已经是很古老的东西了,建议改用UniDAC。我发现论坛上还有很多人还在用BDE、ADO这类古董,实在令人困惑。
      

  5.   

    惯性而已,估计大部分开发者只用了Delphi 1/10不到的能力而已...
      

  6.   


      //也可以这样写
      with spExec do
      begin
        Close;
        ProcedureName:='TestProc';
        Parameters.Refresh;
        Parameters.ParamByName('@iUserID').Value := iRow;
        Open;
      end;
      

  7.   

    应用不深的人,比如我这样的,也就是写几个简单的应用,使部门工作起来简便一些,反而是习惯了简单的ADO+MSSQL,太深了反而影响开发了。
    这几天尝试了一下fircedac,基本上和ADO差不多,但是很多不一样的地方就抓瞎了,网上的教程也很少,果断的放弃了,哈哈
      

  8.   

    想简单的话可以用sdac(用于sql server)和MyDac(用于MySql),可以直连数据库,根本不需要驱动,从使用的角度来讲也比bde或ado更简单。其实UniDAC也是比较简单的,而且能连接几乎所有类型的数据库,而且其中有不少数据库是能通过tcpip直连的(不需要驱动),如oracle、sql server、MySQL、DBF等。我也觉得FireDAC似乎弄得太复杂了,不过熟悉了以后也没有太大的问题。
      

  9.   

    其实Delphi还提供了另外一种连接连接数据库的方式:DBExpress,用起来也算比较简单,但麻烦之处是:dbx驱动(dll文件)要随程序一起发布,不能把它编译连接在exe文件里。
      

  10.   

    EMB不把FireDAC做成全能是为了给第三方组件留出一定的生存空间,不是技术问题
      

  11.   

    还是喜欢一些大众的东西,或者delphi自带的东西,否则,一是出了问题无从查找解决方案,二是一旦升级delphi而第三方插件没有跟上,那可就哭死在厕所了,哈哈
      

  12.   

    可以在FireDAC组件(例如FDQuery)的基础上写自己的类,并根据这个类定义自己所需的接口(interface),程序存取数据库只通过这个接口进行。
    自己定义的类和接口(interface)写在一个单元里面,如果要把FireDAC换成ADO,把那个单元里面的类换成在ADO基础上写的类就可以了。
    这样的话,不管你的程序多大、有多少地方涉及数据库访问,也不管是换成UniDAC、ADO、DBExpress或SDAC等,所需的工作量就很少了。