【问题标题】:Mysql Stored procedure with cursor带游标的Mysql存储过程
【发布时间】:2014-01-01 04:42:30
【问题描述】:

Mysql 游标问题?

我编写了一个存储过程,它将从一个表中旅行的记录并将它们插入到 2-3 个不同的表中 使用插入语句。

问题是我正在检查 table1 中是否不存在记录,然后我将记录从 temptable 依次插入 table1、table2 ,但条件有一些问题我不知道它总是进入其他部分。

代码示例如下:

CREATE PROCEDURE `insertData`(In clientNo INT,In usedID INT)
BEGIN

declare mame varchar(100);
declare address varchar(100);
declare city varchar(50);
declare IdentityNO1 varchar(20)


declare cur1 cursor for select * from temptable;
declare continue handler for not found set done=1;

SET @clientNo = clientNO;
SET @userID = userID;


    set done = 0;
    open cur1;
    igmLoop: loop
        fetch cur1 into Name,Address,City,IdentityNO1,clientNo;
        if done = 1 then leave igmLoop; end if;

        //If no record exists in some records table1,table2.
        IF ( (SELECT COUNT(*) FROM table1 
               WHERE IndentityNo=IdentityNo1 
                 AND clientNo=@clientNo) < = 0)
              INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1);
              INSERT INTO table2 (Address,City) VALUES(address,city);
        ELSE
              INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
              VALUES(name,address,city,IdentityNo1);
    end loop igmLoop;
    close cur1;
END

【问题讨论】:

    标签: mysql stored-procedures database-cursor


    【解决方案1】:

    没有THENEND IF关键字,程序无法编译。
    检查此链接以获取 IF 语句的正确语法:http://dev.mysql.com/doc/refman/5.7/en/if.html

    使用EXIST 运算符而不是(SELECT count(*)... ) &lt;=0
    阅读此链接了解原因:http://sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/exists-vs-count-the-battle-never-ends.aspx

    IF    EXISTS(  
                   SELECT null FROM table1 
                   WHERE IndentityNo=IdentityNo1 
                     AND clientNo=@clientNo
          )
    THEN
                  INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1);
                  INSERT INTO table2 (Address,City) VALUES(address,city);
    ELSE
                  INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
                  VALUES(name,address,city,IdentityNo1);
    END IF;
    


    我建议为过程参数和变量名使用一些前缀以避免歧义,例如使用p_ 表示参数,使用v_ 表示变量。看这段代码很难猜到,哪个名称是列名、变量或过程参数。这可能会导致错误和错误。

    避免使用SELECT * - 如果有人更改表结构,此代码将失败。在游标声明中明确列出所需的列:

    declare cur1 cursor for 
            select name,Address,City,IdentityNO,clientNo
            from temptable;
    

    更正后的过程可能如下所示:

    CREATE PROCEDURE `insertData`(In p_clientNo INT,In p_usedID INT)
    BEGIN
    
    declare v_name varchar(100);
    declare v_address varchar(100);
    declare v_city varchar(50);
    declare v_IdentityNO varchar(20)
    declare v_clientNo int
    
    
    declare cur1 cursor for 
            select name,Address,City,IdentityNO,clientNo
            from temptable;
    declare continue handler for not found set done=1;
    
        set done = 0;
        open cur1;
        igmLoop: loop
            fetch cur1 into v_name,v_Address,v_City,v_IdentityNO,v_clientNo;
            if done = 1 then leave igmLoop; end if;
    
            //If no record exists in some records table1,table2.
            IF  EXISTS(  SELECT 1 FROM table1 
                         WHERE IndentityNo = v_IdentityNo 
                           AND clientNo = v_clientNo)
                  INSERT INTO table1 (Name,IdentityNO) VALUES (v_name,v_IdentityNO);
                  INSERT INTO table2 (Address,City) VALUES(v_address,v_city);
            ELSE
                  INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
                  VALUES(v_name,v_address,v_city,v_IdentityNo);
            END IF;
        end loop igmLoop;
        close cur1;
    END
    

    【讨论】:

    • 谢谢你的回答我会试试的。但是相同的参数名称会导致任何问题吗?因为如果我从表中给出相同的参数名称和列,我将很好地编译过程。
    • @krokodilko,我相信您的答案需要在条件插入子句中使用NOT exists(...)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多