轉 replace 與 update 區分
本文主要對比一下 Sqlite 中的 replace 語句和 update 語句 。javascript
在本例中使用以下數據庫表:java
該表的表名爲student, 存儲學生信息。 全部字段的數據類型都是TEXT 。 其中id和name做爲複合主鍵。 email字段加上了惟一約束。建表語句以下:sql
CREATE TABLE IF NOT EXISTS student (
"id" TEXT, "name" TEXT NOT NULL, "sex" TEXT, "email" TEXT UNIQUE, "fenshu" TEXT CHECK(fenshu > 0), "tecid" TEXT REFERENCES teacher(id), "class" TEXT, PRIMARY KEY(id, name) )
爲了驗證這個結論, 下面打開Sqlite命令行, 執行如下語句來替換id爲2的記錄。數據庫
sqlite> replace into student (id, name, sex, email, fenshu, tecid, class) values ('2', 'lisi', '*F', '123456@qq.com', '80', '2', '1');
執行完這條語句以後, student表中的數據變成下圖所示:bash
對比圖1和圖2 , 能夠發現: 在圖1中, id爲2 的記錄是表中的第一條記錄, 當執行完上述的replace語句以後, id爲2的記錄位於整張表的最後。 這就說明, 這條replace語句刪除了原有的id爲2的記錄, 有插入了一條新的id爲2的記錄。ui
下面咱們仍是以id爲2 的記錄作實驗, 執行以下語句:spa
sqlite> replace into student (id, name, sex, email, fenshu, tecid) values ('2','lisi', '*F', '123456@qq.com', '80', '2');
該語句仍是替換id爲2, name爲lisi的記錄, 只是在指定列的時候, 沒有指定class列。 在執行完成以後, 表中的數據以下:.net
對比圖2和圖3 , 能夠看到, id爲2, name爲lisi的記錄的class字段沒有值。命令行
在該表中, 把id和name指定爲複合主鍵。 在上面兩條語句執行的時候, 都在values中指定了id爲2, name爲lisi 。 執行以後看到的結果也是id爲2, name爲lisi的記錄被替換。 這就說明了replace語句根據主鍵的值肯定被替換的是哪一條記錄。code
執行如下語句:
sqlite> replace into student (id, name, sex, email, fenshu, tecid) values ('2','lisi', '*F', '123456@qq.com', '80', '2') where id = '2';
會報以下錯誤:
Error: near "where": syntax error
在student表中, 咱們讓id和name成爲複合主鍵。 下面咱們使用replace語句替換id爲100, name爲a 的記錄。 從圖3中能夠看到, 表中存在name爲a的記錄, 可是這條記錄的id爲7, 而不是100 。也就是說 id爲100, name爲a 的記錄不存在。
執行以下語句:
sqlite> replace into student (id, name, sex, email, fenshu, tecid, class) values ('100', 'a', '*F', '123456@qq.com', '80', '2', '1');
執行完成以後, 表中的數據以下:
能夠看到, 在表中插入了一條新的記錄。
上面的第5步同時也說明了這個問題。 對比圖4 和圖5 , 發如今插入一條新的id爲100, name爲a的記錄以後, 還刪除了id爲2, name爲lisi的記錄。 爲何會這樣呢? 咱們在開始的時候說過, 表中的email字段加上了惟一約束。 id爲2的記錄的email和新插入的id爲100的記錄中的email相同, 都是123456@qq.com 。 這就致使違反惟一約束, 因此在插入id爲100的記錄以前, 刪除了id爲2的記錄。
下面再次驗證一下。 如今咱們替換id爲5, name爲lisi3 的記錄, 將它的email替換爲2@163.com 。 表中的id爲5的記錄的email字段也是2@163.com , 因此會致使違反惟一約束。
執行下面的語句:
sqlite> replace into student (id, name, sex, email, fenshu, tecid, class) values ('5', 'lisi3', 'F', '2@163.com', '80', '2', '1');
執行完這條語句以後, 表中的數據以下圖:
對比圖4 和 圖5 , 發現id爲5的記錄被替換掉, 而且把這條記錄的email設置爲2@163.com, 這和圖4中原有的id爲6的記錄衝突, 因此致使id爲6的記錄被刪除, 在圖5 中已經沒有id爲6的那條記錄了。
update語句使用where子句定位被更新的記錄;
update語句能夠一次更新一條記錄, 也能夠更新多條記錄, 只要這多條記錄都複合where子句的要求;
update只會在原記錄上更新字段的值, 不會刪除原有記錄, 而後再插入新紀錄;
若是在update語句中沒有指定一些字段, 那麼這些字段維持原有的值, 而不會被置空;