Oracle 19c Trigger INSTEAD OF on View;Поля CHAR и VARCHAR2 не будут привязаны PLS-00049: неверная переменная привязки 'NEW.component' - PullRequest
1 голос
/ 23 сентября 2019

Я пытаюсь работать над представлениями для вставки в разные таблицы в зависимости от содержимого, которое нужно вставить;в следующем примере он использует дату для вставки в разные таблицы, используя вместо триггера.

Проблема у меня в том, что она просто не будет связываться.Я попытался использовать динамический SQL в операторах EXECUTE IMMEDIATE, чтобы попытаться обойти, но столбцы, которые основаны на символах, не будут связываться.Меня интересует, является ли проблема результатом сравнения моих таблиц и представлений?Но это может быть серьезный EBCAK, любой совет, который высоко ценится.

** ОБНОВЛЕНИЕ НЕСКОЛЬКО НОВЫЙ СХЕМА, НЕ ЗАКАЗАНО **

DROP VIEW TEST_ORACLE.events_recorded;
DROP TABLE TEST_ORACLE.events_recorded23SEP19;
DROP TABLE TEST_ORACLE.events_recorded24SEP19;
DROP TABLE TEST_ORACLE.events_recorded25SEP19;
/

CREATE TABLE TEST_ORACLE.events_recorded23SEP19  (txn CHAR(36 BYTE) COLLATE BINARY_CI, 
    stack_trace CLOB COLLATE USING_NLS_COMP,  originating_file NVARCHAR2(500) COLLATE BINARY_CI, originating_line_nr NUMBER(20,0), 
    date_and_time TIMESTAMP (6) WITH TIME ZONE DEFAULT (CURRENT_TIMESTAMP) NOT NULL,
    CONSTRAINT PK_events_recorded23SEP19 PRIMARY KEY (txn));

CREATE TABLE TEST_ORACLE.events_recorded24SEP19  (txn CHAR(36 BYTE) COLLATE BINARY_CI, 
    stack_trace CLOB COLLATE USING_NLS_COMP,  originating_file NVARCHAR2(500) COLLATE BINARY_CI, originating_line_nr NUMBER(20,0), 
    date_and_time TIMESTAMP (6) WITH TIME ZONE DEFAULT (CURRENT_TIMESTAMP) NOT NULL,
    CONSTRAINT PK_events_recorded24SEP19 PRIMARY KEY (txn));

CREATE TABLE TEST_ORACLE.events_recorded25SEP19  (txn CHAR(36 BYTE) COLLATE BINARY_CI, 
    stack_trace CLOB COLLATE USING_NLS_COMP,  originating_file NVARCHAR2(500) COLLATE BINARY_CI, originating_line_nr NUMBER(20,0), 
    date_and_time TIMESTAMP (6) WITH TIME ZONE DEFAULT (CURRENT_TIMESTAMP) NOT NULL,
    CONSTRAINT PK_events_recorded25SEP19 PRIMARY KEY (txn));

CREATE OR REPLACE FORCE NONEDITIONABLE VIEW TEST_ORACLE.events_recorded ( txn, stack_trace, originating_file, originating_line_nr, date_and_time) DEFAULT COLLATION BINARY_CI  AS 
SELECT txn, stack_trace, originating_file, originating_line_nr, date_and_time FROM events_recorded23SEP19 UNION ALL SELECT txn, stack_trace, originating_file, originating_line_nr, date_and_time FROM events_recorded24SEP19 UNION ALL SELECT txn, stack_trace, originating_file, originating_line_nr, date_and_time FROM events_recorded25SEP19;
/

CREATE OR REPLACE TRIGGER events_recorded_trigger DEFAULT COLLATION BINARY_CI 
INSTEAD OF INSERT OR UPDATE OR DELETE ON events_recorded FOR EACH ROW 
BEGIN
  IF INSERTING AND replace(to_char(:NEW.date_and_time), '-', '') = '23SEP19' THEN
    INSERT INTO events_recorded23SEP19 (txn, date_and_time, stack_trace, originating_file, originating_line_nr) VALUES (:NEW.txn, :NEW.date_and_time, :NEW.stack_trace, :NEW.originating_file, :NEW.originating_line_nr);
  ELSIF INSERTING AND replace(to_char(:NEW.date_and_time), '-', '') = '24SEP19' THEN
    INSERT INTO events_recorded24SEP19 (txn, date_and_time, stack_trace, originating_file, originating_line_nr) VALUES (:NEW.txn, :NEW.date_and_time, :NEW.stack_trace, :NEW.originating_file, :NEW.originating_line_nr);
  ELSIF INSERTING AND replace(to_char(:NEW.date_and_time), '-', '') = '25SEP19' THEN
    INSERT INTO events_recorded25SEP19 (txn, date_and_time, stack_trace, originating_file, originating_line_nr) VALUES (:NEW.txn, :NEW.date_and_time, :NEW.stack_trace, :NEW.originating_file, :NEW.originating_line_nr);
  ELSIF UPDATING AND replace(to_char(:NEW.date_and_time), '-', '')  = '23SEP19' THEN
    UPDATE events_recorded23SEP19 SET txn = :NEW.txn, date_and_time = :NEW.date_and_time, stack_trace = :NEW.stack_trace, originating_file = :NEW.originating_file, originating_line_nr = :NEW.originating_line_nr WHERE txn = :OLD.txn;
  ELSIF UPDATING AND replace(to_char(:NEW.date_and_time), '-', '')  = '24SEP19' THEN
    UPDATE events_recorded24SEP19 SET txn = :NEW.txn, date_and_time = :NEW.date_and_time, stack_trace = :NEW.stack_trace, originating_file = :NEW.originating_file, originating_line_nr = :NEW.originating_line_nr WHERE txn = :OLD.txn;
  ELSIF UPDATING AND replace(to_char(:NEW.date_and_time), '-', '')  = '25SEP19' THEN
    UPDATE events_recorded25SEP19 SET txn = :NEW.txn, date_and_time = :NEW.date_and_time, stack_trace = :NEW.stack_trace, originating_file = :NEW.originating_file, originating_line_nr = :NEW.originating_line_nr WHERE txn = :OLD.txn;
  ELSIF DELETING AND replace(to_char(:NEW.date_and_time), '-', '')  = '23SEP19' THEN
    DELETE FROM events_recorded23SEP19 WHERE txn = :OLD.txn;
  ELSIF DELETING AND replace(to_char(:NEW.date_and_time), '-', '')  = '24SEP19' THEN
    DELETE FROM events_recorded24SEP19 WHERE txn = :OLD.txn;
  ELSIF DELETING AND replace(to_char(:NEW.date_and_time), '-', '')  = '25SEP19' THEN
    DELETE FROM events_recorded25SEP19 WHERE txn = :OLD.txn;
  END IF; 
