1

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

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

CREATE PROCEDURE proc_auto()
BEGIN

DECLARE start INT;
SET start = 0;
PREPARE stmt FROM  ' SELECT name FROM autos ORDER BY id LIMIT ?,1 ';

WHILE start < 5 DO

    CASE 
        WHEN (EXECUTE stmt USING @start ) = 'toyota'
            THEN INSERT INTO mytable (log)  VALUES('yes');
        ELSE 
           INSERT INTO mytable (log)  VALUES('no');
    END CASE;
    SET start = start + 1;

END WHILE;
END;
4

2 回答 2

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;

但是,在这种情况下,使用 aCURSOR会产生更好的性能:

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;
于 2012-10-18T17:35:21.043 回答
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

也就是说,上述语句的作用与您的存储过程相同:它从 中检索前 5 行autos并将 5 行插入到mytable. 根据它的值name生成yeses 或nos。

于 2012-07-07T20:47:52.650 回答