SQL经典实例(四)插入、更新和删除[通俗易懂]

SQL经典实例(四)插入、更新和删除[通俗易懂]SQL经典实例(四)插入、更新和删除

大家好,又见面了,我是你们的朋友全栈君。

插入默认值

定义表的某些列的默认值:

create table D (id integer default 0);

所有的数据库都支持使用default关键字来显式地为某一列指定默认值:

insert into D values(default);

Oracle 8i数据库及更早的版本不支持default关键字,因此没办法为某一列显式地插入默认值。
如果所有的列都预设了默认值,MySQL允许制定一个空白的values列表为所有列创建预设的默认值:

MySQL

insert into D values();

如果数据表中某些列没有设定默认值,而某些列设定了默认值,那么在插入数据的时候之哟啊不把预设了默认值的列写入insert列表,就可以方便地为其插入默认值。考虑如下表:

create table DD (id integer default 0, foo varchar(10));

insert列表中只指定foo列:

insert into DD (foo) values ('Bar');

clipboard.png
也可以使用null值覆盖默认值:

insert into DD (id, foo) values (null, 'Brighten');

clipboard.png

复制数据到另一个表

insert into dept_east (deptno, dname, loc)
select deptno, dname, loc
    from dept
where loc in ('NEW YORK', 'BOSTON');

注意在insert列表后没有values关键字。

复制表定义

DEPT表创建一个副本DEPT_2,但是只要表结构,不复制数据:

create table dept_2
as
select * from dept
    where 1=0;

多表插入

Oracle可以使insert all或者insert first语法
Oracle

insert all
    when loc in ('NEW YORK', 'BOSTON') then
        into dept_east (deptno, dname, loc) values (deptno, dname, loc)
    when loc in ('CHICAGO') then
        into dept_mid (deptno, dname, loc) values (deptno, dname, loc)
    else 
        into dept_west (deptno, dname, loc) values (deptno, dname, loc)
select deptno, dname, loc
    from dept;

insert allinsert first的区别就是:一旦WHEN-THEN-ELSE的结果为真,insert first会立即结束评估,insert all则会逐一评估所有的条件,而不论前面的测试结果是否为真,所以使用insert all可能把同一行数据插入到多个表中。
也就是说,当使用insert first时,如果满足某一个whenelse条件,判断过程就会立即返回,不会再继续评估其他判断条件是否成立,保证每次过程都只有一条记录插入到一张表中。

禁止插入特定列

如果想要阻止用户或者错误的软件应用程序在某些列中插入数据,可以创建一个视图,只暴露那些你希望暴露的列,然后强制所有的insert语句都被传送到该视图。向一个简单视图插入数据,数据库服务器会把它转换为针对基础表的插入操作。
例如,创建如下视图:

create view new_emps as
select empno, ename, job
    from emp;

执行下列插入语句

insert into new_emps (empno, ename, job)
    values (1, 'Jonathan', 'Editor');

会被翻译成:

insert into emp (empno, ename, job)
    values (1, 'Jonathan', 'Editor');

当相关行存在时更新记录

例如,如果一个员工出现在EMP_BONUS表中, 将他的工资(在EMP表中)上涨20%。

update emp
    set sal = sal*1.2
  where empno in (select empno from emp_bonus);

也可以使用exists关键字:

update emp
    set sal = sal*1.2
  where exists (select null 
                    from emp_bonus
                 where emp.empno = emp_bonus.empno);

使用另一个表的数据更新记录

MySQL & Oracle

update emp set (e.sal, e.comm) = (select ns.sal, ns.sal/2
                                    from new_sal ns
                                  where ns.deptno = e.deptno)
    where exists (select null
                    from new_sal ns
                  where ns.deptno = e.deptno);

Oracle 更新内嵌视图

update (
    select e.sal as emp_sal, e.comm as emp_comm,
        ns.sal as ns_sal, ns.sal/2 as ns_comm
      from emp e, new_sal ns
    where e.deptno = ns.deptno
) set emp_sal = ns_sal, emp_comm = ns_comm;

合并记录

如果想根据相关记录是否已经存在来插入、更新或删除一个表的记录,例如,如果记录存在,则更新它,如果不存在,则插入一条新纪录;如果更新之后的记录不满足某个条件,则删除它。
考虑如下条件来修改emp_commission表:
1) 如果emp_commission表的员工数据在emp表里也存在相关记录,则更新业务提成comm为1000;
2)对于所有可能会把comm列更新为1000的员工,如果他们的sal低于2000,则删除相关记录(他们不应该存在于emp_commission表中;
3)否则,就要从emp表中取出相应的empnoenamedeptno并插入到emp_commission表。

Oracle

merge into emp_commission ec
using (select * from emp) emp
   on (ec.empno = emp.empno)
 when matched then
      update set ec.comm = 1000
      delete where (sal < 2000)
 when not matched then
      insert (ec.empno, ec.ename, ec.deptno, ec.comm)
      values (emp.empno, emp.ename, emp.deptno, emp.comm);

删除违反参照完整性的记录

想从表里删除一些记录,因为在另一个表里不存在与这些记录相匹配的数据。例如,一些员工所属的部门其实并不存在,你希望删除这些员工。

delete from emp
    where not exists (
        select * from dept
          where dept.deptno = emp.deptno;
    );

或者

delete from emp 
    where deptno not in (select deptno from dept);

删除重复记录

考虑如下表dupes数据:

clipboard.png

对于每一组重复的名字,你希望保留任意一个ID,并删除其余的。

delete from dupes
where id not in (
    select min(id) from dupes
        group by name);

clipboard.png

《SQL经典实例》第四章

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107214.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • POJ 2996 Help Me with the Game (模拟)

    POJ 2996 Help Me with the Game (模拟)题目链接:http://poj.org/problem?id=2996POJ训练计划中的模拟都是非常棒的模拟,也非常有代表性。这个题讲的是给你一个国际象棋棋盘,敲代码打印出黑白两方的棋子。以及棋子的坐标。可是须要注意的国际棋盘的坐标问题例如以下图这个国际棋盘能够看到数字轴和字母轴的方向以及增减关系。所以在这个题的统计的时候须要进行坐标转换。由于已经做过类似的方法…

  • latex大括号各行内容左对齐_word公式大括号左对齐

    latex大括号各行内容左对齐_word公式大括号左对齐终于找到个好用的了{aaaaaaaaaaaaaaaaabc\left\{\begin{array}{l}a\\aaaaaaaaaaaaaaa\\abc\end{array}\right.⎩⎨⎧​aaaaaaaaaaaaaaaaabc​$$\left\{\begin{array}{l}a\\aaaaaaaaaaaaaaa\\abc\end{array}\right.$$…

    2022年10月11日
  • eclipse中怎么自动补全_空格键坏了

    eclipse中怎么自动补全_空格键坏了eclipse自动补全及其空格键优化(去除空格自动补全)使用eclipse在创建其他工作区间的时候,想要配置代码自动补全,因为老是忘记,每次都要从网上查找,于是就自己总结一下。选1是代码自动补全,只需将“.”换为“.qwertyuiopasdfghjklzxcvbnm”就行了,看起来很乱,其实还是有规律可循的。(只需将键盘上的26字母按从左到右,从上到下的顺序按一遍就行了。)选2是空格不会自动补全,因为按空格会自动补全,所以有时候特别烦,而网上的大多数解决方法是需要改代码的,就会显得特别麻烦。于是

  • JS前端去掉emoji表情和Java后台处理emoji表情方法

    莫非定律 : 任何事情都没表面看去来那么简单!emoji表情在项目中使用,因为其特殊的编码格式,经常导致在网络传输、编解码、以及数据入库中带来一些问题!下面简单介绍使用Js和java处理移除emoji表情!Emoji 表情的相关基础内容介绍,请读者自行在网上查找资料!前端JS代码//emojob编码集,因为emoji表情在不断地增加,下面的reg可能在未来会不能满足…

  • 国家的崛起,无法建立局域网连接[通俗易懂]

    国家的崛起,无法建立局域网连接[通俗易懂]w8,w10需要启动directplay,具体步骤:控制面板,选择程序和功能,启用或关闭windows功能,旧版组件。然后勾选上directx组件就行了。

  • 什么是java 前端_为什么很多人选择前端而不选择 Java?

    什么是java 前端_为什么很多人选择前端而不选择 Java?互联网常见的九种职业,和游戏中的角色一样,不同的职业都有不同的特点。前端和后端,不同的人感受完全不一样。从性别上来说,妹子更适合前端,汉子可能会更偏爱后端,但影响不是特别大,其中一个原因就在于是,后端做的事情,看不见,摸不着,需要有比较强的抽象思维能力。那什么是抽像思维能力呢?如果你会下象棋的话,我马二进四,你炮八进三,我马四退五,你象三进五,能不能在脑袋里想象出来是什么样子?如果不会下象期的话,…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号