[20150115]insert多个表.txt

[20150115]insert多个表.txt

--别人给我提出一个问题,要把表拆开2个表,能否快速完成这个工作。还是通过例子来说明:

SCOTT@test> @ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.3.0     Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

create table t1 (id number,name varchar2(20),c1 varchar2(20),c2 varchar2(20),c3 varchar2(20),c4 varchar2(20));

insert into t1 values (1,'a','a1','a2','a3','a4');
insert into t1 values (2,'b','b1','b2',NULL,NULL);
insert into t1 values (3,'c','c1','c2','c3',NULL);

--要把表变成两个:
--表t1x:
1,'a'
2,'b'
3,'c'

--表t2x
1,1,'a1','a2'
1,2,'a3','a4'
2,1,'b1','b2'
3,1,'c1','c2'

--有错误的记录在另外的表中:
--t2err
3,2,'c3',NULL

--实际上真正生产系统要折返的字段更多,这个明显违反关系数据结构的设计,国内的开发团队那个时候能提高,在数据结构上出现错误
--,要修改代码的工程量很大的。

--自己开始考虑多个select在插入,明显效率不高。有考虑11g的pivot,可以参考链接:
--http://www.oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1.php

--昨天看了sql 的参考手册,才想起来使用insert多个表的操作最简单。操作如下:

1.建立表:

create table t1x   (id number,name varchar2(20));
create table t2x   (id number,seq number,c1 varchar2(20),c2 varchar2(20));
create table t2err (id number,seq number,c1 varchar2(20),c2 varchar2(20));

2.执行如下:

insert all
   when 1 =1 then
       into t1x values (id,name)
   when c1 is not null and c2 is not null then
       into t2x values (id,1,c1,c2)
   when c3 is not null and c4 is not null then
       into t2x values (id,2,c3,c4)
   when ( c1 is null and c2 is not null ) or ( c1 is not null and c2 is null ) then
       into t2err values (id,1,c1,c2)
   when ( c3 is null and c4 is not null ) or ( c3 is not null and c4 is null ) then
       into t2err values (id,2,c3,c4)
   select * from t1;

SCOTT@test> @dpc ''  ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  0yy08jpx5vcqk, child number 0
-------------------------------------
insert all    when 1 =1 then        into t1x values (id,name)    when
c1 is not null and c2 is not null then        into t2x values
(id,1,c1,c2)    when c3 is not null and c4 is not null then        into
t2x values (id,2,c3,c4)    when ( c1 is null and c2 is not null ) or (
c1 is not null and c2 is null ) then        into t2err values
(id,1,c1,c2)    when ( c3 is null and c4 is not null ) or ( c3 is not
null and c4 is null ) then        into t2err values (id,2,c3,c4)
select * from t1

Plan hash value: 1248537433

----------------------------------------------------------------------------------------------------
| Id  | Operation           | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT    |       |      1 |        |     3 (100)|      0 |00:00:00.01 |      24 |
|   1 |  MULTI-TABLE INSERT |       |      1 |        |            |      0 |00:00:00.01 |      24 |
|   2 |   TABLE ACCESS FULL | T1    |      1 |      3 |     3   (0)|      3 |00:00:00.01 |       7 |
|   3 |   INTO              | T1X   |      0 |        |            |      0 |00:00:00.01 |       0 |
|   4 |   INTO              | T2X   |      0 |        |            |      0 |00:00:00.01 |       0 |
|   5 |   INTO              | T2X   |      0 |        |            |      0 |00:00:00.01 |       0 |
|   6 |   INTO              | T2ERR |      0 |        |            |      0 |00:00:00.01 |       0 |
|   7 |   INTO              | T2ERR |      0 |        |            |      0 |00:00:00.01 |       0 |
----------------------------------------------------------------------------------------------------

SCOTT@test> select * from t1x;
        ID NAME
---------- --------------------
         1 a
         2 b
         3 c

SCOTT@test> select * from t2x;
        ID        SEQ C1                   C2
---------- ---------- -------------------- --------------------
         1          1 a1                   a2
         2          1 b1                   b2
         3          1 c1                   c2
         1          2 a3                   a4

SCOTT@test> select * from t2err;
        ID        SEQ C1                   C2
