Могу я копировать: СТАРЫЙ и: НОВЫЕ псевдозаписи в/к хранимой процедуре Oracle?

Я имею AFTER INSERT OR UPDATE OR DELETE триггер, который я пишу для хранения каждого рекордного пересмотра, который происходит в определенной таблице путем копирования INSERT и UPDATE :NEW значения в зеркальную таблицу, и для DELETE :OLD значения.

Я мог значительно не создать помехи своему коду путем условной передачи любого :NEW или :OLD запись в процедуру, которая затем сделала бы вставку в мою таблицу истории. К сожалению, я, может казаться, не нахожу способ передать все :OLD или :NEW запись.

Я пропускаю что-то или не являюсь там никаким способом постараться не перечислять каждый :NEW и :OLD столбец, поскольку я вызываю свою процедуру вставки?

Я хочу сделать следующее:

DECLARE
  PROCEDURE LOCAL_INSERT(historyRecord in ACCT.ACCOUNTS%ROWTYPE) IS
  BEGIN
    INSERT INTO ACCT.ACCOUNTS_HISTORY (ID, NAME, DESCRIPTION, DATE) VALUES (historyRecord.ID, historyRecord.NAME, historyRecord.DESCRIPTION, SYSDATE);
  END;
BEGIN
  IF INSERTING OR UPDATING THEN
    LOCAL_INSERT(:NEW);
  ELSE --DELETING
    LOCAL_INSERT(:OLD);
  END IF;
END;

Но я застреваю, делая это:

DECLARE
  PROCEDURE LOCAL_INSERT(id in ACCT.ACCOUNTS.ID%TYPE,
                         name in ACCT.ACCOUNTS.NAME%TYPE,
                         description in ACCT.ACCOUNTS.DESCRIPTION%TYPE) IS
  BEGIN
    INSERT INTO ACCT.ACCOUNTS_HISTORY (ID, NAME, DESCRIPTION, DATE) VALUES (id, name, description, SYSDATE);
  END;
BEGIN
  IF INSERTING OR UPDATING THEN
    LOCAL_INSERT(:NEW.ID, :NEW.NAME, :NEW.DESCRIPTION);
  ELSE --DELETING
    LOCAL_INSERT(:OLD.ID, :OLD.NAME, :OLD.DESCRIPTION);
  END IF;
END;

Хорошо, таким образом, это не похоже на большую разницу, но это - просто пример с 3 столбцами, а не десятки.

6
задан aw crud 25 February 2010 в 20:38
поделиться

2 ответа

Это не так. Вы должны сделать это сами посредством перечисления.

Причины, по которым он не может / не работает автоматически, включают:

  • : старый и : новый - соглашения по умолчанию; вы можете присвоить ссылкам : old и : new все, что захотите, с помощью предложения REFERENCING оператора CREATE TRIGGER .

  • вам потребуется публичное объявление типа (через CREATE TYPE или через объявление пакета), чтобы иметь возможность использовать его в качестве аргумента для другого фрагмента кода.

  • код триггера - это интерпретируемый код, а не скомпилированный код.

3
ответ дан 17 December 2019 в 07:03
поделиться

Я не думаю, что такое возможно. Документация не упоминает ничего подобного.

Это, конечно, будет стоить производительности, но вы можете попробовать определить свой триггер AFTER INSERT и другой BEFORE UPDATE OR DELETE, и в триггере сделать что-то вроде:

SELECT *
INTO rowtype_variable
FROM accounts
WHERE accounts.id = :NEW.id; -- :OLD.id for UPDATE and DELETE

а затем вызвать свою процедуру с этой rowtype_variable.

1
ответ дан 17 December 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: