2010-04-22 4 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

кажется один запрос является недостаточным при использовании Oracle:

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. Это и сложнее поддерживать (таблицы, представления и триггеры по сравнению с одной процедурой с тремя операциями обновления). Пока не появится лучшее решение, ваши побеждают. ;-) –

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. –

+0

К сожалению, вы совершенно правы - неправильно задайте вопрос. Извините, –

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; 
Смежные вопросы