mysql用户变量的陷阱!

1. 用户变量

用户变量是指通过set语句:set @var_name = expr [, @var_name = expr]对指定变量名赋值,然后在以后引用它。用户变量的形式为@var_name,以后的引用也是这样。

set语句注意点:

1) 可以使用=或:=作为分配符。

2) 变量expr可以为整数、实数、字符串或者NULL值。

3) 可以使用非set语句代替set来为用户变量分配一个值,此时分配符必须为:=而不能用=。

4) 使用没有初始化的用户变量,其值为NULL,类型为字符串。

用户变量注意点:

1) 用户变量和连接有关。(这意味着:一个客户端定义的变量不能被其它客户端看到或使用。当客户端退出时,该客户端连接的所有变量将自动释放。)

2) 用户变量不使用查询缓存。

3) 用户变量大小写不敏感。(mysql5.0及其以上版本)

4) 用户变量不能准确的指定类型。

2. 使用

mysql> SET @t1=0, @t2=0, @t3=0;

mysql> SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;

+----------------------+------+------+------+

| @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 |

+----------------------+------+------+------+

| 5 | 5 | 1 | 4 |

+----------------------+------+------+------+

mysql> select @t:=count(*) from admin;

+--------------+

| @t:=count(*) |

+--------------+

| 1 |

+--------------+

注意:在SELECT语句中,表达式发送到客户端后才进行计算。

3. 变量使用的陷阱

3.1看一个官方文档的例子:

mysql> set @a='test';

mysql> select @a,(@a:=20) from admin;

+------+----------+

| @a | (@a:=20) |

+------+----------+

| test | 20 |

+------+----------+

mysql> select @a;

+------+

| @a |

+------+

| 20 |

+------+

这个列子中,第一个set语句表示@a是一个字符串,并且将@a的所有访问转换为字符串,即使@a在第2行中被设置为一个数字。但是在执行select语句后,@a被视为下一语句的数字。

3.2 一个行号的用户变量

mysql> create table test (id int primary key, value int) ENGINE=InnoDB;

Query OK, 0 rows affected (0.03 sec)

mysql> insert into test values(1, 1), (2, 10), (3, 12), (4, 5), (5, 20);

Query OK, 5 rows affected (0.03 sec)

Records: 5 Duplicates: 0 Warnings: 0

mysql> set @rownum = 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select @rownum := @rownum + 1 as rownum, id, value

-> from test where @rownum < 2;

+--------+----+-------+

| rownum | id | value |

+--------+----+-------+

| 1 | 1 | 1 |

| 2 | 2 | 10 |

+--------+----+-------+

2 rows in set (0.00 sec)

我们执行的最后一条语句得到的结果不是我们想要的。为什么会这样?Mysql内部执行的过称是这样的:首先,判断where条件@rownum < 2,而第一次@rownum为0,返回一会结果,@rownum此时为1,小于2,又会返回一行,此时@rownum为2,结束。

解决的办法是将条件写在where中:

mysql> select @rownum as rownum, id, value from test

-> where (@rownum := @rownum + 1) < 2;

3.3 对于行号的用户变量延伸

mysql> set @rownum = 0;

mysql> select @rownum := @rownum + 1 as rownum, id, value

-> from test where @rownum < 2 order by value;

+--------+----+-------+

| rownum | id | value |

+--------+----+-------+

| 1 | 1 | 1 |

| 2 | 4 | 5 |

| 3 | 2 | 10 |

| 4 | 3 | 12 |

| 5 | 5 | 20 |

+--------+----+-------+

5 rows in set (0.00 sec)

我们还是用刚才的数据,可是这次执行的结果更出乎我们的意料。Mysql内部执行的过称是这样的:首先where判断@rownum < 2,然后order by,最后select。(同上)

解决的办法是将条件写在where中:

mysql> select @rownum as rownum, id, value from test

-> where (@rownum := @rownum + 1) < 2 order by value;

对以上这几个问题产生原因的解释:

我们同时在一条语句中对一个用户变量进行了赋值和取值,这样就有可能导致我们上面问题的存在!所以,一般原则是不要在语句的一个部分为用户变量分配一个值而在同一语句的其它部分使用该变量。

注:本文mysql版本5.1.42。

1 楼

Technoboy

2011-04-08

这个问题大家一直没有发现吗?

2 楼

Summer花的姿态

2011-04-19

3 楼

曾老师

2012-09-14

我遇到一个问题 就是 分页的时候 rownum作为 行号 都是 1.0 2.0 3.0 要怎么解决啊

请回答

4 楼

曾老师

2012-09-14

set @rownum = 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select @rownum := @rownum + 1 as rownum, id, value

-> from test where @rownum < 2;

