mysql update 语句的行为会根据用户变量是不是存在而有所不同
Posted
技术标签:
【中文标题】mysql update 语句的行为会根据用户变量是不是存在而有所不同【英文标题】:mysql update statement behaves differently based on whether a user variable existsmysql update 语句的行为会根据用户变量是否存在而有所不同 【发布时间】:2008-12-04 20:07:52 【问题描述】:我正在重置具有重复或缺失值的排序列,如下所示:
set @last='';
set @sort=NULL;
update conf_profile set sort=
if(
@last=(@last:=concat(org_id,',',profile_type_id,',',page,',',col)),
(@sort:=@sort+1),
(@sort:=0)
)
order by org_id,profile_type_id,page,col,sort,id;
(遍历所有按多个关键字段排序的行,逐步分配 要排序的递增值;每当这些字段中的任何一个发生更改时,都从 0 重新开始。)
似乎只有在更新之前创建了 @sort 变量时才有效 (尽管它的设置无关紧要)。如果没有'set @sort',所有 排序值设置为 0 或 NULL。
任何想法为什么会这样? mysql 版本 5.0.51。
更新:为了更详细地解释逻辑:在第一行,@last=(@last:=...) 将始终为假,此后当任何关键字段更改时,它将为假 从上一行。 (注意,没有一个被连接的关键字段是 NULL)。 当它为假时,我们从 0 (@sort:=0) 重新开始排序计数器,否则,它是 递增 (@sort:=@sort+1) 并使用新值。
在更新语句中设置 @sort 之前,绝不会使用它,所以无论是 在更新语句之前如何设置应该没有区别。
【问题讨论】:
我知道这是一个老问题,但是“作为一般规则,您永远不应该为用户变量赋值并在同一语句中读取值。”来自User-defined variables 文档的段落涵盖了它吗?换句话说,MySQL 可能会选择做一些完全出乎意料的事情…… 我不知道;它继续展示了违反该一般规则的案例,并解释了您如何期望它们起作用,而我的案例不是其中之一。不过,感谢您的链接。 【参考方案1】:如果您在表达式中引用未设置的用户变量,则会将其视为NULL
。
在 SQL 中,NULL
+ 1 返回 NULL
。如果在此 UPDATE
之前未将 @sort
设置为非 NULL
值,那么无论您评估 @sort:=@sort+1
多少次,它都将继续为 NULL
。一旦你做@sort:=0
,那么它应该正常增加。
试试这个,不要在UPDATE
:
mysql> set @sort := NULL;
mysql> SELECT @sort; -- returns NULL
mysql> set @sort := @sort + 1;
mysql> SELECT @sort; -- returns NULL again
mysql> set @sort := 0;
mysql> set @sort := @sort + 1;
mysql> SELECT @sort; -- returns 1
我猜你第一次设置@sort:=0
后没有重复只是一个巧合。
编辑: 以上是正确的,但正如您所指出的,它并不能解释您所看到的行为,因为从逻辑上讲,@sort
在评估第一行。
但是,我注意到,如果我更改 IF()
表达式中的术语顺序,即使在我们开始时未设置 @sort
,它也能正常工作:
set @last='';
-- set @sort=NULL;
update conf_profile set sort=
if(
@last!=(@last:=concat(org_id,',',profile_type_id,',',page,',',col)),
(@sort:=0),
(@sort:=@sort+1)
)
order by org_id,profile_type_id,page,col,sort,id;
我不确定我是否理解得足够好,无法准确解释为什么会这样,但是关于何时评估用户变量有一些古怪的东西。有关大量示例和血腥细节,请参阅此博客:“Advanced MySQL user variable techniques”。
【讨论】:
抱歉,这并不能解释为什么它可以使用 set @sort=NULL 但不能不使用。以上是关于mysql update 语句的行为会根据用户变量是不是存在而有所不同的主要内容,如果未能解决你的问题,请参考以下文章
PHP 准备 MySQL UPDATE 语句,其中包含字符串中的变量