这个合并操作有什么问题?
What’s wrong in this merge operation?
我正在 Oracle 11g 中执行 MERGE 操作,但它们返回的行多于预期。
create table sales(product varchar2(20),month date, amount number(10))
insert into sales values('LG','01-Jan-17',20000);
insert into sales values('sony','01-Jan-18',22000);
insert into sales values('panasonic', '22-dec-17',18000);
create table sales_history(product varchar2(20),month date, amount number(10))
insert into sales_history values('sony', '22-dec-17',24000);
insert into sales_history values('panasonic', '22-dec-17',18000);
select * from sales;
select * from sales_history
merge into sales_history sh using(select product,month,amount from sales)s
on (s.product=sh.product)
when matched then update set sh.month=s.month,sh.amount=s.amount
when not matched then insert(sh.product,sh.month,sh.amount)
values(s.product,s.month,s.amount);
并且我尝试在 Pl/SQL 中执行相同的查询,这将给我相同的结果,但它返回更多重复的行 rows.Why 是这样吗?
set serveroutput on
declare
s_product varchar2(20);
s_month date;
s_amount number(10);
p_product s_product%type;
m_month s_month%type;
a_amount s_amount%type;
cursor sc1 is
select product,month,amount from sales;
cursor shc2 is
select product,month,amount from sales_history;
begin
open sc1;
open shc2;
loop <<l1>>
fetch sc1 into s_product,s_month,s_amount;
fetch shc2 into p_product,m_month,a_amount;
if s_product = p_product then
if s_month <> m_month then
update sales_history set month = s_month where product = s_product;
end if;
if s_amount <> a_amount then
update sales_history set amount = s_amount where product = s_product;
end if;
else
INSERT INTO sales_history(product, month, amount)
SELECT product, month, amount FROM sales;
dbms_output.put_line('DATA IS UPDATED');
end if;
exit when sc1%notfound;
exit when shc2%notfound;
end loop l1;
close sc1;
close shc2;
end;
select * from sales_history
我已经尝试执行 Oracle 12c 中提到的案例并且它正在运行。请查看下面提到的输出:
create table sales(product varchar2(20),month date, amount number(10))
Affected rows: 0
Time: 0.012s
insert into sales values('LG','01-Jan-17',20000)
Affected rows: 1
Time: 0.003s
insert into sales values('sony','01-Jan-18',22000)
Affected rows: 1
Time: 0.004s
insert into sales values('panasonic', '22-dec-17',18000)
Affected rows: 1
Time: 0.003s
create table sales_history(product varchar2(20),month date, amount number(10))
Affected rows: 0
Time: 0.004s
insert into sales_history values('sony', '22-dec-17',24000)
Affected rows: 1
Time: 0.002s
insert into sales_history values('panasonic', '22-dec-17',18000)
Affected rows: 1
Time: 0.003s
merge into sales_history sh using(select product,month,amount from sales)s
on (s.product=sh.product)
when matched then update set sh.month=s.month,sh.amount=s.amount
when not matched then insert(sh.product,sh.month,sh.amount)
values(s.product,s.month,s.amount)
Affected rows: 3
Time: 0.015s
写的时候
if s_product = p_product then
<<your code>>
else
<<your code>>
当第一个产品名称是 sony 来自 table sales 时,它与 匹配sales_history 中的 sony 并提供所需的输出,但它与 sales_hist[ 中的其他条目不匹配=30=] 并执行插入代码的 else 部分。结果是多行。
查看下面的输出。我尝试使用多个 dbms 输出。 else 当 sony 不同于 panasonic 等时执行 else 部分。
set serveroutput on
declare
s_product varchar2(20);
s_month date;
s_amount number(10);
p_product s_product%type;
m_month s_month%type;
a_amount s_amount%type;
cursor sc1 is
select product,month,amount from sales;
cursor shc2 is
select product,month,amount from sales_history;
begin
open sc1;
open shc2;
loop <<ll>>
fetch sc1 into s_product,s_month,s_amount;
fetch shc2 into p_product,m_month,a_amount;
dbms_output.put_line('outside if');
dbms_output.put_line(s_product);
dbms_output.put_line(p_product);
if s_product = p_product then
dbms_output.put_line(p_product);
if s_month <> m_month then
dbms_output.put_line(m_month);
update sales_history set month = s_month where product = s_product;
end if;
if s_amount <> a_amount then
update sales_history set amount = s_amount where product = s_product;
end if;
else
INSERT INTO sales_history(product, month, amount)
SELECT product, month, amount FROM sales;
dbms_output.put_line('DATA IS UPDATED');
end if;
exit when sc1%notfound;
exit when shc2%notfound;
end loop l1;
close sc1;
close shc2;
end;
输出
outside if
LG
sony
DATA IS UPDATED
outside if
sony
panasonic
DATA IS UPDATED
outside if
panasonic
panasonic
panasonic
我正在 Oracle 11g 中执行 MERGE 操作,但它们返回的行多于预期。
create table sales(product varchar2(20),month date, amount number(10))
insert into sales values('LG','01-Jan-17',20000);
insert into sales values('sony','01-Jan-18',22000);
insert into sales values('panasonic', '22-dec-17',18000);
create table sales_history(product varchar2(20),month date, amount number(10))
insert into sales_history values('sony', '22-dec-17',24000);
insert into sales_history values('panasonic', '22-dec-17',18000);
select * from sales;
select * from sales_history
merge into sales_history sh using(select product,month,amount from sales)s
on (s.product=sh.product)
when matched then update set sh.month=s.month,sh.amount=s.amount
when not matched then insert(sh.product,sh.month,sh.amount)
values(s.product,s.month,s.amount);
并且我尝试在 Pl/SQL 中执行相同的查询,这将给我相同的结果,但它返回更多重复的行 rows.Why 是这样吗?
set serveroutput on
declare
s_product varchar2(20);
s_month date;
s_amount number(10);
p_product s_product%type;
m_month s_month%type;
a_amount s_amount%type;
cursor sc1 is
select product,month,amount from sales;
cursor shc2 is
select product,month,amount from sales_history;
begin
open sc1;
open shc2;
loop <<l1>>
fetch sc1 into s_product,s_month,s_amount;
fetch shc2 into p_product,m_month,a_amount;
if s_product = p_product then
if s_month <> m_month then
update sales_history set month = s_month where product = s_product;
end if;
if s_amount <> a_amount then
update sales_history set amount = s_amount where product = s_product;
end if;
else
INSERT INTO sales_history(product, month, amount)
SELECT product, month, amount FROM sales;
dbms_output.put_line('DATA IS UPDATED');
end if;
exit when sc1%notfound;
exit when shc2%notfound;
end loop l1;
close sc1;
close shc2;
end;
select * from sales_history
我已经尝试执行 Oracle 12c 中提到的案例并且它正在运行。请查看下面提到的输出:
create table sales(product varchar2(20),month date, amount number(10))
Affected rows: 0
Time: 0.012s
insert into sales values('LG','01-Jan-17',20000)
Affected rows: 1
Time: 0.003s
insert into sales values('sony','01-Jan-18',22000)
Affected rows: 1
Time: 0.004s
insert into sales values('panasonic', '22-dec-17',18000)
Affected rows: 1
Time: 0.003s
create table sales_history(product varchar2(20),month date, amount number(10))
Affected rows: 0
Time: 0.004s
insert into sales_history values('sony', '22-dec-17',24000)
Affected rows: 1
Time: 0.002s
insert into sales_history values('panasonic', '22-dec-17',18000)
Affected rows: 1
Time: 0.003s
merge into sales_history sh using(select product,month,amount from sales)s
on (s.product=sh.product)
when matched then update set sh.month=s.month,sh.amount=s.amount
when not matched then insert(sh.product,sh.month,sh.amount)
values(s.product,s.month,s.amount)
Affected rows: 3
Time: 0.015s
写的时候
if s_product = p_product then
<<your code>>
else
<<your code>>
当第一个产品名称是 sony 来自 table sales 时,它与 匹配sales_history 中的 sony 并提供所需的输出,但它与 sales_hist[ 中的其他条目不匹配=30=] 并执行插入代码的 else 部分。结果是多行。
查看下面的输出。我尝试使用多个 dbms 输出。 else 当 sony 不同于 panasonic 等时执行 else 部分。
set serveroutput on
declare
s_product varchar2(20);
s_month date;
s_amount number(10);
p_product s_product%type;
m_month s_month%type;
a_amount s_amount%type;
cursor sc1 is
select product,month,amount from sales;
cursor shc2 is
select product,month,amount from sales_history;
begin
open sc1;
open shc2;
loop <<ll>>
fetch sc1 into s_product,s_month,s_amount;
fetch shc2 into p_product,m_month,a_amount;
dbms_output.put_line('outside if');
dbms_output.put_line(s_product);
dbms_output.put_line(p_product);
if s_product = p_product then
dbms_output.put_line(p_product);
if s_month <> m_month then
dbms_output.put_line(m_month);
update sales_history set month = s_month where product = s_product;
end if;
if s_amount <> a_amount then
update sales_history set amount = s_amount where product = s_product;
end if;
else
INSERT INTO sales_history(product, month, amount)
SELECT product, month, amount FROM sales;
dbms_output.put_line('DATA IS UPDATED');
end if;
exit when sc1%notfound;
exit when shc2%notfound;
end loop l1;
close sc1;
close shc2;
end;
输出
outside if
LG
sony
DATA IS UPDATED
outside if
sony
panasonic
DATA IS UPDATED
outside if
panasonic
panasonic
panasonic