在存储过程中使用参数分配列来在存储过程中使用SELECT CASE param_name END CASE INTO @var

时间:2018-10-24 07:24:50

标签: mysql sql database

我有一个要使用参数创建的存储过程。

DELIMITER // 
    CREATE PROCEDURE insert_avg(IN area INT, IN checkid INT, IN legend INT)
this_proc: BEGIN

SELECT
    CASE legend
        WHEN 1 THEN "Input_Day"
        WHEN 2 THEN "Input_Week"
        WHEN 3 THEN "Input_Month"
        ELSE LEAVE this_proc
    END CASE;
INTO @LEGEND;

INSERT INTO 
    `input_teamboards` 
    (
        `Input_KPI`, 
        `Input_Month`, 
        `Input_Week`,   
        `Input_Day`, 
        `Input_Value`, 
        `Input_Comparison`, 
        `Input_Area`, 
        `Input_Created`
     ) 
VALUES 
    (
        7,
        IFNULL(SELECT `Input_Month` FROM `input` WHERE `check_id` = checkid, NULL, MONTH(NOW())),
        IFNULL(SELECT `Input_Week` FROM `input` WHERE `check_id` = checkid, NULL, WEEKOFYEAR(NOW())),
        IFNULL(SELECT `Input_Day` FROM `input` WHERE `check_id` = checkid, NULL, DAYOFYEAR(NOW())),
        (SELECT 
            AVG(`Input_value`) 
        FROM 
            `input` 
        WHERE 
            `Area_ID` = area AND @LEGEND = 1),
        2,
        area,
        NOW()
    )

END//
DELIMITER ;

如您所见,@LEGEND变量被用作子查询的一部分,以进一步查询列名。

我遇到的问题是case语句,它会在case语句内不断抛出错误:

  

“#1064-您的SQL语法有误;请查看与您的MariaDB服务器版本相对应的手册,以获取在'LEAVE this_proc附近使用的正确语法        结束案例;    进入@LEGEND;    插入        input_teamboards'在第8行“

到目前为止,我已经使用了这些链接,但是我做错了什么?

 Mysql Storing a variable with the result of an SELECT CASE
Mysql - How to quit/exit from stored procedure
case statement in stored procedure

任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

我会这样重写您的proc。有关详细说明,请参见下面的代码。

DELIMITER // 
CREATE PROCEDURE insert_avg(IN area INT, IN checkid INT, IN legend INT)
this_proc:BEGIN

IF legend NOT IN (1, 2, 3)
     LEAVE this_proc;
END IF;

INSERT INTO input_teamboards
(
    Input_KPI, 
    Input_Month, 
    Input_Week,   
    Input_Day, 
    Input_Value, 
    Input_Comparision, 
    Input_Area, 
    Input_Created
 ) 
SELECT
    7,
    COALESCE(Input_Month, MONTH(NOW())),
    COALESCE(Input_Week, WEEKOFYEAR(NOW())),
    COALESCE(Input_Day, DAYOFYEAR(NOW())),
    (SELECT AVG(Input_value) FROM input WHERE Area_ID = area AND
     ((legend = 1 AND Input_Day = 1)  OR
      (legend = 2 AND Input_Week = 1)  OR
      (legend = 3 AND Input_Month = 1))),
    2,
    area,
    NOW()
FROM input
WHERE check_id = checkid;

END//
DELIMITER ;

我在这里所做的主要更改是重写您的插入查询。我将其改写为INSERT INTO ... SELECT。这应该起作用,因为您的大多数子查询都引用相同的input表。对于一般的子查询,我通过仅检查其值,然后检查相应的相应列来处理涉及legend参数的逻辑。然后,我们可以删除您在proc开始时通常使用的CASE表达式。