最近在写存储过程的时候发现一个问题:
有的代码赋值语句使用的是:=
,有些代码使用的又是=
,于是就产生了一个疑问,这两者之间有什么区别?
在网上搜了很久,也没有找到一个满意的答案,于是直接去MySQL官方文档中寻求解释。果然,MySQL官方文档专门对这两者的区别做了说明,下面是官方文档的部分说明:
Unlike =, the := operator is never interpreted as a comparison operator. This means you can use := in
any valid SQL statement (not just in SET statements) to assign a value to a variable.
Within a SET statement, = is treated as an assignment operator that causes the user variable on the
left hand side of the operator to take on the value to its right. (In other words, when used in a SET
statement, = is treated identically to :=.) The value on the right hand side may be a literal value, another
variable storing a value, or any legal expression that yields a scalar value, including the result of a query
(provided that this value is a scalar value). You can perform multiple assignments in the same SET
statement.
In the SET clause of an UPDATE statement, = also acts as an assignment operator; in this case,
however, it causes the column named on the left hand side of the operator to assume the value given
to the right, provided any WHERE conditions that are part of the UPDATE are met. You can make multiple
assignments in the same SET clause of an UPDATE statement.
In any other context, = is treated as a comparison operator.
翻译过来大意就是:
-
:=
在任何情况下都会被当作是赋值操作,因此,如果你确实想要进行赋值操作,那就大胆使用:=
就好了; -
在以下两种情况下,
=
和:=
是等效,都会被当作赋值操作:- 在使用
SET
操作符进行赋值时;
如: SET @param = 1 与 SET @param := 1的效果是一样的,都是将1赋给@param - 在
UPDATE
语句的SET
语句中;
如 UPDATE t_user SET phone_num = ‘13888888888’ WHERE user_name = ‘蔡徐坤’;
- 在使用
-
在其他的任何条件下,
=
都会被当作比较操作。
下面介绍一个经典的案例:
给查询结果集中的每条数据加一个递增的序号
:
赋值语句使用:=
# 在 SET 操作中 := 和 = 是等效的
SET @row_num := 0;
# 只取前10条展示一下效果
SELECT @row_num := @row_num + 1 AS rowNum, a.* from t_user_view a where a.user_id = 1 LIMIT 0,10;
可以看到,rowNum从1开始递增,这符合我们的预期
赋值语句使用=
# 在 SET 操作中 := 和 = 是等效的
SET @row_num := 0;
# 只取前10条展示一下效果
SELECT @row_num = @row_num + 1 AS rowNum, a.* from t_user_view a where a.user_id = 1 LIMIT 0,10;
可以看到,所有行的rowNum都是0!这是因为 SELECT 语句中的 =
被当成了比较符,@row_num
和 @row_num + 1
的值进行比较,结果总是false,因此rowNum总是0;
为了验证这一猜想,我们可以做如下实验:
SET @row_num := 0;
# 如果此处 = 被当成赋值语句的话,rowNum的值应该总是0
SELECT @row_num = 0 AS rowNum, a.* from t_user_view a where a.user_id = 1 LIMIT 0,10;
如果 SELECT 语句中的 =
被当成赋值语句的话,rowNum的值应该总是0,然而,实际上,rowNum的值恒为1,这是因为 @row_num = 0
条件恒成立。