mysql set类型的用户变量,mysql用户变量的圈套相关推荐

  1. mysql image类型_MyCat教程【mysql主从复制实现】

    原文:http://iii75.cn/mwQhBW 作者:波波烤鸭 历史相关文章 Mycat入门教程 单个mysql数据库在处理业务的时候肯定是有限的,这时我们扩展数据库的第一种方式就是对数据库做读写 ...

  2. hibernate mysql 映射_hibernate与mysql映射类型对应表与mysql导入导出

    http://blog.sina.com.cn/s/blog_5f240fc40100etlt.html 一.记录下hibernate mysql映射类型对应表: 1.常规Hibernate 映射 i ...

  3. Mysql varchar类型长度计算(mysql字段长度计算)

    博客上的文章深度参差不齐,本人也是看了好几篇博客才找到另自己满意的博客. 1.限制规则 字段的限制在字段定义的时候有以下规则: a)存储限制 varchar 字段是将实际内容单独存储在聚簇索引之外,内 ...

  4. mysql varchar类型实例_Mysql实例MySQL数据类型varchar详解

    <Mysql实例MySQL数据类型varchar详解>要点: 本文介绍了Mysql实例MySQL数据类型varchar详解,希望对您有用.如果有疑问,可以联系我们.1.varchar(N) ...

  5. mysql 字符串类型 小数_在Mysql中,小数数据类型是指由字符串来表示的数字。(  )...

    [单选题]中药检查项下的总灰分是指( ) [单选题]中国药典规定取某样品 2.00g ,系指称取的质量应为( ) [多选题]中国药典2015版鉴别中药真伪的方法有( ) [多选题]中药及其制剂的鉴别方 ...

  6. MySQL text类型的最大长度

     MySQL text类型的最大长度             MySQL 3种text类型的最大长度如下: TEXT 65,535 bytes ~64kb MEDIUMTEXT 16,777,21 ...

  7. mysql boolean类型_mysql 布尔类型

    ...对象的原型创建的函数: var myvar = new Boolean(1); myvar.constructor; 结果输出: function Boolean() { [native cod ...

  8. Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)

    所有示例使用的数据表均为Oracle提供的SQL基础数据表(t_employees.sql dept.sql emp.sql salgrade.sql) 熟练掌握多多练习即可达到完成后端开发所需具备的 ...

  9. mysql $gt_mysql变量(用户+系统)

    9.3. 用户变量 可以先在用户变量中保存值然后在以后引用它:这样可以将值从一个语句传递到另一个语句.用户变量与连接有关.也就是说,一个客户端定义的变量不能被其它客户端看到或使用.当客户端退出时,该客 ...

最新文章

  1. 星际2虫王iA加入商汤,担任AI研究员,网友:iA vs AI ,是自己训练跟自己打吗?...
  2. idea解决maven全局配置
  3. pip升级python版本_GEE学习笔记 六十八:【GEE之Python版教程二】配置Python开发环境...
  4. 这几天惨遭Delphi类型转换折磨,请问怎么把double转成int类型
  5. 参加计算机俱乐部的英语怎么说,参加象棋俱乐部用英语怎么说
  6. 如何查看电脑配置信息_如何查看软件著作权登记的信息?
  7. 4.5.2 Stress Testing
  8. android 控件发光_Android自定义控件打造闪闪发光字体
  9. L1-087 机工士姆斯塔迪奥 - java
  10. java如何连接与断开SQL server2008数据库
  11. 《Node.js开发指南》读书笔记
  12. wifi打印机打印(二维码,条形码等)
  13. python基金预测分析_Python爬虫抓取基金数据分析、预测系统设计与实现
  14. 如何做好 OSPO,推动企业开源丨雨林开源行
  15. web应用票据打印实现(一)
  16. 最早游戏空当接龙计算机,电脑中随机附带的游戏空当接龙怎么玩?
  17. java代码使用.pac脚本自动配置代理服务器策略
  18. 使用proxychains代理时报错:!!!need more proxies!!!解决办法
  19. Altium Designer 20 入门基础知识(2)
  20. Android相机、相册获取图片显示并保存到SD卡

热门文章

  1. 小米应用使用时间统计_应用统计Screentime|一款帮你知道每天手机和APP使用时间的软件 | 我爱分享网...
  2. 人工智能和计算机视觉(5)-边缘检测
  3. [book]自卑与超越
  4. Needleman–Wunsch algorithm
  5. 章鱼体验第一天:思杰VDI之7.14.1
  6. 数百家门店“联营管理” 鞋企瑞贝卡为何看重IMO班聊?
  7. html5写手机端页面
  8. 宇视网络视频录像机“设备级”、“通道级”告警是什么意思
  9. Tennessee Eastman(TE)田纳西-伊斯曼仿真平台应用试验与分析
  10. p标签和超链接的认识