84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
$q=2; ① $sql="select * from user where id ='".$q."'"; ② $sql="select * from user where id ='$q'"; ③ $sql="select * from user where id =$q";
以上三条语句执行效果是一样的 ①②里面$q是字符串型的吧 ③的$q是整型 我这样理解不知道对不对
user表里的id字段设置的是int 为何查询的时候是字符串型的也能查出来呢
菜鸟在此谢过
走同样的路,发现不同的人生
这个不只是作为主键会产生问题,作为其他索引键也会有类似问题。 int型索引字段,查询时加”,不会导致查询时不使用索引, 而字符换类型字段,查询不加”,却会导致查询时不适用索引, 而且还有一点是如果没有这个单引号,Innodb的存储引擎表的查询都会因为无索引可以,而上升为表级锁定
找到一篇介绍这个文章:http://www.zendstudio.net/archives/single-quotes-or-no-single-quotes-in-sql-query/
@江湖大虾仁 的答案是说插入数据时候,数据类型的问题,这个和MySQL的严格模式也有关系,严格模式下对语法要求更严格,那时候就不是warning了。
在查询条件里的单引号问题,这个主要考虑是不是影响使用索引,上面引文里说的很明白,对int无所谓的,但是对char就有区别了。
int
char
注:没有测试严格模式下查询语句中 int 字段值加不加单引号 会不会报错。
严格模式
针对 @R.ming 的回答我更新下。我想表达的是mysql在类型不同的情况下他会自动进行类型转换,这不光是在数据插入的时候才会做,在数据更新、查询和删除的时候都会这么做。
老规矩,上例子。(重点是最后一个select)
mysql> create table temp(a varchar(10)); Query OK, 0 rows affected (0.01 sec) mysql> insert into temp values('a'); Query OK, 1 row affected (0.01 sec) mysql> insert into temp values('1'); Query OK, 1 row affected (0.00 sec) mysql> select * from temp where a = 1; +------+ | a | +------+ | 1 | +------+ 1 row in set, 1 warning (0.01 sec) mysql> select * from temp where a = 0; +------+ | a | +------+ | a | +------+ 1 row in set, 1 warning (0.00 sec)
反对公子的答案,这个和php无关,对于php来说这三条sql语句都只是普通的字符串而已。楼主这个问题是因为mysql他做了兼容处理。对于字段是int类型的,如果你传入字符串(无论是在select, insert 还是 update),他会尝试转为数字的(类似于php中的intval)。具体可以看下面贴的这个例子。
另外,如果在诸如postgresql之类的数据库上,这种类型不符是会抛错误的。
p.s. 由于mysql的这种特性,一般推荐无论是否是字符串类型,全部加上单引号以降低sql注入的风险。← 不是说加了单引号就无法注入了,降低而已。 再p.s. 更推荐prepared statement
mysql> create table temp (k int); Query OK, 0 rows affected (0.02 sec) mysql> desc temp; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | k | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.04 sec) mysql> insert into temp values(1),(2),(3),('a'); Query OK, 4 rows affected, 1 warning (0.01 sec) Records: 4 Duplicates: 0 Warnings: 1 mysql> select * from temp; +------+ | k | +------+ | 1 | | 2 | | 3 | | 0 | +------+ 4 rows in set (0.00 sec) mysql> update temp set k = 'a' where k = 1; Query OK, 1 row affected, 1 warning (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 1 mysql> update temp set k = '20' where k = 2; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update temp set k = '30a' where k = 3; Query OK, 1 row affected, 1 warning (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 1 mysql> select * from temp; +------+ | k | +------+ | 0 | | 20 | | 30 | | 0 | +------+ 4 rows in set (0.00 sec)
PHP里面数据库读取是不分字段类型的,这个好像被很多大神吐槽过了。
mysql下直接执行下面两条语句效果一样,是数据库的原因,跟PHP没有关系虽然PHP本身是弱类型。select * from user where id ='1';select * from user where id =1;
select * from user where id ='1';
select * from user where id =1;
找到一篇介绍这个文章:
http://www.zendstudio.net/archives/single-quotes-or-no-single-quotes-in-sql-query/
@江湖大虾仁 的答案是说插入数据时候,数据类型的问题,这个和MySQL的严格模式也有关系,严格模式下对语法要求更严格,那时候就不是warning了。
在查询条件里的单引号问题,这个主要考虑是不是影响使用索引,上面引文里说的很明白,对
int
无所谓的,但是对char
就有区别了。注:没有测试
严格模式
下查询语句中int
字段值加不加单引号 会不会报错。针对 @R.ming 的回答我更新下。我想表达的是mysql在类型不同的情况下他会自动进行类型转换,这不光是在数据插入的时候才会做,在数据更新、查询和删除的时候都会这么做。
老规矩,上例子。(重点是最后一个select)
反对公子的答案,这个和php无关,对于php来说这三条sql语句都只是普通的字符串而已。楼主这个问题是因为mysql他做了兼容处理。对于字段是int类型的,如果你传入字符串(无论是在select, insert 还是 update),他会尝试转为数字的(类似于php中的intval)。具体可以看下面贴的这个例子。
另外,如果在诸如postgresql之类的数据库上,这种类型不符是会抛错误的。
p.s. 由于mysql的这种特性,一般推荐无论是否是字符串类型,全部加上单引号以降低sql注入的风险。← 不是说加了单引号就无法注入了,降低而已。
再p.s. 更推荐prepared statement
PHP里面数据库读取是不分字段类型的,这个好像被很多大神吐槽过了。
mysql下直接执行下面两条语句效果一样,是数据库的原因,跟PHP没有关系虽然PHP本身是弱类型。
select * from user where id ='1';
select * from user where id =1;