Как настроить обновляемый вид с помощью объединения в Firebird? - PullRequest
6 голосов
/ 23 марта 2012

У меня есть три таблицы, назовем их GRANDPARENT, PARENT и CHILD.PARENT имеет столбец FK для PK GRANDPARENT, а CHILD имеет столбец FK для PK PARENT.Пока все хорошо.

Теперь я хочу настроить представление, содержащее всю информацию в CHILD, плюс PK из GRANDPARENT.Итак:

CREATE VIEW CHILD_VIEW
(
  ID,
  PARENT_ID,
  OTHER_STUFF,
  GRANDPARENT_ID
)
AS
SELECT 
  C.ID,
  C.PARENT_ID,
  C.OTHER_STUFF,
  C.GRANDPARENT_ID
FROM CHILD C
join PARENT P on P.ID = C.PARENT_ID;

Не слишком сложно.Но вот сложная часть: я хочу иметь возможность INSERT или UPDATE для этого представления, и чтобы все соответствующие данные были записаны в таблицу CHILD, а значение GRANDPARENT_ID, если оно есть, следует игнорировать.

Я немного погуглил, и, очевидно, должна быть возможность настроить обновляемое представление, например, «с помощью триггеров», но оно нигде не объясняет, что я должен делать стриггеры для достижения этого эффекта.Я думаю, что знаю более или менее, как обращаться с делом INSERT, но как насчет дела UPDATE?UPDATE операторы имеют WHERE предложения и могут содержать или не содержать произвольные столбцы в таблице.

Например, как мне использовать триггер для преобразования чего-то вроде update CHILD_VIEW set (blah blah blah) where ID = 5 в update CHILD set (blah blah blah excluding GRANDPARENT_ID) where ID = 5

1 Ответ

6 голосов
/ 23 марта 2012

Ну, вы делаете это с помощью триггеров, как вы уже узнали:)

Это действительно так просто, вы можете использовать все функции, доступные в триггерах (например, OLD и NEW контексты) ... если вы используете Firebird 2.1 или новее, то вы можете использовать UPDATE ИЛИ INSERT , или вы можете использовать контекстные переменные INSERTING и UPDATING , чтобы определить, является ли это обновлением или вставкой в ​​триггер много действия. Или, конечно, вы можете написать отдельные триггеры ON UPDATE и ON INSERT ...

Так что ваш триггер может выглядеть примерно так

CREATE TRIGGER CHILD_VIEW_Save FOR CHILD_VIEW
ACTIVE BEFORE INSERT OR UPDATE POSITION 10
AS
BEGIN
  IF(NEW.ID IS NULL)THEN NEW.ID = GEN_ID(GEN_Child, 1);
  UPDATE OR INSERT INTO CHILD (ID, PARENT_ID, OTHER_STUFF, GRANDPARENT_ID)
            VALUES(NEW.ID, NEW.PARENT_ID, NEW.OTHER_STUFF, NEW.GRANDPARENT_ID);
END
...