---------- ---------- -------------------- --------------------
         3          2 c3

--注意这里使用了all,要求记录走遍全部条件分支,满足就插入。使用first表示满足1个条件就插入,剩下的不再判断。
--btw :以前也写过一篇http://blog.itpub.net/267265/viewspace-713115/,这种技巧不常用,有点忘记了。
--实际上还可以选择有条件的插入,特此做一个记录。

时间: 2024-07-30 10:55:41

[20150115]insert多个表.txt的相关文章

[20151231]主外键与空表.txt

[20151231]主外键与空表.txt --主外键的测试例子很多,今天做一个特别的,外部键表为空,也会出现阻塞吗?测试看看. 1.建立环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- -------------------------------------------------------

[20161023]为什么以前可以这样的表.txt

[20161023]为什么以前可以这样的表.txt --上午看https://oracleblog.org/working-case/ora-01401-impdp-same-character/ CREATE TABLE ASS_ACCHSHT_GREEN_MEMORY (    "GREEN_ID" VARCHAR2(16) NOT NULL ENABLE,      "ACCOUNT_ID" VARCHAR2(16) NOT NULL ENABLE,     

[20150918]禁止用户truncate以及drop表.txt

[20150918]禁止用户truncate以及drop表.txt --一个需求要求禁止用户truncate以及drop表,实际上很简单仅仅建立一个触发器就ok了. CREATE OR REPLACE TRIGGER SYS.tri_prevent_drop_truncate    BEFORE TRUNCATE OR DROP ON DATABASE BEGIN    IF ora_dict_obj_type = 'TABLE' AND ora_dict_obj_owner = 'SCOTT'

[20170315]11.2.0.4 exp可以导出空表.txt

[20170315]11.2.0.4 exp可以导出空表.txt --链接http://www.itpub.net/thread-2084282-1-1.html,11.2.0.4可以使用exp导出空表,没有问题,测试看看.   SCOTT@book> @ &r/ver BANNER -------------------------------------------------------------------------------- Oracle Database 11g Ente

[20161002]impdp导入空表.txt

[20161002]impdp导入空表.txt --业务需求要求建立新的测试库,由于磁盘空间有限,要求几个大表导入空表,11g支持段延迟提交,即使表init很大也不会出现空间问题. --全表的数据已经通过expdp导出.自己测试一下如何实现: 1.环境: SCOTT@test01p> @ ver1 PORT_STRING          VERSION    BANNER                                                              

[20130121]应用程序访问那些表.txt

[20130121]应用程序访问那些表.txt 前一阵子要优化一个项目,表结构使用的汉语拼音的首字母作为表名,又没有注解说明,要了解应用的细节,解决应用的问题太麻烦了.我想先确定程序主要使用那些表,想到了以前遇到的v$access视图. http://space.itpub.net/267265/viewspace-717912 通过它应该可以确定应用经常使用的那些表以及视图,主要了解靠前的表就可以解决问题. WITH a AS      (SELECT  /*+ materialize */ 

asp+access sql insert into select表复制

这里是把一个同的数据一次性保存到另一个表,用的是sql insert into  select另一张同结构的新表 sub append() call opendb() dim zsql,zdysql zsql="insert into zdgz select title,s_name,user_from,image,content,send_date,isture from zdy "  conn.execute(zsql)  if err=0 then   response.writ

mysql中insert...select复制表数据

语法 INSERT INTO db1_name (field1,field2) SELECT field1,field2 FROM db2_name 实例 可以运行insert...select语法解决问题: insert into hotel_ktv (title,price, number,date,area,content,num) select title,price,number,date,area,content,num from hotel_ktv; 查看结果  代码如下 复制代码

[20141203]分析语句导致阻塞分析表.txt

[20141203]分析语句导致阻塞分析表,分析表导致阻塞sql语句执行分析.txt --我们知道如果语句连接的表很多,会消耗大量的CPU资源. http://blog.itpub.net/267265/viewspace-1298186/ --分析sql语句还会导致什么问题呢?昨天看了一篇bloghttp://www.bobbydurrettdba.com/2014/11/24/parsing-blocks-stats-blocks-parsing/, --重复测试看看. SCOTT@test