Обновляемое представление (Oracle) - PullRequest
4 голосов
/ 30 июня 2011

Допустим, у нас есть следующее:

create view view_1 as
(
  select key, data from some_table_or_view;
);

create table table_1
(
  key
  more_data
);

create view view_2 as
(
  select v1.key, v1.data, t1.more_data 
  from view_1 v1, table_1 t1 
  where v1.key = t1.key
);

create table table_2 as
(
  key
  data
  more_data
);

create view view_3 as
(
  select key, data, more_data from view_2
  union
  select key, data, more_data from table_2
);

Итак, по сути, мы объединили два потока данных, один из которых поступил из объединения, а другой - необработанные данные.

Я хочу иметь возможность сделать следующее.

update view_3 set more_data = 'BLAH_MORE_DATA' where key = 'BLAH_KEY';

Где это каким-то образом обновляет либо table_1, либо table_2, в зависимости от того, происходит ли BLAH_KEY от table_1 или table_2.

В настоящее время я могу думать только о следующем:

create view view_3 as
(
  select 'TAB1' as source, key, data, more_data from view_2
  union
  select 'TAB2' as source, key, data, more_data from table_2
);

и затем выполнение обновлений с использованием функции PL / SQL, которая проверяет исходный столбец и обновляет соответствующую таблицу, но это означает, что я должен синхронизировать представление и функцию PL / SQL.

Я ищу более хороший способ сделать это.

Ответы [ 3 ]

7 голосов
/ 30 июня 2011

Вы можете использовать вместо триггера на view_3

CREATE OR REPLACE TRIGGER view3_trg
INSTEAD OF  UPDATE
ON view_3
FOR EACH ROW
BEGIN
IF :OLD.source = 'TAB1' THEN

  UPDATE table_1 t1
  set t1.data = :NEW.data
  WHERE
    t1.key = :OLD.key
  ;
ELSIF OLD.source = 'TAB2' THEN
   UPDATE table_2 t2
  set t2.data = :NEW.data
  WHERE
    t2.key = :OLD.key
  ;
END IF;
END;
/
2 голосов
/ 01 июля 2011
create view view_2 as
(
  select v1.key, v1.data, t1.more_data 
  from view_1 v1, table_1 t1 
  where v1.key = t1.key
);

View_2, вероятно, не будет обновляемым. Или, по крайней мере, только столбцы дочерней таблицы в принудительном отношении внешнего ключа.

Проверьте user_updatable_columns, чтобы увидеть, какие столбцы представления могут автоматически обновляться (то есть, где Oracle может решить, что обновление столбца никогда не может быть неоднозначным). Используя EMP и DEPT, например, если SMITH и JONES работают для одного и того же отдела, вы не можете обновить название отдела только для SMITH (поскольку dept_name является атрибутом родителя), но вы можете обновить зарплату SMITH. *

2 голосов
/ 30 июня 2011

Адаптируем ответ Щурика и учтем ваш комментарий о "болезни еще-если-Геймера":

CREATE OR REPLACE TRIGGER view3_trg
INSTEAD OF  UPDATE
ON view_3
FOR EACH ROW
BEGIN
  UPDATE table_1 t1
  set t1.data = :NEW.data
  WHERE t1.key = :OLD.key;

  UPDATE table_2 t2
  set t2.data = :NEW.data
  WHERE t2.key = :OLD.key;
END;

/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...