$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;