【SQL开发实战技巧】系列(八):聊聊如何插入数据时比约束更灵活的限制数据插入以及怎么一个insert语句同时插入多张表

简介: 插入数据、阻止对某几列插入的实现、复制表的定义和数据以及注意事项、比创建约束功能更强大!用 WITH CHECK OPTION限制数据录入、如何一个insert将数据同时插入多个表【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。但是!ORA - 01723 : 不允许长度为 0 的列。

前言

本篇文章讲解的主要内容是:插入数据、阻止对某几列插入的实现、复制表的定义和数据以及注意事项、比创建约束功能更强大!用 WITH CHECK OPTION限制数据录入、如何一个insert将数据同时插入多个表
【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。


一、插入数据

先创建一个测试表,然后插入一条数据

create table test(
aa varchar2(20) default 'aa',
bb varchar2(20) default 'bb',
cc varchar2(20) default 'cc',
dd date default sysdate
);
insert into test(aa,bb,cc) values(default,null,'zyd');
 SQL> select * from test;

AA                   BB                   CC                   DD
-------------------- -------------------- -------------------- -----------
aa                                        zyd                  2023-2-7 16

注意以下几点:

  1. 如果INSERT语句中没有含默认值的列,则会添加默认值,如dd列。
  2. 如果包含有默认值的列,需要用DEFAULT关键字,才会添加默认值,如aa列。
  3. 如果已显示设定了NULL或其他值,则不会再生成默认值,如bb列。
  4. 建立表时,有时明明设定了默认值,可生成的数据还是NULL,原因在于我们在代码中不知不觉地加入了NULL。

二、阻止对某几列插入

这种需求我们可以创建一个视图,视图中暴露出来可以变更的列,然后DML操作均基于此视图来做,看下面这个案例:

SQL> insert into vtest values('a','b',sysdate);

1 row inserted


SQL> select * from vtest;

AA                   BB                   DD
-------------------- -------------------- -----------
aa                                        2023-2-7 16
a                    b                    2023-2-7 16

SQL> insert into vtest values('c',default,sysdate);
insert into vtest values('c',default,sysdate)

ORA-32575: 对于正在修改的视图, 不支持显式列默认设置

ok,看上面的操作我们可以通过视图实现需求,但是视图这种方式有个弊端就是通过VIEW新增数据,不能再使用关键字DEFAULT

三、复制表的定义和数据以及注意事项

我们可以用以下语句复制表 TEST:

create table  test2 as select * from test;

也可以先复制表的定义,再新增数据:

create table test3 as select * from test where 1=2;
insert into test3 select * from test;

但是!看下面这个操作:

SQL> create table test4 as
  2  select '1' as aa, null bb, '' cc, sysdate dd from test;
create table test4 as
select '1' as aa, null bb, '' cc, sysdate dd from test

ORA-01723: 不允许长度为 0 的列

当我们CTAS操作的时候,如果你的字段中包含null时候,会创建失败,因为你没有指定这个列的数据类型, oracle咋个推断你的数据类型呢?

四、比创建约束功能更强大!用 WITH CHECK OPTION限制数据录入

当约束条件比较简单时,可以直接加在表中,如工资必须>0:

SQL> alter table emp add constraints ck_sal check(sal > 0);
Table altered

但有些复杂或特殊的约束条件是不能这样放在表里的,如雇佣日期大于当前日期

SQL> alter table emp add constraints ck_hiredate check(hiredate>sysdate);

ORA-02436: 日期或系统变量在 CHECK 约束条件中指定错误

这时我们可以使用加了WITH CHECK OPTION关键字的VIEW来达到目的。下面的示例中,我们限制了不符合内联视图条件的数据(SYSDATE+1)

SQL> insert into (
  2  select * from test where dd<=sysdate with check option
  3  )
  4  select 'a1','b1','c1',sysdate
  5  from dual;

1 row inserted


SQL> select * from test;

