程序员在编程过程中, 经常会在代码中使用到 "where 1=1", 这是为什么呢?
SQL 注入
初次看到这种写法的同学肯定很纳闷, 加不加 where 1=1, 查询不都一样吗? 例如:
select * from customers;
与
select * from customers where 1=1;
查询出来的结果完全没有区别呀.
是的, 上面的查询结果是没有区别, 但是这并不是我们要添加它的目的. 我们知道 1=1 表示 true, 即永真, 在 SQL 注入时配合 or 运算符会得到意向不到的结果.
例如, 当我们要删除客户名称为 "张三" 的记录, 我们可以这样写:
delete from customers where name='张三'
这个时候如果在 where 语句后面加上 or 1=1 会是什么后果?
即:
delete from customers where name='张三' or 1=1
本来只要删除张三的记录, 结果因为添加了 or 1=1 的永真条件, 会导致整张表里的记录都被删除了.
当然这种事我们可千万不能干, 也不能让别人有机可乘, 这里只是为了表述 where 1=1 的作用之一.
语法规范
我们在写代码的过程中, 为了保证语法规范的时候, 也会使用到 where 1=1.
我们先看下面这段 Java 代码:
- String sql="select * from table_name where 1=1";
- if( condition 1) {
- sql=sql+"and var2=value2";
- }
- if(condition 2) {
- sql=sql+"and var3=value3";
- }
如果我们不写 1=1 的话, 当 condition 1 为真时, 代码拼接后被执行的 SQL 代码如下:
select * from table_name where and var2=value2;
很明显, 这里会出现一个 SQL 的语法错误: and 必须前后都有条件.
有人说我直接把 where 写在 if 语句里面, 我就不写 where 1=1.
- String sql="select * from table_name";
- if( condition 1) {
- sql=sql+"where var2=value2";
- }
- if(condition 2) {
- sql=sql+"where var3=value3";
- }
当 condition 1 为真, condition 2 为假时, 上面被执行的 SQL 代码为:
select * from table_name where var2=value2;
这个确实没有语法错误, 但是当 condition 1 和 condition 2 都为真呢? 那么 SQL 语句就变成了这样:
- select * from table_name
- where var2=value2
- where var3=value3;
很明显这是不符合 SQL 语法规范的.
这里写上 where 1=1 是为了避免 where 关键字后面的第一个词直接就是 "and" 而导致语法错误, 加上 1=1 后, 不管后面有没有 and 条件都不会造成语法错误了.
拷贝表
在我们进行数据备份时, 也经常使用到 where 1=1, 当然其实这两可以不写, 写上之后如果想过滤一些数据再备份会比较方便, 直接在后面添加 and 条件即可.
- create table table_name
- as
- select * from Source_table
- where 1=1;
复制表结构
有 1=1 就会有 1<>1 或 1=2 之类的永假的条件, 这个在拷贝表的时候, 加上 where 1<>1, 意思就是没有任何一条记录符合条件, 这样我们就可以只拷贝表结构, 不拷贝数据了.
- create table table_name
- as
- select * from
- Source_table where 1 <> 1;
1=1 的性能问题
在 MySQL 早期的版本中 "where 1=1" 可能会对有所影响, 使用了 "where 1=1" 的过滤条件以后数据系统就无法使用索引等查询优化策略, 数据库系统将会被迫对每行数据进行扫描 (即全表扫描) 以比较此行是否满足过滤条件, 当表中数据量较大时查询速度会非常慢.
但在 5.6 版本 (也可能更早几个版本) 以后这个问题被优化了, 在写 "where 1=1" 时, 查询分析器会将 "1=1" 处理掉, 所以不会对查询造成性能影响, 感兴趣的小伙伴可以试验一下, 反正我试过了.
来源: http://database.51cto.com/art/202109/682466.htm