0

手続きに問題があります。sales テーブルから値を取得し、それらを使用してクエリを作成しようとしています。手順は次のようになります。

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 < co DO
        SET m = (SELECT DISTINCT month FROM sales LIMIT 1 OFFSET i);
        SET q = 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 = q + " FROM sales GROUP BY article";
    EXECUTE q;
END$$

DELIMITER ;

CALL turnover();

エラーが表示されます:

エラー コード: 1292。切り捨てられた不正な DOUBLE 値: ',value,NULL)) AS '

どうすればそれを機能させることができますか?

ありがとう。

4

2 に答える 2

1

この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 に進み、それを使用します。

于 2016-11-23T00:45:28.047 に答える
0

SELECT DISTINCT month FROM sales何も返さない場合に発生します。次の行では、クエリ フラグメントが生成されSUM(IF(month=,value,NULL)) AS、もちろんエラーがあります (MySQL が正しいエラー メッセージを生成しない可能性がありますが、ここでエラーが発生します)。

エラーの原因は、不明な変数WHILEと比較する行です。おそらく次のように読む必要があります。ico

WHILE i < col DO

colしかし、は の個別の値の数であり、 の個別の値に対して1articleから反復するため、問題は解決しません。ほとんどの場合、それらは異なる量であり、記事の数が多い場合、エラーが再び発生します.colmonth

于 2016-11-23T00:26:55.893 に答える