AA                   BB                   CC                   DD
-------------------- -------------------- -------------------- -----------
aa                                        zyd                  2023-2-7 16
a                    b                    cc                   2023-2-7 16
a1                   b1                   c1                   2023-2-7 17


SQL> rollback;

Rollback complete


SQL> select * from test;

AA                   BB                   CC                   DD
-------------------- -------------------- -------------------- -----------
aa                                        zyd                  2023-2-7 16
a                    b                    cc                   2023-2-7 16

SQL> 
SQL> insert into (
  2  select * from test where dd<=sysdate with check option
  3  )
  4  select 'a1','b1','c1',sysdate+1
  5  from dual;
insert into (
select * from test where dd<=sysdate with check option
)
select 'a1','b1','c1',sysdate+1
from dual

ORA-01402: 视图 WITH CHECK OPTION where 子句违规

因为里面有关键字WITH CHECK OPTION,所以INSERT的数据不符合其中的条件(hiredate<=SYSDATE)时,就不允许利用INSERT。
当规则较复杂,无法用约束实现时,这种限制方式就比较有用。

五、如何一个insert将数据同时插入多个表

多表插入语句分为以下四种:

  • 无条件INSERT
  • 有条件INSERT ALL
  • 转置INSERT
  • 有条件INSERT FIRST

接下来先创建两个临时表

create table empa as select empno,ename,job from emp where 1=2;
create table empb as select empno,ename,deptno from emp where 1=2;
  • 无条件INSERT
INSERT ALL
into empa(empno,ename,job)VALUES(empno,ename,job)
into empb(empno,ename,deptno)VALUES(empno,ename,deptno)
SELECT empno,ename,job,deptno FROM emp WHERE deptno in (10,20);
16 rows inserted

SQL> select * from empa;

EMPNO ENAME      JOB
----- ---------- ---------
 7369 SMITH      CLERK
 7566 JONES      MANAGER
 7782 CLARK      MANAGER
 7788 SCOTT      ANALYST
 7839 KING       PRESIDENT
 7876 ADAMS      CLERK
 7902 FORD       ANALYST
 7934 MILLER     CLERK

8 rows selected


SQL> select * from empb;

EMPNO ENAME      DEPTNO
----- ---------- ------
 7369 SMITH          20
 7566 JONES          20
 7782 CLARK          10
 7788 SCOTT          20
 7839 KING           10
 7876 ADAMS          20
 7902 FORD           20
 7934 MILLER         10

8 rows selected


SQL> rollback;

Rollback complete

因为没有加条件,所以会同时向两个表中插入数据,且两个表中插入的条数一样。

  • 有条件 INSERT ALL
INSERT ALL
when job in('SALESMAN','MANAGER') then 
into empa(empno,ename,job)VALUES(empno,ename,job)
when deptno in('20','30')then
into empb(empno,ename,deptno)VALUES(empno,ename,deptno)
SELECT empno,ename,job,deptno FROM emp WHERE deptno in (10,20);
7 rows inserted


SQL> select * from empa;

EMPNO ENAME      JOB
----- ---------- ---------
 7566 JONES      MANAGER
 7782 CLARK      MANAGER

SQL> select * from empb;

EMPNO ENAME      DEPTNO
----- ---------- ------
 7369 SMITH          20
 7566 JONES          20
 7788 SCOTT          20
 7876 ADAMS          20
 7902 FORD           20

SQL> rollback;

Rollback complete

当增加条件后,就会按条件插入。如EMPNO=7654等数据在两个表中都有。

  • INSERT FIRST就不一样
INSERT FIRST
when job in('SALESMAN','MANAGER') then 
into empa(empno,ename,job)VALUES(empno,ename,job)
when deptno in('20','30')then
into empb(empno,ename,deptno)VALUES(empno,ename,deptno)
SELECT empno,ename,job,deptno FROM emp WHERE deptno in (10,20);

6 rows inserted


SQL> select * from empa;

EMPNO ENAME      JOB
----- ---------- ---------
 7566 JONES      MANAGER
 7782 CLARK      MANAGER

SQL> select * from empb;

