replace 与 update 区分
本文主要对比一下 Sqlite 中的 replace 语句和 update 语句 。

在本例中使用如下数据库表:

 
图1

该表的表名为student, 存储学生信息。 所有字段的数据类型都是TEXT 。 其中id和name作为复合主键。 email字段加上了唯一约束。建表语句如下:

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)
)

1. replace语句会删除原有的一条记录, 并且插入一条新的记录来替换原记录。

为了验证这个结论, 下面打开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表中的数据变成下图所示:

 
图2

对比图1和图2 , 可以发现: 在图1中, id为2 的记录是表中的第一条记录, 当执行完上述的replace语句之后, id为2的记录位于整张表的最后。 这就说明, 这条replace语句删除了原有的id为2的记录, 有插入了一条新的id为2的记录。

2. 一般用replace语句替换一条记录的所有列, 如果在replace语句中没有指定某列, 在replace之后这列的值被置空 。

下面我们还是以id为2 的记录做实验, 执行如下语句:

sqlite> replace into student (id, name, sex, email, fenshu, tecid) values ('2','lisi', '*F', '123456@qq.com', '80', '2');

该语句还是替换id为2, name为lisi的记录, 只是在指定列的时候, 没有指定class列。 在执行完成之后, 表中的数据如下:

 
图3

对比图2和图3 , 可以看到, id为2, name为lisi的记录的class字段没有值。

3. replace根据主键确定被替换的是哪一条记录

在该表中, 把id和name指定为复合主键。 在上面两条语句执行的时候, 都在values中指定了id为2, name为lisi 。 执行之后看到的结果也是id为2, name为lisi的记录被替换。 这就说明了replace语句根据主键的值确定被替换的是哪一条记录。

4 replace语句不能根据where子句来定位要被替换的记录

执行以下语句:

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

5. 如果执行replace语句时, 不存在要替换的记录, 那么就会插入一条新的记录。

在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');

执行完成之后, 表中的数据如下:

 
图4

可以看到, 在表中插入了一条新的记录。

6. 如果新插入的或替换的记录中, 有字段和表中的其他记录冲突, 那么会删除那条其他记录。

上面的第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');

执行完这条语句之后, 表中的数据如下图:

 
图5

对比图4 和 图5 , 发现id为5的记录被替换掉, 并且把这条记录的email设置为2@163.com, 这和图4中原有的id为6的记录冲突, 所以导致id为6的记录被删除, 在图5 中已经没有id为6的那条记录了。

replace语句和update语句的对比

  • update语句使用where子句定位被更新的记录;

  • update语句可以一次更新一条记录, 也可以更新多条记录, 只要这多条记录都复合where子句的要求;

  • update只会在原记录上更新字段的值, 不会删除原有记录, 然后再插入新纪录;

  • 如果在update语句中没有指定一些字段, 那么这些字段维持原有的值, 而不会被置空;

replace into 详解 update mysql的更多相关文章

  1. [数据库事务与锁]详解六: MySQL中的共享锁与排他锁

    注明: 本文转载自http://www.hollischuang.com/archives/923 在MySQL中的行级锁,表级锁,页级锁中介绍过,行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大 ...

  2. [数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁

    注明: 本文转载自http://www.hollischuang.com/archives/914 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的 ...

  3. MySql安装步骤详解,MySql的root密码设置,启动MySql服务。

    1.下载mysql安装包,并解压,双击mysql-5.6.24-winx64.msi 2.点击下一步 3.选择custom 4.选择安装内容和位置,5个安装内容要选择will be installed ...

  4. PHP商品秒杀问题解决方案实例详解【mysql与redis】

    本文实例讲述了PHP商品秒杀问题解决方案.分享给大家供大家参考,具体如下: 引言 假设num是存储在数据库中的字段,保存了被秒杀产品的剩余数量. if($num > 0){ //用户抢购成功,记 ...

  5. (转)MySQL配置文件mysql.ini参数详解、MySQL性能优化

    本文转自:http://www.cr173.com/html/18331_1.html my.ini(Linux系统下是my.cnf),当mysql服务器启动时它会读取这个文件,设置相关的运行环境参数 ...

  6. MySQL配置文件mysql.ini参数详解、MySQL性能优化

    my.ini(Linux系统下是my.cnf),当mysql服务器启动时它会读取这个文件,设置相关的运行环境参数. my.ini分为两块:Client Section和Server Section.  ...

  7. MySQL配置文件my.cnf中文详解附mysql性能优化方法分享

    Mysql参数优化对于新手来讲,是比较难懂的东西,其实这个参数优化,是个很复杂的东西,对于不同的网站,及其在线量,访问量,帖子数量,网络情况,以及机器硬件配置都有关系,优化不可能一次性完成,需要不断的 ...

  8. Linux开机启动chkconfig命令详解(让MySQL、Apache开机启动)

    chkconfig chkconfig在命令行操作时会经常用到.它可以方便地设置和查询不同运行级上的系统服务.这个可要好好掌握,用熟练之后,就可以轻轻松松的管理好你的启动服务了. 注:谨记chkcon ...

  9. Node.js之【正则表达式函数之match、test、exec、search、split、replace使用详解】

    1. Match函数 使用指定的正则表达式函数对字符串惊醒查找,并以数组形式返回符合要求的字符串 原型:stringObj.match(regExp) 参数: stringObj 必选项,需要去进行匹 ...

随机推荐

  1. 30、Python程序中的线程操作(oncurrent模块)

    进程是cpu资源分配的最小单元,一个进程中可以有多个线程. 线程是cpu计算的最小单元. 对于Python来说他的进程和线程和其他语言有差异,是有GIL锁. GIL锁 GIL锁保证一个进程中同一时刻只 ...

  2. keywordAsVar.php

    <?php //keywordAsVar.php #keywordAsVar.php $True="我是变量True"; echo($True); echo("&l ...

  3. Spark SQL中的Catalyst 的工作机制

      Spark SQL中的Catalyst 的工作机制 答:不管是SQL.Hive SQL还是DataFrame.Dataset触发Action Job的时候,都会经过解析变成unresolved的逻 ...

  4. 如何保护你的 Python 代码 (一)—— 现有加密方案

    https://zhuanlan.zhihu.com/p/54296517 0 前言 去年11月在PyCon China 2018 杭州站分享了 Python 源码加密,讲述了如何通过修改 Pytho ...

  5. js 类型系统的核心:元类型、原型链与内省机制

    js 类型系统的核心:元类型.原型链与内省机制 二.JS数据类型 下面就来看看JS中的数据类型,在js中定义了如下几种数据类型:大方向上分为 基本数据类型(简单数据类型) 和 引用数据类型(复杂数据类 ...

  6. What is the difference between Reactjs and Rxjs?--React is the V (View) in MVC (Model/View/Controller).

    This is really different, React is view library; and Rxjs is reactive programming library for javasc ...

  7. three arrays HDU - 6625 (字典树)

    three arrays \[ Time Limit: 2500 ms \quad Memory Limit: 262144 kB \] 题意 给出 \(a\),\(b\) 数组,定义数组 \(c[i ...

  8. 【转载】java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider

    https://blog.csdn.net/zqz_zqz/article/details/80922164 window上运行以下代码获取jvm进程: List<VirtualMachineD ...

  9. 大文件上传组件webupload插件

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  10. 我的.NET之路

    有时感觉知识比较零散,做个总结形成自己的知识体系,方便查阅[持续更新...] C#语法特性 .Net FrameWork发展史 C# 语言版本发展史 1.NET体系结构 [C#与.NET的关系.公共语 ...