SET命令在MySQL过程中似乎被忽略
我终于使此功能正常工作,直到我尝试以生产状态实施为止。当我运行此过程并致电时,我只会获得下限输出的值,而上限输出的零。我在过程中添加了一个选择,该过程显示了正在计算内部变量@lowlim和@upplim的结果,但看来只有Lowerlimit变量的集合才能正常工作。我一直在敲几个小时,到目前为止无法弄清楚。谁能看到我在这里缺少的明显的东西? 这是问题发生的地方:
SET LowerLimit = @lowlim;
SET UpperLimit = @upplim;
SELECT @lowlim, @upplim;
这是完整的过程。
DELIMITER $$
DROP PROCEDURE if exists p_GetOutlierLimits;
CREATE DEFINER=`user`@`%` PROCEDURE p_GetOutlierLimits(
IN KPI VARCHAR(255), TableName VARCHAR(100),
OUT LowerLimit decimal(16,6), UpperLimit decimal(16,6)
)
BEGIN
SET @lowlim = 0;
SET @upplim = 0;
SET @SQLExec = CONCAT("
with orderedList AS (
SELECT
",KPI,",
ROW_NUMBER() OVER (ORDER BY ",KPI,") AS row_n
FROM ",TableName,"
),
quartile_breaks AS (
SELECT
",KPI,",
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.75)
) AS q_three_lower,
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.75) + 1
) AS q_three_upper,
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.25)
) AS q_one_lower,
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.25) + 1
) AS q_one_upper
FROM orderedList
),
iqr AS (
SELECT
",KPI,",
(
(SELECT MAX(q_three_lower)
FROM quartile_breaks) +
(SELECT MAX(q_three_upper)
FROM quartile_breaks)
)/2 AS q_three,
(
(SELECT MAX(q_one_lower)
FROM quartile_breaks) +
(SELECT MAX(q_one_upper)
FROM quartile_breaks)
)/2 AS q_one,
1.5 * ((
(SELECT MAX(q_three_lower)
FROM quartile_breaks) +
(SELECT MAX(q_three_upper)
FROM quartile_breaks)
)/2 - (
(SELECT MAX(q_one_lower)
FROM quartile_breaks) +
(SELECT MAX(q_one_upper)
FROM quartile_breaks)
)/2) AS outlier_range
FROM quartile_breaks
)
SELECT MAX(q_one) OVER () - MAX(outlier_range) OVER () AS lower_limit,
MAX(q_three) OVER () + MAX(outlier_range) OVER () AS upper_limit
INTO @lowlim, @upplim
FROM iqr
LIMIT 1;");
PREPARE stmt FROM @SQLExec;
EXECUTE stmt;
SET LowerLimit = @lowlim;
SET UpperLimit = @upplim;
SELECT @lowlim, @upplim;
END$$
DELIMITER ;
CALL p_GetOutlierLimits('576_VMC_Sol_Savings_Pct','vmctco',@LowerLimit, @UpperLimit);
SELECT @LowerLimit, @UpperLimit;
I finally got this function to work correctly until I tried to implement in a production state. When I run this procedure and call, I am only getting a value for the LowerLimit output and a NULL for the UpperLimit output. I added a SELECT in the procedure that shows the results for both the internal variables @lowlim and @upplim are being computed, but it appears that only the set for the LowerLimit variable is working. I've been banging on this for hours and can't figure it out so far. Can anyone see anything obvious I'm missing here?
Here is where the problem is occurring:
SET LowerLimit = @lowlim;
SET UpperLimit = @upplim;
SELECT @lowlim, @upplim;
Here is the full procedure.
DELIMITER $
DROP PROCEDURE if exists p_GetOutlierLimits;
CREATE DEFINER=`user`@`%` PROCEDURE p_GetOutlierLimits(
IN KPI VARCHAR(255), TableName VARCHAR(100),
OUT LowerLimit decimal(16,6), UpperLimit decimal(16,6)
)
BEGIN
SET @lowlim = 0;
SET @upplim = 0;
SET @SQLExec = CONCAT("
with orderedList AS (
SELECT
",KPI,",
ROW_NUMBER() OVER (ORDER BY ",KPI,") AS row_n
FROM ",TableName,"
),
quartile_breaks AS (
SELECT
",KPI,",
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.75)
) AS q_three_lower,
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.75) + 1
) AS q_three_upper,
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.25)
) AS q_one_lower,
(
SELECT ",KPI," AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM ",TableName,")*0.25) + 1
) AS q_one_upper
FROM orderedList
),
iqr AS (
SELECT
",KPI,",
(
(SELECT MAX(q_three_lower)
FROM quartile_breaks) +
(SELECT MAX(q_three_upper)
FROM quartile_breaks)
)/2 AS q_three,
(
(SELECT MAX(q_one_lower)
FROM quartile_breaks) +
(SELECT MAX(q_one_upper)
FROM quartile_breaks)
)/2 AS q_one,
1.5 * ((
(SELECT MAX(q_three_lower)
FROM quartile_breaks) +
(SELECT MAX(q_three_upper)
FROM quartile_breaks)
)/2 - (
(SELECT MAX(q_one_lower)
FROM quartile_breaks) +
(SELECT MAX(q_one_upper)
FROM quartile_breaks)
)/2) AS outlier_range
FROM quartile_breaks
)
SELECT MAX(q_one) OVER () - MAX(outlier_range) OVER () AS lower_limit,
MAX(q_three) OVER () + MAX(outlier_range) OVER () AS upper_limit
INTO @lowlim, @upplim
FROM iqr
LIMIT 1;");
PREPARE stmt FROM @SQLExec;
EXECUTE stmt;
SET LowerLimit = @lowlim;
SET UpperLimit = @upplim;
SELECT @lowlim, @upplim;
END$
DELIMITER ;
CALL p_GetOutlierLimits('576_VMC_Sol_Savings_Pct','vmctco',@LowerLimit, @UpperLimit);
SELECT @LowerLimit, @UpperLimit;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要为每个参数声明
out
:https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html 说:
You need to declare
OUT
for each parameter:https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html says: