insert语句总结

16.1 第一类,insert语句:单行插入

1)SQL> create table a (id int,name char(10) default 'aaa');   //name列指定了default值

2)SQL> insert into a values(1,'abc');        //表a后没有所选列,values必须指定所有字段的值。

3)SQL> insert into a values(2,default);        //同上,name字段用default占位。

4)SQL> insert into a values(3,null);        //表a后没有所选列,name字段用null占位。

5)SQL> insert into a (id) values(4);        //表a后有选择字段,未选定的字段如果指定了default,则以default的值代替null

6)SQL> insert into (select id from a) values (5); //这种形式本质同上,只不过表a的形式以结果集代之。

7)SQL> insert into a values(6,(select dname from dept where deptno=10));  //values里的某列使用了subquery引用另一个表的数据。

注意:

1)insert语句会有约束的问题,不符合约束条件的insert不能成功。
2)default不但可以用于insert语句, 也可以用于update语句(考点)
3)values后面不可以跟多列子查询。

SQL> insert into a values(select deptno,dname from dept where deptno=10);
insert into a values(select deptno,dname from dept where deptno=10)
                     *
第 1 行出现错误:
ORA-00936: 缺失表达式

更正一下:
SQL> insert into a values((select deptno from dept where deptno=10), (select dname from dept where deptno=10));

已创建 1 行。

SQL> select * from a;

ID NAME
---------- ----------
         1 abc
         2 aaa
         3
         4 aaa
         5 aaa
         6 ACCOUNTING

SQL> commit;

7)insert WITH CHECK OPTION的用法

SQL> insert into (select id from a where id<100  WITH CHECK OPTION) values (20);

SQL> select * from a;

ID NAME
---------- ----------
         1 abc
         2 aaa
         3
         4 aaa
         5 aaa
         6 ACCOUNTING
         20 aaa

SQL> rollback;

SQL> insert into (select id from a where id<100  WITH CHECK OPTION) values (101);
insert into (select id from a where id<100  WITH CHECK OPTION) values (101)
                            *
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation

看看这句话的另一种情况:

SQL> insert into (select name from a where id<100  WITH CHECK OPTION) values ('NBA');
insert into (select name from a where id<100  WITH CHECK OPTION) values ('NBA')
                              *
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation

上例是想说明如果插入的列不在where条件里,则不允许插入。(考点)。

SQL> insert into (select id,name from a where id<100  WITH CHECK OPTION) values (10,'tim');

SQL> insert into (select name from a where id<100) values ('NBA'); //不加WITH CHECK OPTION则在插入时不会检查。

关于WITH CHECK OPTION 关键字考点较多,这里是OCP教材中的一个例子,看看它在DML语句中的实际意义:

conn hr/hr

SELECT l.location_id,l.city,l.country_id FROM locations l JOIN countries c ON (l.country_id=c.country_id) JOIN regions USING(region_id) WHERE region_name='Europe';

LOCATION_ID CITY                           CO
----------- ------------------------------ --
       1000 Roma                           IT
       1100 Venice                         IT
       2400 London                         UK
       2500 Oxford                         UK
       2600 Stretford                      UK
       2700 Munich                         DE
       2900 Geneva                         CH
       3000 Bern                             CH
       3100 Utrecht                        NL

INSERT INTO (SELECT location_id,city,country_id FROM locations WHERE  country_id IN
             (SELECT country_id FROM countries NATURAL JOIN regions
              WHERE region_name='Europe')
              WITH CHECK OPTION)
VALUES (3500,'Berlin','DE');

已创建 1 行。

INSERT INTO (SELECT location_id,city,country_id FROM locations WHERE  country_id IN
             (SELECT country_id FROM countries NATURAL JOIN regions
              WHERE region_name='Europe')
              WITH CHECK OPTION)
VALUES (3500,'NEW YORK','US');

