转 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语句中没有指定一些字段, 那么这些字段维持原有的值, 而不会被置空;