该col
问题已在下文中修复或假设。
CREATE SCHEMA safe_Tuesday_01; -- safe sandbox
USE safe_Tuesday_01; -- DO the work in this db to test it
-- a fake table, we need something
create table sales
( article varchar (100) not null,
month int not null
);
第 1 步,找出字符串的样子:
DROP PROCEDURE IF EXISTS turnover;
DELIMITER $$
CREATE PROCEDURE turnover()
BEGIN
DECLARE col INT;
DECLARE q TEXT;
DECLARE i INT DEFAULT 0;
DECLARE m TEXT;
SET col = (SELECT count(DISTINCT article) FROM sales);
SET q = "SELECT article, ";
WHILE i < col DO
SET m = (SELECT DISTINCT month FROM sales LIMIT 1 OFFSET i);
SET q = CONCAT(q,"SUM(IF(month=" + m + ",value,NULL)) AS ", m);
IF i < (col - 1) THEN
SET q = q + ", ";
END IF;
SET i = i + 1;
END WHILE;
SET q = CONCAT(q," FROM sales GROUP BY article");
select q;
-- EXECUTE q; -- No no no this is wrong anyway
END$$
DELIMITER ;
CALL turnover();
SELECT article, FROM sales GROUP BY article
好吧,上面SELECT
看起来并不那么热。在步骤 1 中反复修复您的逻辑以修复该字符串。
第 2 步,当您修复上面的代码时,请在下面插入。请注意,目前,它不是固定的。所以,再一次,在上面。
但是在下面,使用PREPARED STATEMENT
你不是的正确的。
DROP PROCEDURE IF EXISTS turnover;
DELIMITER $$
CREATE PROCEDURE turnover()
BEGIN
DECLARE col INT;
DECLARE q TEXT;
DECLARE i INT DEFAULT 0;
DECLARE m TEXT;
SET col = (SELECT count(DISTINCT article) FROM sales);
SET q = "SELECT article, ";
WHILE i < col DO
SET m = (SELECT DISTINCT month FROM sales LIMIT 1 OFFSET i);
SET q = CONCAT(q,"SUM(IF(month=" + m + ",value,NULL)) AS ", m);
IF i < (col - 1) THEN
SET q = q + ", ";
END IF;
SET i = i + 1;
END WHILE;
SET q = CONCAT(q," FROM sales GROUP BY article");
-- select q;
SET @theSQL=q;
PREPARE stmt1 FROM @theSQL;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END$$
DELIMITER ;
完成后,
DROP SCHEMA safe_Tuesday_01; -- clean up, poof, sandbox is gone
CONCAT
是你的朋友。你错过了这一步。重要的是PREPARE
针对用户变量(带有@
符号)而不是本地变量(来自 a DECLARE
)工作,否则它会爆炸。所以我用@theSQL
再次,请参阅 MySQL 手册页PREPARE Syntax。正确设置字符串很重要。这就是第 1 步的重点。只有这样,您才能进入第 2 步并使用它。