我使用以下查询插入新行:
insert into table1 (c1, c2, c3) (select c1, c2, c3 from table2 where some_condition)
如果table2中有一行满足some_condition
,则可以正常工作。但如果没有行,则不会插入任何内容。
如果select返回空结果集,有没有办法指定要插入的默认值?我想在一个SQL查询中执行此操作。
答案 0 :(得分:1)
这不是很漂亮,但它可以做你想要的,你需要测试你的环境,看它是否表现得足够好
SQL> drop table so_tgt;
Table dropped.
SQL>
SQL> create table so_src (
2 c1 varchar2(6)
3 ,c2 varchar2(6)
4 ,c3 varchar2(6)
5 );
Table created.
SQL>
SQL> insert into so_src values ( 'foo','bar','moo' );
1 row created.
SQL>
SQL> create table so_tgt as select * from so_src where 1 = 0;
Table created.
SQL>
SQL> /* Test for existing row insert */
SQL> insert into so_tgt
2 with x as ( select s.*, 1 as r
3 from so_src s
4 where c1='foo'
5 union
6 select 'x','y','z',0 as r /* DEFAULT VALUES */
7 from dual )
8 select c1,c2,c3
9 from x
10 where r = ( select max(r) from x ) ;
1 row created.
SQL>
SQL> select * from so_tgt;
C1 C2 C3
------ ------ ------
foo bar moo
SQL> truncate table so_tgt;
Table truncated.
SQL>
SQL> /* Test for default row insert */
SQL> insert into so_tgt
2 with x as ( select s.*, 1 as r
3 from so_src s
4 where c1='far'
5 union
6 select 'x','y','z',0 as r /* DEFAULT VALUES */
7 from dual )
8 select c1,c2,c3
9 from x
10 where r = ( select max(r) from x ) ;
1 row created.
SQL>
SQL> select * from so_tgt;
C1 C2 C3
------ ------ ------
x y z
SQL> truncate table so_tgt ;
Table truncated.
答案 1 :(得分:1)
快速而肮脏的方式,如果您不介意重复some_condition
并且some_condition
不依赖于表2中的值,那么:
insert into table1 (c1,c2,c3)
select c1, c2, c3 from table2 where some_condition
union select defaultvalue1, defaultvalue2, defaultvalue3 from dual where not (some_condition)
如果some_condition
依赖于table2中的值,那么您可以(未经测试):
insert into table1 (c1,c2,c3)
select nvl(t2.c1, defaultvalue1), nvl(t2.c2, defaultvalue2), nvl(t2.c2, defaultvalue3)
from dual left join (select c1,c2,c3 from table2 where some_condition) t2
on 1 = 1
如果我是对的,这个查询将始终返回至少一行,但如果右侧没有显示任何行,那么t2值将全部返回为null,因此nvl
可以是用于提供您的默认值。
修改:小警告。这假设从table2返回的值不为null,如果是,则需要默认值。