【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的一系列常用操作。

相关文章
|
2月前
|
SQL 存储 缓存
SQL Server 数据太多如何优化
11种优化方案供你参考,优化 SQL Server 数据库性能得从多个方面着手,包括硬件配置、数据库结构、查询优化、索引管理、分区分表、并行处理等。通过合理的索引、查询优化、数据分区等技术,可以在数据量增大时保持较好的性能。同时,定期进行数据库维护和清理,保证数据库高效运行。
|
3月前
|
SQL 移动开发 Oracle
SQL语句实现查询连续六天数据的方法与技巧
在数据库查询中,有时需要筛选出符合特定时间连续性条件的数据记录
|
3月前
|
SQL 存储 关系型数据库
添加数据到数据库的SQL语句详解与实践技巧
在数据库管理中,添加数据是一个基本操作,它涉及到向表中插入新的记录
|
3月前
|
SQL 数据挖掘 数据库
SQL查询每秒的数据:技巧、方法与性能优化
id="">SQL查询功能详解 SQL(Structured Query Language,结构化查询语言)是一种专门用于与数据库进行沟通和操作的语言
|
3月前
|
SQL 监控 数据处理
SQL数据库数据修改操作详解
数据库是现代信息系统的重要组成部分,其中SQL(StructuredQueryLanguage)是管理和处理数据库的重要工具之一。在日常的业务运营过程中,数据的准确性和及时性对企业来说至关重要,这就需要掌握如何在数据库中正确地进行数据修改操作。本文将详细介绍在SQL数据库中如何修改数据,帮助读者更好
630 4
|
4月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
6月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
147 13
|
6月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
6月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
82 6
|
6月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
505 1