INSERT INTO (SELECT location_id,city,country_id FROM locations WHERE  country_id IN
*
第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (HR.LOC_ID_PK)

其实这个WITH CHECK OPTION和我们之前讲的视图中的WITH CHECK OPTION是一个意思,比较一下:

CREATE OR REPLACE VIEW euro_city AS
      SELECT location_id,city,country_id FROM locations WHERE  country_id IN
           (SELECT country_id FROM countries NATURAL JOIN regions
            WHERE region_name='Europe')
            WITH CHECK OPTION;

INSERT INTO euro_city VALUES (3600,'NEW YORK','US')
        
ORA-01402: 视图 WITH CHECK OPTION where 子句违规

总结:

这样的语法看起来很特殊,其实select子句是不会真正执行的,它只是规定了insert语句对某些字段的约束形式而已。即如果不满足subquery里的where条件的话,就不允许插入。关于DML语句中嵌入subquery的用法,要注意有些指定是强制的。

比如这一句

SQL> update (select empno,job,sal from emp) set sal=8000 where job=(select job from emp where empno=7788);

update后接subquery,用于限制修改列。这里sal列和job列必须包含在subquery内,否则set sal=8000 和 where job=()就无法识别了。

下面的例子也类似,where 中限定sal和deptno, 那么在subquery中也必须声明一下。

SQL> delete (select empno,sal,deptno from emp) where sal>3000 and deptno=10;

16.2 第二类,insert 一次插入多行 语法上去掉了values选项。

SQL> create table b as select * from a where 1>2;    //建立一个空表b。结构来自a表, where 1>2 使没有符合的记录被筛选出来.

SQL> insert into b select * from a where name='aaa'; //插入的是结果集,注意没有values选项。

SQL> select * from b;

ID NAME
---------- ----------
         2 aaa
         4 aaa
         5 aaa

SQL> insert into b(id) select id from a where id in(1,3);   //使用子查询(结果集)插入,对位, 注意b表没有default。

SQL> select * from b;

ID NAME
---------- ----------
         2 aaa
         4 aaa
         5 aaa
         1
         3

16.3 第三类,Multitable insert 一条INSERT语句可以完成向多张表的插入任务。

insert all与insert first

1.创建表T并初始化测试数据,此表作为数据源。

create table t (x number(10), y varchar2(10));
insert into t values (1,'a');
insert into t values (2,'b');
insert into t values (3,'c');
insert into t values (4,'d');
insert into t values (5,'e');
insert into t values (6,'f');
commit;

2.查看表T的数据

SQL>select * from t;

X         Y
---------- ----------
1         a
2         b
3         c
4         d
5         e
6         f

6 rows selected.

3.创建表T1和T2,作为我们要插入的目标表。
SQL>create table t1 as select * from t where 0=1;
Table created.
SQL>create table t2 as select * from t where 0=1;
Table created.

16.3.1 第一种多表插入方法INSERT ALL (不分先后,各插各的)

unconditional insert all(无条件insert all)

1)完成INSERT ALL插入
SQL>insert all into t1 into t2 select * from t;   
12 rows created.

这里之所以显示插入了12条数据,实际上表示在T1表中插入了6条,T2表插入了6条,一共是12条数据。

2)验证T1表中被插入的数据。
SQL>select * from t1;

3)验证T2表中被插入的数据。
SQL>select * from t2;

OK,完成INSERT ALL命令的使命。

conditional insert all(有条件insert all)

SQL> insert all when x>=3 then into t1 when x>=2 then into t2 select * from t;

已创建9行。

16.3.2 第二种多表插入方法INSERT FIRST

conditional insert first(有条件insert first)

1)清空表T1和T2
SQL> truncate table t1;
SQL> truncate table t2;

2)完成INSERT FIRST插入

SQL> insert first when x>=3 then into t1 when x>=2 then into t2 select * from t;

处理逻辑是这样的,首先检索T表查找X列值大于等于3的数据插入到T1表,然后将前一个查询中出现的数据排除后再查找T表,找到X列值大于等于2的数据再插入到T2表,注意INSERT FIRST的真正目的是将同样的数据只插入一次。

3)验证T1表中被插入的数据。
SQL> select * from t1;

X Y
---------- ----------
         3 c
         4 d
         5 e
         6 f

4)验证T2表中被插入的数据。

SQL> select * from t2;

X Y
---------- ----------
         2 b

16.3.3 第三种,旋转Insert (pivoting insert)

Pivoting INSERT 有行变列的功能

create table sales_source_data (
employee_id number(6),
week_id number(2),
sales_mon number(8,2),
sales_tue number(8,2),
sales_wed number(8,2),
sales_thur number(8,2),
sales_fri number(8,2)
);

insert into sales_source_data values (176,6,2000,3000,4000,5000,6000);
 
create table sales_info (
employee_id number(6),
week number(2),
sales number(8,2)
);
 
看上面的表结构,现在将要sales_source_data表中的数据转换到sales_info表中,这种情况就需要使用旋转Insert
 
示例如下:
insert all
into sales_info values(employee_id,week_id,sales_mon)
into sales_info values(employee_id,week_id,sales_tue)
into sales_info values(employee_id,week_id,sales_wed)
into sales_info values(employee_id,week_id,sales_thur)
into sales_info values(employee_id,week_id,sales_fri)
select employee_id,week_id,sales_mon,sales_tue,
sales_wed,sales_thur,sales_fri
from sales_source_data;

SQL> select * from sales_info;

EMPLOYEE_ID       WEEK      SALES
----------- ---------- ----------
        176              6       2000
        176              6       3000
        176              6       4000
        176             6       5000
        176              6       6000

从该例子可以看出,所谓旋转Insert是无条件 insert all 的一种特殊应用, 将一个表中的行转换成另一个表中的列,这种应用被oracle官方,赋予了一个pivoting insert的名称,即旋转insert.

oracle之insert语句总结的更多相关文章

  1. Python批量执行oracle中的insert语句

    从oracle导出一个表的数据,导出的格式是insert语句,数据量30万. 直接在PL/SQL Developer中执行,速度非常慢,脚本中也是100条数据提交一次.因为需要的时间太长,每次中断后, ...

  2. 如何通过sql的insert语句插入大量字符串到oracle的clob字段?

    当通过insert语句直接插入大量字符串(主要是html的内容),超过4000字符时候,就会报: ORA-01489: 字符串连接的结果过长 虽然字段是clob,足以存储,但是通过这种直接插入的时候, ...

  3. oracle带条件的Insert语句

    背景 在一条记录完结时,自动向表中加入一条新的记录,采用的是事务处理,修改现有记录,并新增一条记录,直接采用的insert语句会报错 //主键冲突 unique constraint (XXXXXX) ...

  4. SQLServer将表数据导出为Insert语句

    从网上找到的方法,不过很不错,记录下来,也算是分享下~~ 有一个表,city,有列:cityID,cityName;将此表中所有数据,变为insert语句 select 'insert into ta ...

  5. Oracle的update语句优化研究

    最近研究sql优化,以下文章转自互联网: 1.     语法 单表:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 如:update t_join_situation s ...

  6. Oracle动态执行语句

      一.为什么要使用动态执行语句? 由于在PL/SQL 块或者存储过程中只支持DML语句及控制流语句,并不支持DDL语句,所以Oracle动态执行语句便应允而生了.关于DDL与DML的区别,请参见:D ...

  7. 取得表中数据的insert语句

    Build Insert Statements for the Existing Data in Tables 下面这个脚本实现了取得一个非空表中的所有insert语句 This script bui ...

  8. 【转】Oracle 执行动态语句

    1.静态SQLSQL与动态SQL Oracle编译PL/SQL程序块分为两个种:其一为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型:另外一 ...

  9. oracle常用SQL语句(汇总版)

    Oracle数据库常用sql语句 ORACLE 常用的SQL语法和数据对象一.数据控制语句 (DML) 部分 1.INSERT (往数据表里插入记录的语句) INSERT INTO 表名(字段名1, ...

随机推荐

  1. Spring——IOC(控制反转)与DI(依赖注入)

    IOC与DI的理解及使用 控制反转IOC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IOC的一种方法.在没有IOC的程序中,我们使用面向对象编程,对象的创建于对象 ...

  2. 看DLI服务4核心如何提升云服务自动化运维

    摘要:今天我们来说说DLI是如何实现监控告警来提升整体运维能力,从而为客户更好的提供Serverless的DLI. DLI是支持多模引擎的Serverless大数据计算服务,免运维也是其作为Serve ...

  3. 调试备忘录-J-Link RTT的使用(原理 + 教程 + 应用 + 代码)

    MCU:STM32F407VE MDK:5.29 IAR:8.32 目录--点击可快速直达 目录 写在前面 什么是RTT? RTT的工作原理 RTT的性能 快速使用教程 高级使用教程 附上测试代码 2 ...

  4. 关于C#调用非托管DLL,报“内存已损坏的”坑,坑,坑

    因客户需求,与第三方对接,调用非托管DLL,之前正常对接的程序,却总是报“内存已损坏的异常”,程序进程直接死掉,折腾到这个点(2018-05-11 00:26),终于尘埃落定,直接上程序. 之前的程序 ...

  5. Shell脚本之for循环语句的应用

    在实际工作中,经常会遇到某项任务需要多次执行的情况,而每次执行时仅仅是处理的对象不一样,其他命令相同.这时候可以使用for循环语句,针对不同的取值重复执行相同的命令序列. for循环语句的语法结构: ...

  6. Jmeter系列(50)- 详解 If 控制器

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 可以通过条件来控制是否运行其 ...

  7. Python日期时间(详细)

    获取当前时间戳 import time t = time.time() millis1 = int(t) print('10位时间戳:{}'.format(millis1)) millis2 = in ...

  8. gpio模拟mdc/mdio通信

    本文主要是学习gpio模拟mdc/mdio通信. 运行环境是在ATMEL的sama5d35MCU,两个GPIO引脚模拟MDC/MDIO通信,读取百兆phy的寄存器的值. #include<lin ...

  9. 【原创】Linux虚拟化KVM-Qemu分析(二)之ARMv8虚拟化

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...

  10. WPF新手快速入门系列 2.绑定

    [概要] 上一章讲了布局,按照市面上的书籍每一本讲的顺序都不一样,本系列是希望大家能快速上手去应对工作需要,所以本章就直接开始讲绑定. 如有学习过程中想交流学习.疑惑解答可以来此QQ群交流:58074 ...