END;

Таким образом, вышеприведенное все еще дает ошибку:


Trigger EVENTS_RECORDED_TRIGGER compiled

LINE/COL  ERROR
--------- -------------------------------------------------------------
3/121     PLS-00049: bad bind variable 'NEW.TXN'
3/169     PLS-00049: bad bind variable 'NEW.ORIGINATING_FILE'
5/121     PLS-00049: bad bind variable 'NEW.TXN'
5/169     PLS-00049: bad bind variable 'NEW.ORIGINATING_FILE'
7/121     PLS-00049: bad bind variable 'NEW.TXN'
7/169     PLS-00049: bad bind variable 'NEW.ORIGINATING_FILE'
9/45      PLS-00049: bad bind variable 'NEW.TXN'
9/142     PLS-00049: bad bind variable 'NEW.ORIGINATING_FILE'
9/224     PLS-00049: bad bind variable 'OLD.TXN'
11/45     PLS-00049: bad bind variable 'NEW.TXN'
11/142    PLS-00049: bad bind variable 'NEW.ORIGINATING_FILE'
11/224    PLS-00049: bad bind variable 'OLD.TXN'
13/45     PLS-00049: bad bind variable 'NEW.TXN'
13/142    PLS-00049: bad bind variable 'NEW.ORIGINATING_FILE'
13/224    PLS-00049: bad bind variable 'OLD.TXN'
15/52     PLS-00049: bad bind variable 'OLD.TXN'
17/52     PLS-00049: bad bind variable 'OLD.TXN'
19/52     PLS-00049: bad bind variable 'OLD.TXN'
Errors: check compiler log

Ответы [ 2 ]

2 голосов
/ 23 сентября 2019

Это триггер INSTEAD OF для представления "events_recorded".Таким образом, соответствующий DDL был бы оператором create or replace view.Я предполагаю, что столбцы, определенные в проекции представления, не совпадают с двойными кавычками переменных, на которые ссылается триггер.

Конечно, это может быть какая-то другая разница, но основной причиной является то, что представление не имеет столбцов с именами "component", "transaction_id", "originating_file", "owner" или "linked_entity".


Я попытался запустить ваш исправленный скрипт.Для меня это не удалось на ORA-43929, потому что у вас есть весь этот синтаксис Collation, а в моей локальной базе данных MAX_STRING_SIZE = STANDARD.Боюсь, я подведу черту при пересоздании базы данных, чтобы ответить на ТАКИЙ вопрос.Я удалил все инструкции COLLATE и COLLATION, и ваш опубликованный скрипт компилируется полностью.

так что каким-то образом это сопоставление этих столбцов (sic) вызывает боль

Кажется, что так, хотя трудно понять, почему это так.Если у вас есть учетная запись службы поддержки Oracle, я советую вам поднять билет.

0 голосов
/ 24 сентября 2019

Возможно, вы могли бы использовать динамический SQL, чтобы сделать вашу жизнь немного лучше:

CREATE OR REPLACE TRIGGER events_recorded_trigger
  INSTEAD OF INSERT OR UPDATE OR DELETE
  ON EVENTS_RECORDED
  FOR EACH ROW
DECLARE
  strStmt  VARCHAR2(32000);
  strDate  VARCHAR2(200);
BEGIN
  strDate := TO_CHAR(NVL(:NEW.DATE_AND_TIME, :OLD.DATE_AND_TIME), 'DDMONRR');

  IF INSERTING THEN
    strStmt := 'INSERT INTO events_recorded' || strDate ||
               '(txn, date_and_time, stack_trace, originating_file,originating_line_nr)' ||
               ' VALUES (:a, :b, :c, :d, :e)';

   EXECUTE IMMEDIATE strStmt
     USING :NEW.txn, :NEW.date_and_time, :NEW.stack_trace,
           :NEW.originating_file, :NEW.originating_line_nr;
  ELSIF UPDATING THEN
    strStmt := 'UPDATE events_recorded' || strDate ||
               ' SET txn = :a, date_and_time = :b, stack_trace = :c, ' ||
               '     originating_file = :d, originating_line_nr = :e ' ||
               ' WHERE txn = :f';

    EXECUTE IMMEDIATE strStmt
      USING :NEW.txn, :NEW.date_and_time, :NEW.stack_trace, 
            :NEW.originating_file, :NEW.originating_line_nr, :OLD.txn;
  ELSIF DELETING THEN
    strStmt := 'DELETE FROM events_recorded' || strDate ||
               ' WHRE txt = :a';
    EXECUTE IMMEDIATE strStmt
      USING :OLD.txn;
  END IF; 
END events_recorded_trigger;
...