この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 記事、FROM sales GROUP BY 記事
上記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
、ユーザー変数 (記号付き) に対して機能することが重要です。そうしないと、爆発します。だから私はそれを上記で修正しました@
DECLARE
@theSQL
繰り返しますが、MySQL のマニュアル ページPREPARE 構文を参照してください。文字列を正しくすることが重要です。それがステップ 1 のポイントです。その後、ステップ 2 に進み、それを使用します。