在 case 语句中更新值并设置局部变量
Posted
技术标签:
【中文标题】在 case 语句中更新值并设置局部变量【英文标题】:Update a value and set a local variable in a case statement 【发布时间】:2022-01-12 22:18:39 【问题描述】:我正在尝试更新数据库中的值,但也想设置一个局部变量VAR_IS_RATE_LIMITED
。这样做的原因是因为我不想使用 select 语句并希望在一个语句中执行它。如何设置VAR_IS_RATE_LIMITED
?我查看了其他问题,但他们的 CASE 语句没有嵌入到更新语句中。
DELIMITER //
CREATE FUNCTION F_RATE_LIMITED(P_IP varchar(45),
P_MAX_RATE int unsigned
)
RETURNS INT UNSIGNED
BEGIN
DECLARE VAR_IS_RATE_LIMITED INT UNSIGNED DEFAULT 0;
INSERT INTO rate_limit (ip, rate)
VALUES (P_IP, 1)
ON DUPLICATE KEY UPDATE
rate =
CASE
WHEN (rate + 1) > P_MAX_RATE THEN
SET VAR_IS_RATE_LIMITED = 1;
rate
ELSE
rate + 1
END;
RETURN VAR_IS_RATE_LIMITED;
END; //
DELIMITER ;
【问题讨论】:
很遗憾,你不能这样做,它不能那样工作,你不能在update
语句中设置变量。
@Stu 在不使用 select 语句的情况下,有什么解决方案可以解决我想要做的事情吗?本质上,我想要的是,如果您超过了速率,我希望函数返回 1。
【参考方案1】:
要在数据修改语句期间设置某些内容,它必须是表达式的一部分,而不是语句。据我所知,您不能在表达式中设置存储的函数变量。但是你可以设置一个用户变量:
DELIMITER //
CREATE FUNCTION F_RATE_LIMITED(P_IP varchar(45),
P_MAX_RATE int unsigned
)
RETURNS INT UNSIGNED
BEGIN
SET @VAR_IS_RATE_LIMITED = 0;
INSERT INTO rate_limit (ip, rate)
VALUES (P_IP, 1)
ON DUPLICATE KEY UPDATE
rate =
CASE
WHEN (rate + 1) > P_MAX_RATE THEN
CASE WHEN @VAR_IS_RATE_LIMITED := 1 THEN rate END
ELSE
rate + 1
END;
RETURN @VAR_IS_RATE_LIMITED;
END; //
DELIMITER ;
这里的变量是在 CASE 测试中设置的(您也可以使用 IF 表达式),该测试始终为真,因此始终从 CASE 返回 rate。
【讨论】:
理论上你可以在 INSERT 之后检查 FOUND_ROWS() ;如果插入了一行,它应该是 1,如果更新了一行,它应该是 2,如果达到限制,它应该是 0,所以没有发生任何变化。但我无法让它工作。以上是关于在 case 语句中更新值并设置局部变量的主要内容,如果未能解决你的问题,请参考以下文章