Dzień dobry wszystkim,

Mam problem z tworzeniem pracy spustowej. Jeśli chodzi o funkcjonalność ciała i jak się zachowuje, robi to dokładnie tak, jak zamierzałem się zachowywać. Jednakże, gdy zaczynam strzelać spust, zwraca błąd, w którym wyzwalacze nie powinny mieć instrukcji wyboru od wewnątrz głównego korpusu. Nadal jestem dość nowy, aby kodować i jak zmaterializować pomysł w mojej głowie do kodu. Mam nadzieję, że ktoś mógłby wskazać mnie we właściwy kierunek, jak zmienić wyzwalacz, który chciałbym mieć jako wynik końcowy. Zobacz poniżej skrypt.

Aktualizacja: Oczekiwany wynik byłby za każdym razem, gdy użytkownik zostanie zaktualizowany wiersz i włożyć nowy rekord za pośrednictwem aplikacji lub pracy w tle, S1_HOVER_REPORT byłoby zaktualizowane z wartością z SELECT skrypt i użyj danych z danych S1_HOVER Wynik przypadrek.

(Edytuj: Zaktualizowałem szczegóły powyższego problemu, dodałem stosowaną tabelę i powrót błędów)

Table: SITE
Column Name       Type        
------------------------------
ID                VARCHAR2(14)
NAME              VARCHAR2(70)
TYPE_CODE         VARCHAR2(2)
PARENT            VARCHAR2(14)
S1_HOVER_REPORT   VARCHAR2(14) 
CREATE OR REPLACE TRIGGER MESS.S1_HOVER_REPORT
AFTER INSERT OR UPDATE ON MESS.SITE
FOR EACH ROW
BEGIN
   UPDATE (SELECT S1.ID,
                  S1.NAME,
                  S1.TYPE_CODE,
                  S1.PARENT AS PARENT1,
                  S2.PARENT AS PARENT2,
                  S1.S1_HOVER_REPORT,
                  CASE
                     WHEN (S1.TYPE_CODE = 'H2') THEN S1.PARENT
                     WHEN (S1.TYPE_CODE = 'S1') THEN S2.PARENT
                     ELSE S1.ID
                  END AS S1_HOVER
             FROM SITE S1,
                     (SELECT ID,
                             NAME,
                             PARENT,
                             TYPE_CODE
                        FROM site
                       WHERE type_code='H2') S2
            WHERE S1.PARENT=S2.ID
               OR S1.ID = S2.PARENT) S3
   SET S3.S1_HOVER_REPORT = S3.S1_HOVER;
END;
Error returned when Trigger fired:
Error report -
SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
ORA-06512: at "MES.S1_HOVER_REPORT", line 2
ORA-04088: error during execution of trigger 'MES.S1_HOVER_REPORT'
01779. 00000 -  "cannot modify a column which maps to a non key-preserved table"
*Cause:    An attempt was made to insert or update columns of a join view which
           map to a non-key-preserved table.
*Action:   Modify the underlying base tables directly.

( Aktualizacja: Uwzględniłem zaktualizowany wyzwalacz i teraz kompilacji bez problemu, ale mam błędy, gdy próbuję aktualizować rekord)

CREATE OR REPLACE TRIGGER MESS.S1_HOVER_REPORT
BEFORE INSERT OR UPDATE ON MESS.SITE
FOR EACH ROW
DECLARE
   v_S1_HOVER_REPORT VARCHAR2(14);
BEGIN
SELECT CASE
           WHEN (S1.TYPE_CODE = 'H2') THEN S1.PARENT
           WHEN (S1.TYPE_CODE = 'S1') THEN S2.PARENT
           ELSE (S1.ID)
        END AS S1_HOVER
   INTO v_S1_HOVER_REPORT
   FROM SITE S1,
       (SELECT ID,
               NAME,
               PARENT,
               TYPE_CODE
          FROM site
         WHERE type_code='H2') S2
  WHERE S1.PARENT=S2.ID
     OR S1.ID = S2.PARENT;

:NEW.S1_HOVER_REPORT := v_S1_HOVER_REPORT;
END;
Error report -
SQL Error: ORA-04091: table MES.SITE is mutating, trigger/function may not see it
ORA-06512: at "MES.S1_HOVER_REPORT", line 4
ORA-04088: error during execution of trigger 'MES.S1_HOVER_REPORT'
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it"
*Cause:    A trigger (or a user defined plsql function that is referenced in
           this statement) attempted to look at (or modify) a table that was
           in the middle of being modified by the statement which fired it.
*Action:   Rewrite the trigger (or function) so it does not read that table.
0
Eiro Spades 19 październik 2020, 14:26

1 odpowiedź

Najlepsza odpowiedź

Po pierwsze z komunikatu o błędzie

An attempt was made to insert or update columns of a join view which map to a non-key-preserved table.

S3 to widok (tworzysz widok, wykonując wybierz w instrukcję aktualizacji). Możesz spróbować zmienić to, aby mieć kluczowe zachowanie, ale naprawdę nie wiedziałbym, jak.

Błąd sugeruje aktualizację tabel bazowych, a nie widok. Jak wspomniano w komentarzach: stary i: nowy są twoim przyjacielem.

: Old trzyma wszystkie wartości tabeli Wyzwalacz jest tworzony przed aktualizacją (Null, jeśli wkładka)

: Nowe posiada wszystkie wartości tabeli Wyzwalacz jest tworzony po aktualizacji / wkładce .....

Więc jeśli rozumiem, co chcesz zrobić poprawnie, musisz ...

  1. zadeklarować zmienną, np. v_s1_hover_report

  2. Wykonaj wybrane zwracanie dowolnej wartości, której potrzebujesz do tej zmiennej

  3. Ustaw wartość w tabeli witryny, robiąc

    : New.s1_hover_report: = v_s1_hover_report

Ustawiając tę wartość do: Nowy obiekt, gdy się dzieje, zostanie on popełniony do bazy danych. To całkowicie usuwa potrzebę aktualizacji w spustu.

Możesz także użyć: New.id w wyróżnieniu, aby przefiltrować go do rekordu, w którym aktualizujesz, jeśli jest pomocny

CREATE OR REPLACE TRIGGER MESS.S1_HOVER_REPORT
AFTER INSERT OR UPDATE ON MESS.SITE
FOR EACH ROW

v_test varchar2(10);

BEGIN

select 'Your value' into v_test from dual;

:new.s1_hover_report := v_test;

END;

LUB

CREATE OR REPLACE TRIGGER MESS.S1_HOVER_REPORT
AFTER INSERT OR UPDATE ON MESS.SITE
FOR EACH ROW

v_test varchar2(10);

BEGIN

select 'Your value' into :new.s1_hover_report from dual;

END;
0
Shaun Peterson 20 październik 2020, 19:55