mysql存储过程带参数问题

时间:2009-10-26 11:53:08

标签: mysql stored-procedures parameters

我创建了以下程序。

DELIMITER ;;

DROP PROCEDURE IF EXISTS getAllPortfoliosDemo;;

CREATE PROCEDURE getAllPortfoliosDemo( IN keyid INT(10)) 
    BEGIN 
        DECLARE whereString char(100);

        IF (keyid > 0 ) THEN
            SET  whereString =  CONCAT( ' WHERE pkid = ', keyid );
        ELSE
            SET whereString = ' WHERE 1 ';
        END IF;


        SELECT pkid, title FROM Portfolio whereString;

    END ;;

此查询不返回任何错误。没有参数,它运作良好。 例如,CALL getAllPortfoliosDemo();作品。但它不适用于参数。例如 CALL getAllPortfoliosDemo(5);没有返回任何一行。

我也尝试了以下备用查询

DELIMITER ;;

DROP PROCEDURE IF EXISTS getAllPortfoliosDemo;;

CREATE PROCEDURE getAllPortfoliosDemo( IN keyid INT(10)) 
    BEGIN 
        DECLARE whereString char(100) DEFAULT NULL;

        IF (keyid > 0 ) THEN
            SET  whereString =  CONCAT( ' AND pkid = ', keyid );
        END IF;


        SET @SQLstmt =  CONCAT('SELECT pkid, title FROM Portfolio ', whereString) ;

        PREPARE SQLbase FROM @SQLstmt;
    EXECUTE SQLbase;
    DEALLOCATE PREPARE SQLbase;

    END ;;       

这也没有返回任何结果集。任何一个人都可以成为一种方法。提前谢谢

2 个答案:

答案 0 :(得分:1)

SELECT pkid, title 
FROM Portfolio whereString;

这样,您的whereString变量会被转换为BOOLEAN,并且总是计算为true,因为它不是空的。

IF (keyid > 0 ) THEN
    SET  whereString =  CONCAT( ' AND pkid = ', keyid );
END IF;

SET @SQLstmt =  CONCAT('SELECT pkid, title FROM Portfolio ', whereString)

对于高于0的值,这应该会失败,因为它会产生以下语句:

SELECT  pkid, title
FROM    Portfolio
WHERE   AND pkid = $keyid
--      ^
--  Wrong!

只需使用以下声明:

SELECT  pkid, title
FROM    Portfolio
WHERE   pkid = keyid
UNION ALL
SELECT  pkid, title
FROM    Portfolio
WHERE   keyid = 0

这将优化其中一个SELECT查询并且非常有效。

答案 1 :(得分:0)

是。 Quassnoi很好地回答了这个问题。非常感谢他。 我已将查询修改为

DELIMITER ;;

DROP PROCEDURE IF EXISTS getAllPortfoliosDemo;;

CREATE PROCEDURE getAllPortfolios( IN keyid INT(10)) 
    BEGIN 
        DECLARE whereString char(100) DEFAULT NULL;

        IF (keyid > 0 ) THEN
            SET  whereString =  CONCAT( ' WHERE 1 AND pkid = ', keyid );
        ELSE
            SET  whereString =  ' WHERE 1 ';
        END IF;


        SET @SQLstmt =  CONCAT('SELECT pkid, title  FROM Portfolio ', whereString) ;

        PREPARE SQLbase FROM @SQLstmt;
 EXECUTE SQLbase;
 DEALLOCATE PREPARE SQLbase;

    END ;;   

这样'CALL getAllPortfoliosDemo(0)'将返回所有记录,'CALL getAllPortfoliosDemo(5)'将返回第五行

查询

  CREATE PROCEDURE getAllPortfoliosDemo( IN keyid INT(10)) 
    BEGIN 
       SELECT  pkid, title
       FROM    Portfolio
       WHERE   pkid = keyid
   UNION ALL
      SELECT  pkid, title
      FROM    Portfolio
      WHERE   pkid = 0;
    END ;;

太有用了。但是'CALL getAllPortfoliosDemo(0)'在这里没有重新记录,因为我们没有主键ID为'0'的记录。 getAllPortfoliosDemo(5)工作正常