EMPNO ENAME      DEPTNO
----- ---------- ------
 7369 SMITH          20
 7788 SCOTT          20
 7876 ADAMS          20
 7902 FORD           20

SQL> rollback;

INSERT FIRST语句中,当第一个表符合条件后,第二个表将不再插入对应的行,表empb中不再有与表empa相同的数据EMPN0=7654,这就是INSERT FIRSTINSERT ALL的不同之处。

  • 转置INSERT与其说是一个分类,不如算作"INSERT ALL"的一个用法。

创建一个临时表

create table deptb(
dname varchar2(200),
remark  varchar2(200)
);
insert all 
into deptb values(aa,'aa')
into deptb values(bb,'bb')
into deptb values(cc,'cc')
select * from (select 'zhaoyd' aa,'zhaoyandong' bb ,'赵延东'cc from dual 
);
SQL> select * from deptb;

DNAME                                                                            REMARK
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
zhaoyd                                                                           aa
zhaoyandong                                                                      bb
赵延东                                                                           cc

可以看到,转置INSERT的实质就是把不同列的数据插入到同一表的不同行中。


总结

本章主要是介绍关于insert的一系列常用操作。

相关文章
|
6天前
|
SQL 数据库
【SQL】已解决:SQL分组去重并合并相同数据
【SQL】已解决:SQL分组去重并合并相同数据
17 1
|
10天前
|
SQL 自然语言处理 网络协议
【Linux开发实战指南】基于TCP、进程数据结构与SQL数据库:构建在线云词典系统(含注册、登录、查询、历史记录管理功能及源码分享)
TCP(Transmission Control Protocol)连接是互联网上最常用的一种面向连接、可靠的、基于字节流的传输层通信协议。建立TCP连接需要经过著名的“三次握手”过程: 1. SYN(同步序列编号):客户端发送一个SYN包给服务器,并进入SYN_SEND状态,等待服务器确认。 2. SYN-ACK:服务器收到SYN包后,回应一个SYN-ACK(SYN+ACKnowledgment)包,告诉客户端其接收到了请求,并同意建立连接,此时服务器进入SYN_RECV状态。 3. ACK(确认字符):客户端收到服务器的SYN-ACK包后,发送一个ACK包给服务器,确认收到了服务器的确
|
15天前
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之在使用ODPSSQL节点进行SQL任务开发时,如何执行大量的SQL语句
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
26 4
|
13天前
|
SQL 存储 关系型数据库
SQL约束
SQL约束
17 1
|
6天前
|
SQL 测试技术 数据库
【SQL】已解决:SQL错误(15048): 数据兼容级别有效值为100、110或120
【SQL】已解决:SQL错误(15048): 数据兼容级别有效值为100、110或120
13 0
|
20天前
|
SQL
sql语句按指定某个字段分组后删除重复数据只保留id最小/最大的一条数据
sql语句按指定某个字段分组后删除重复数据只保留id最小/最大的一条数据
11 0
|
27天前
|
SQL IDE Java
Java连接SQL Server数据库的详细操作流程
Java连接SQL Server数据库的详细操作流程
|
1月前
|
SQL DataWorks NoSQL
DataWorks产品使用合集之如何将SQL Server中的数据转存到MongoDB
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
253 1
|
5天前
|
SQL 存储 安全
数据库数据恢复—SQL Server数据库出现逻辑错误的数据恢复案例
SQL Server数据库数据恢复环境: 某品牌服务器存储中有两组raid5磁盘阵列。操作系统层面跑着SQL Server数据库,SQL Server数据库存放在D盘分区中。 SQL Server数据库故障: 存放SQL Server数据库的D盘分区容量不足,管理员在E盘中生成了一个.ndf的文件并且将数据库路径指向E盘继续使用。数据库继续运行一段时间后出现故障并报错,连接失效,SqlServer数据库无法附加查询。管理员多次尝试恢复数据库数据但是没有成功。
|
11天前
|
SQL 存储 关系型数据库
关系型数据库SQL Server学习
【7月更文挑战第4天】
21 2