濮阳杆衣贸易有限公司

主頁 > 知識(shí)庫 > MySQL update set 和 and的區(qū)別

MySQL update set 和 and的區(qū)別

熱門標(biāo)簽:武漢電銷機(jī)器人電話 催天下外呼系統(tǒng) html地圖標(biāo)注并導(dǎo)航 南太平洋地圖標(biāo)注 400電話變更申請(qǐng) 呂梁外呼系統(tǒng) 400電話辦理服務(wù)價(jià)格最實(shí)惠 大豐地圖標(biāo)注app 北京金倫外呼系統(tǒng)

問題描述

最近接到一個(gè)奇怪的咨詢,update 語句執(zhí)行沒有報(bào)錯(cuò),但是沒有更新數(shù)據(jù),具體有問題的語句類似于如下形式:

update test.stu set cname = '0' and math = 90 and his = 80 where id = 100;

原因分析

直觀上看,這個(gè) update 語句的語法是有問題的,正常更新多列數(shù)據(jù)的語法應(yīng)該是用逗號(hào),類似于如下形式:

update test.stu set cname = '0',math = 90,his = 80 where id = 100;

直接用 and 第一反應(yīng)其實(shí)是會(huì)報(bào)語法錯(cuò)誤,不太像是能正常執(zhí)行的。那么基于騰訊云數(shù)據(jù)庫 MySQL,實(shí)際構(gòu)造一個(gè)簡(jiǎn)單的場(chǎng)景,嘗試復(fù)現(xiàn)一下這個(gè)問題。

SQL 語句如下:

CREATE TABLE `stu` (
  `id` int(11) NOT NULL,
  `sname` varchar(16) NOT NULL,
  `cname` varchar(8) DEFAULT NULL,
  `math` int(11) NOT NULL,
  `eng` int(11) DEFAULT NULL,
  `his` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

insert into stu values(100,'sam','0',90,88,83);
insert into stu values(101,'jhon','1',97,82,81);
insert into stu values(102,'mary','2',87,89,92);
insert into stu values(103,'adam','2',87,89,92);

然后分別試一試正常的 update 語句和使用 and 的 update 語句,看一下實(shí)際的運(yùn)行結(jié)果:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update test.stu set cname = '0' and math = 90 and his = 80 where id = 100;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   83 |
| 101 | jhon  | 1     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)

mysql> update test.stu set cname = '0',math = 90,his = 80 where id = 100;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   80 |
| 101 | jhon  | 1     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.01 sec)

mysql>

可以看到這兩個(gè)語句確實(shí)都不會(huì)報(bào)錯(cuò),且?guī)?and 的 update 語句匹配到了具體的行(Rows matched: 1),但是沒有修改數(shù)據(jù)(Changed: 0),標(biāo)準(zhǔn)語法下的 update 語句倒是正常修改了數(shù)據(jù)。

由此可見,MySQL 在語法上,并不認(rèn)為 and 這個(gè)用法是錯(cuò)誤的,那么說明 MySQL 用另外的方式“解讀”了這個(gè)語句。最容易想到的,就是 MySQL 是不是在 set 的時(shí)候,把 and 解釋成了邏輯運(yùn)算符,而不是英文意義上的“和”?而且 cname 的取值本來就是 0,也符合數(shù)據(jù)庫處理 bool 數(shù)據(jù)時(shí)的行為(用 0 和 1 代替 False 和 True)。

驗(yàn)證起來很簡(jiǎn)單,換個(gè) cname 不為 0 的數(shù)據(jù) update 一下就可以了:

mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   83 |
| 101 | jhon  | 1     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)

mysql> begin;update test.stu set cname = '0' and math = 90 and his = 80 where id = 101;
Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   83 |
| 101 | jhon  | 0     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

從結(jié)果來看,MySQL 修改 cname 的值為 0,說明確實(shí)是當(dāng)成邏輯運(yùn)算符來處理了,仔細(xì)分析這個(gè)語句,會(huì)發(fā)現(xiàn) MySQL 按照如下方式來處理:

set cname = ('0' and math = 90 and his = 80)

math 和 his 的取值是根據(jù) where 條件篩選的行來決定的,實(shí)際對(duì)應(yīng)到上面測(cè)試的場(chǎng)景,會(huì)變成如下的邏輯判斷:

'0' and 97 = 90 and 81 = 80

PS:需要注意,即便是字符型的數(shù)據(jù) 0,也會(huì)被當(dāng)做 False。

解決方案

目前并不能通過 sql_mode 或者其他參數(shù)的形式來阻止這種帶 and 的 update 語句,因此這一類問題的隱蔽性比較強(qiáng)。建議在開發(fā)的時(shí)候,利用封裝好的框架,或者加強(qiáng)代碼或者 SQL review 來避免這個(gè)問題。

PS:騰訊云數(shù)據(jù)庫 MySQL 也會(huì)有類似的問題,需要警惕。

以上就是MySQL update set 和 and的區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于MySQL update set 和 and的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • 實(shí)操M(fèi)ySQL+PostgreSQL批量插入更新insertOrUpdate
  • MySQL UPDATE 語句的非標(biāo)準(zhǔn)實(shí)現(xiàn)代碼
  • mysql update case 更新字段值不固定的操作
  • Mysql update多表聯(lián)合更新的方法小結(jié)
  • mysql事務(wù)select for update及數(shù)據(jù)的一致性處理講解
  • MySQL UPDATE 語句一個(gè)“經(jīng)典”的坑

標(biāo)簽:龍巖 自貢 麗水 南充 西寧 徐州 迪慶 無錫

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MySQL update set 和 and的區(qū)別》,本文關(guān)鍵詞  MySQL,update,set,和,and,的,區(qū)別,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MySQL update set 和 and的區(qū)別》相關(guān)的同類信息!
  • 本頁收集關(guān)于MySQL update set 和 and的區(qū)別的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    阿克苏市| 富川| 密云县| 讷河市| 宽城| 永济市| 唐河县| 浦县| 中江县| 涪陵区| 庆元县| 永顺县| 乐清市| 拜泉县| 祁阳县| 固始县| 阿拉善右旗| 千阳县| 泗阳县| 龙泉市| 河北省| 青海省| 嘉峪关市| 清丰县| 沙湾县| 曲靖市| 常州市| 巴楚县| 凤庆县| 广河县| 湘阴县| 桓台县| 南澳县| 卫辉市| 晋江市| 南涧| 吉水县| 本溪市| 梧州市| 曲松县| 神木县|