搜尋

首頁  >  問答  >  主體

mysql - 数据库查询字段类型问题

$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
为何查询的时候是字符串型的也能查出来呢

菜鸟在此谢过

怪我咯怪我咯2821 天前844

全部回覆(4)我來回復

  • PHP中文网

    PHP中文网2017-04-17 11:37:29

    這個不只是作為主鍵會產生問題,作為其他索引鍵也會有類似問題。 int型索引字段,查詢時加”,不會導致查詢時不使用索引,
    而字元換類型字段,查詢不加”,卻會導致查詢時不適用索引,
    而且還有一點是如果沒有這個單引號,Innodb的儲存引擎表的查詢都會因為無索引可以,而上升為表格級鎖定

    找到一篇介紹這篇文章:
    http://www.zendstudio.net/archives/single-quotes-or-no-single-quotes-in-sql-query/

    @江湖大蝦仁 的答案是說插入資料時候,資料類型的問題,這個和MySQL的嚴格模式也有關係,嚴格模式下對文法要求更嚴格,那時候就不是warning了。

    在查詢條件裡的單引號問題,這個主要考慮是不是影響使用索引,上面引文裡說的很明白,對int無所謂的,但是對char就有區別了。

    註:沒有測驗严格模式下查詢語句中 int 欄位值加上不加單引號 會不會報錯。

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-17 11:37:29

    針對 @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)
    
    

    回覆
    0
  • 阿神

    阿神2017-04-17 11:37:29

    PHP裡面資料庫讀取是不分字段類型的,這個好像被很多大神吐槽過了。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 11:37:29

    mysql下直接執行下面兩條語句效果一樣,是資料庫的原因,跟PHP沒有關係雖然PHP本身是弱型別。
    select * from user where id ='1';
    select * from user where id =1;

    回覆
    0
  • 取消回覆