[英]Conditionally insert into another table if id exists in another table else insert into both both tables in oracle
如果表A 中存在客户 ID,则在表 B中插入订单。 如果A 表中没有客户 ID,则在 A表中插入客户 ID,然后在B表中订购。 我一直在尝试通过if/else 和 merge来实现这一点,但一直遇到无效的 sql 语句。
IF EXISTS (SELECT CustomerID FROM Customer_T WHERE CustomerID = 18)
Insert into Order_T
values(79,18,to_date('09/28/2021','mm/dd/yyyy'),to_date('10/01/2021','mm/dd/yyyy'),1,3)
ELSE
insert INTO Customer_T VALUES (18,'Capitol Industries Ltd', '999 Fifth Avenue', 'New York', 'NY','10015')
insert into Order_T values (79,18,to_date('09/28/2021','mm/dd/yyyy'),to_date('10/01/2021','mm/dd/yyyy'),1,3)
END IF;
这种情况不需要IF THEN ELSE
逻辑。 而是使用数据库内置功能。 customerid 应该是您的主键,因此如果您尝试插入并且它已经存在,则会引发DUP_VAL_ON_INDEX
异常。
检查以下示例:
-- create tables
create table customers (
id number generated by default on null as identity
constraint customers_id_pk primary key,
name varchar2(255 char)
)
;
create table orders (
id number generated by default on null as identity
constraint orders_id_pk primary key,
customer_id number
constraint orders_customer_id_fk
references customers on delete cascade,
product varchar2(100 char)
)
;
BEGIN
BEGIN
insert INTO customers VALUES (2,'Capitol Industries Ltd');
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
NULL;
END;
insert into orders (customer_id,product) values (2,'a book');
END;
/
运行上面的块几次。 只有第一次它会插入一个客户。
假设您有 2 个非常简单的表。
表
create table T1( num_ )
as
select 1 from dual ;
create table T2( num_ )
as
select 200 from dual ;
包含 IF.. ELSE.. END IF 和 EXISTS() 的匿名块类似于您问题中的代码,会导致错误:
function 或伪列“EXISTS”只能在 SQL 语句中使用
begin
if exists( select num_ from T1 where num_ = 2 ) then
insert into T2( num_ ) values( 2 ) ;
dbms_output.put_line( 'if' ) ;
else
insert into T1( num_ ) values( 2 ) ;
insert into T2( num_ ) values( 2 ) ;
dbms_output.put_line( 'else' ) ;
end if ;
end ;
/
-- error:
... function or pseudo-column 'EXISTS' may be used inside a SQL statement only
一种解决方案可能是执行以下操作(请参阅 asktom.oracle.com - 相当于 IF 语句中的 EXISTS() )
begin
for x in ( select count(*) cnt
from dual
where exists ( select num_ from T1 where num_ = 2 )
) loop
if ( x.cnt = 1 ) then -- found
insert into T2( num_ ) values( 2 ) ;
dbms_output.put_line( 'if' ) ;
else -- not found
insert into T1( num_ ) values( 2 ) ;
insert into T2( num_ ) values( 2 ) ;
dbms_output.put_line( 'else' ) ;
end if;
end loop;
end;
/
-- output:
1 rows affected
dbms_output:
else
第一次执行匿名块后,表中包含以下行:
select num_, '<- T1' as table_ from T1
union all
select num_, '<- T2' from T2 ;
-- result
NUM_ TABLE_
1 <- T1
2 <- T1
200 <- T2
2 <- T2
再次执行匿名块,你会得到...
1 rows affected
dbms_output:
if
-- tables
NUM_ TABLE_
1 <- T1
2 <- T1
200 <- T2
2 <- T2
2 <- T2
DBfiddle 在这里。
您可以使用多表插入并使用这样一个事实,即没有group by
聚合 function 在不存在(= 不满足where
条件)行的情况下总是返回带有null
的行。
代码如下:
insert into customers(id, name, company, state) values (1, 'Some name', 'Some company', 'NY')
1 行受影响
insert all when cust_exists = 0 then into customers (id, name, company, state) values (cust_id, cust_name, company, state) when 1 = 1 then into orders (id, customer_id, order_date, due_date, some_id) values(order_id, cust_id, order_date, due_date, some_id) select 1 as order_id, 1 as cust_id, 'Some other name' as cust_name, 'Company' as company, 'NY' as state, date '2021-09-28' as order_date, date '2021-10-03' as due_date, 100 as some_id, nvl(max(1), 0) as cust_exists from customers where id = 1
1 行受影响
insert all when cust_exists = 0 then into customers (id, name, company, state) values (cust_id, cust_name, company, state) when 1 = 1 then into orders (id, customer_id, order_date, due_date, some_id) values(order_id, cust_id, order_date, due_date, some_id) select 2 as order_id, 2 as cust_id, 'Some other name' as cust_name, 'Company' as company, 'NY' as state, date '2021-09-28' as order_date, date '2021-10-03' as due_date, 100 as some_id, nvl(max(1), 0) as cust_exists from customers where id = 2
2 行受影响
您还可以使用两个带有记录ignore_row_on_dupkey_index
提示的插入,这正如其名称所暗示的那样。
insert /*+ ignore_row_on_dupkey_index(customers(id)) */ into customers (id, name, company, state) values (2, 'Name', 'Comp', 'NY')
✓
insert into orders (id, customer_id, order_date, due_date, some_id) values (3, 2, date '2021-09-30', date '2021-10-07', 5)
1 行受影响
select * from customers
ID 姓名 公司 STATE 1个 一些名字 某公司 纽约 2个 其他名字 公司 纽约
db<> 在这里摆弄
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.