2010-04-22 100 views
3

如何使用單個查詢更新多個表中的數據?使用單個查詢更新多個表列值

的MySQL實例

等效在MySQL代碼:

 
UPDATE party p 
LEFT JOIN party_name n ON p.party_id = n.party_id 
LEFT JOIN party_details d ON p.party_id = d.party_id 
LEFT JOIN incident_participant ip ON ip.party_id = p.party_id 
LEFT JOIN incident i ON ip.incident_id = i.incident_id 
SET 
    p.employee_id = NULL, 
    c.em_address = '[email protected]', 
    c.ad_postal = 'x', 
    n.first_name = 'x', 
    n.last_name = 'x' 
WHERE 
    i.confidential_dt IS NOT NULL 

什麼是使用Oracle 11g相同的語句?

謝謝!

RTFM

看來當使用一個單一的查詢是不夠的甲骨文:

http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/statements_108a.htm#2067717

回答

5
/** XXX CODING HORROR... */ 

根據您的需求,您可以使用一個更新視圖。您創建基表的視圖並向此視圖添加「而不是」觸發器,並直接更新視圖。

一些示例表:

create table party (
    party_id integer, 
    employee_id integer 
    ); 

create table party_name (
    party_id integer, 
    first_name varchar2(120 char), 
    last_name varchar2(120 char) 
    ); 

insert into party values (1,1000); 
insert into party values (2,2000); 
insert into party values (3,3000); 

insert into party_name values (1,'Kipper','Family'); 
insert into party_name values (2,'Biff','Family'); 
insert into party_name values (3,'Chip','Family'); 

commit; 

select * from party_v; 

PARTY_ID EMPLOYEE_ID FIRST_NAME LAST_NAME 
1   1000   Kipper  Family 
2   2000   Biff   Family 
3   3000   Chip   Family 

...然後創建一個可更新視圖

create or replace view party_v 
as 
select 
    p.party_id, 
    p.employee_id, 
    n.first_name, 
    n.last_name 
from 
    party p left join party_name n on p.party_id = n.party_id; 

create or replace trigger trg_party_update 
instead of update on party_v 
for each row 
declare 
begin 
-- 
    update party 
    set 
     party_id = :new.party_id, 
     employee_id = :new.employee_id 
    where 
     party_id = :old.party_id; 
-- 
    update party_name 
    set 
     party_id = :new.party_id, 
     first_name = :new.first_name, 
     last_name = :new.last_name 
    where 
     party_id = :old.party_id; 
-- 
end; 
/

現在,您可以直接更新視圖...

update party_v 
set 
    employee_id = 42, 
    last_name = 'Oxford' 
where 
    party_id = 1; 

select * from party_v; 

PARTY_ID EMPLOYEE_ID FIRST_NAME LAST_NAME 
1   42    Kipper  Oxford 
2   2000   Biff   Family 
3   3000   Chip   Family 
+1

感謝你,尼克。令人遺憾的是,除了用同樣的where子句創建三個不同的更新語句之外,還有很多工作要做。這更難以維護(表格,視圖和觸發器與具有三條更新語句的一個過程)。直到有更好的解決方案出現,你的勝利。 ;-) – 2010-04-23 16:45:58

1

我有同樣的問題,我無法找到一個簡單的方法在Oracle中做到這一點。

看這裏: Oracle Update Statements欲瞭解更多信息。

1

您可以使用Oracle MERGE語句來執行此操作。它是基於通過內聯視圖連接目標表的批量更新或插入語句。

MERGE INTO bonuses D 
    USING (
     SELECT employee_id, salary, department_id FROM employees 
     WHERE department_id = 80 
    ) S ON (D.employee_id = S.employee_id) 
WHEN MATCHED THEN 
    UPDATE SET D.bonus = D.bonus + S.salary*.01 
WHEN NOT MATCHED THEN 
    INSERT (D.employee_id, D.bonus) 
    VALUES (S.employee_id, S.salary*0.1); 

如果您不需要插入部分,您只需省略上面的最後3行。

+0

雖然你的問題是關於同時更新多個表 - 不能與MERGE一個選項。 – 2010-04-23 08:34:13

+0

糟糕 - 你說得很對 - 誤解了這個問題。對不起 – 2010-04-23 11:28:38

1

在某些情況下,可以使用PL/SQL來實現這一點。在我的情況下,我通過一些標準在兩個表中搜索匹配的行,然後在循環中更新每一行。

事情是這樣的:

begin 
    for r in (
    select t1.id as t1_id, t2.id as t2_id 
    from t1, t2 
    where ... 
) loop 
    update t1 
    set ... 
    where t1.id = r.t1_id; 

    update t2 
    set ... 
    where t2.id = r.t2_id; 
    end loop; 
end;