Я выполняю операцию MERGE в Oracle 11g, но они возвращают больше строк, чем ожидалось.
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, который даст мне те же результаты, но он возвращает больше строк, которые являются дублированными. Почему это так?
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
2 ответа
Я попытался выполнить вышеупомянутый случай в Oracle 12C, и он работает. Пожалуйста, смотрите выходные данные, упомянутые ниже
[SQL]create table sales(product varchar2(20),month date, amount number(10))
Affected rows: 0
Time: 0.012s
[SQL]insert into sales values('LG','01-Jan-17',20000)
Affected rows: 1
Time: 0.003s
[SQL]insert into sales values('sony','01-Jan-18',22000)
Affected rows: 1
Time: 0.004s
[SQL]insert into sales values('panasonic', '22-dec-17',18000)
Affected rows: 1
Time: 0.003s
[SQL]create table sales_history(product varchar2(20),month date, amount number(10))
Affected rows: 0
Time: 0.004s
[SQL]insert into sales_history values('sony', '22-dec-17',24000)
Affected rows: 1
Time: 0.002s
[SQL]insert into sales_history values('panasonic', '22-dec-17',18000)
Affected rows: 1
Time: 0.003s
[SQL]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
Когда вы пишете, если s_product = p_product, то <> else <>
и когда 1-е имя продукта - sony из таблицы продаж, оно совпадает с sony в sales_history и выдает желаемый результат, но также не совпадает с другой записью в sales_hist и выполняет остальную часть вашего кода, которая является вставкой, это дает вам несколько строк как результат. смотрите вывод ниже, я пытаюсь с несколькими выходами дБмс. Остальная часть исполняется, когда Sony <> Panasonic и так далее.
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;
Output
outside if
LG
sony
DATA IS UPDATED
outside if
sony
panasonic
DATA IS UPDATED
outside if
panasonic
panasonic
panasonic
Похожие вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.