WHILE循环中的PREPARED STATEMENT

时间:2012-07-07 19:34:40

标签: mysql stored-procedures while-loop prepared-statement

我有一个包含autos列的表name,我想检查表中的前5行,如果name值是"toyota",则在表{ {1}}写“是”,否则写“不”。 我编写存储过程,但mytable返回错误,我有mysqli_error()

如果在EXECUTE ...中我不写WHEN,而是直接写查询,则该过程有效。 请看我的代码告诉我,哪里错了?

PREPARED STATEMENT

2 个答案:

答案 0 :(得分:2)

(关于EXECUTE的建议被删除为不正确且可能令人困惑。)

您尝试使用存储过程解决的问题实际上可以在没有它的情况下使用完全不同的方法解决:只需使用单个INSERT ... SELECT语句:

INSERT INTO mytable (log)
SELECT
  CASE name
    WHEN 'toyota' THEN 'yes'
    ELSE 'no'
  END
FROM autos
ORDER BY id
LIMIT 5

也就是说,上述语句与存储过程相同:它从autos检索前5行,并在mytable中插入5行。根据{{​​1}}的值,它会生成name es或yes s。

答案 1 :(得分:2)

Andriy M的INSERT声明是最优雅的解决方案,但如果您仍想使用某个程序,这将有效:

CREATE PROCEDURE proc_auto()
BEGIN
    DECLARE start INT DEFAULT 0;

    PREPARE stmt FROM 
        'SELECT name INTO @name FROM autos ORDER BY id LIMIT ?,1';

    WHILE start < 5 DO
        SET @start = start;
        EXECUTE stmt USING @start;
        IF @name = 'toyota' THEN
            INSERT INTO mytable (log)  VALUES('yes');
        ELSE 
            INSERT INTO mytable (log)  VALUES('no');
        END IF;
        SET start = start + 1;
    END WHILE;
END;

但是,在这种情况下,使用CURSOR会产生更好的效果:

CREATE PROCEDURE proc_auto()
BEGIN
    DECLARE start INT DEFAULT 0;
    DECLARE b_not_found BOOL DEFAULT FALSE;

    DECLARE cur CURSOR FOR
        'SELECT name FROM autos ORDER BY id LIMIT 5';

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET b_not_found = TRUE;

    OPEN cur;

    loop1: WHILE start < 5 DO
        FETCH cur INTO @name;
        IF b_not_found THEN
            LEAVE loop1;
        END IF;

        IF @name = 'toyota' THEN
            INSERT INTO mytable (log)  VALUES('yes');
        ELSE 
            INSERT INTO mytable (log)  VALUES('no');
        END IF;
        SET start = start + 1;
    END WHILE;

    CLOSE cur;
END;