ORACLE触发器,而不是在具有嵌套表的视图上插入

ORACLE触发器,而不是在具有嵌套表的视图上插入,oracle,view,triggers,Oracle,View,Triggers,我必须写一个触发器。它编译所有内容,但如果我想在视图中插入某些内容,就会收到一条错误消息。也许你能帮我 SET DEFINE off; CREATE OR REPLACE TRIGGER LieferantOV_trig INSTEAD OF INSERT ON LIEFERANT_OV FOR EACH ROW BEGIN IF INSERTING THEN INSERT INTO Lieferant (LiefNr, Name, Adresse) VALUES(:new.

我必须写一个触发器。它编译所有内容,但如果我想在视图中插入某些内容,就会收到一条错误消息。也许你能帮我

SET DEFINE off;
CREATE OR REPLACE TRIGGER LieferantOV_trig

INSTEAD OF INSERT
ON LIEFERANT_OV
FOR EACH ROW
BEGIN 
  IF INSERTING THEN
  INSERT INTO Lieferant (LiefNr, Name, Adresse)  
  VALUES(:new.LiefNr, :new.Name, ntTAdresse());

  INSERT INTO TABLE (SELECT Adresse FROM Lieferant  ) VALUES
  (TAdresse(:new.Straße, :new.PLZ, :new.Ort));

  END IF;
  END;

INSERT INTO Lieferant_OV 
VALUES(752443, 'Laepple Teublitz', 'Maxstr. 12', '93158', 'Teublitz');
对于嵌套表

CREATE OR REPLACE TYPE TAdresse AS OBJECT(
Straße VARCHAR2(50),
PLZ VARCHAR2(5),
Ort VARCHAR2(50)
);



CREATE TABLE Lieferant(
LiefNr number(6) PRIMARY KEY,
Name varchar2(20) NOT NULL
);
1.
CREATE OR REPLACE TYPE ntTAdresse AS TABLE OF TAdresse;
2.
ALTER TABLE Lieferant ADD Adresse ntTAdresse NESTED TABLE Adresse STORE AS TAdresseNT;


CREATE OR REPLACE VIEW Lieferant_OV (LiefNr, Name, Straße, PLZ, ORT) 
AS SELECT k.LiefNr, k.Name, l.Straße, l.PLZ, l.Ort 
FROM Lieferant k, table(k.Adresse) l;

我认为,如果希望每次插入都保留一行,则需要这样做

CREATE OR REPLACE TRIGGER LieferantOV_trig

INSTEAD OF INSERT
ON LIEFERANT_OV
FOR EACH ROW
BEGIN
  INSERT INTO Lieferant (LiefNr, Name, Adresse)  
  VALUES(:new.LiefNr, :new.Name, ntTAdresse(TAdresse(:new.Straße, :new.PLZ, :new.Ort)));
END;
/

如果ADRESE列只包含一个Adress,则此操作有效。但这不是嵌套表的用途。因此,您可能需要检查表中是否存在具有给定LiefNr的现有行。如果是,则仅插入嵌套表。

语法如下:

CREATE OR REPLACE TRIGGER LieferantOV_trig
   INSTEAD OF INSERT
   ON LIEFERANT_OV
   FOR EACH ROW
BEGIN 
   INSERT INTO Lieferant (LiefNr, Name, Adresse)  
   VALUES(:new.LiefNr, :new.Name, ntTAdresse(TAdresse(:new.Straße,:new.PLZ,:new.ORT));

END;
如果插入,则可以跳过
,因为触发器仅在
INSERT

注意,这样每个记录最多只有一个地址,因此嵌套表没有多大意义

要向现有Lieferant添加地址,您可以执行以下操作:

CREATE OR REPLACE TRIGGER LieferantOV_trig
   INSTEAD OF INSERT
   ON LIEFERANT_OV
   FOR EACH ROW

DECLARE
   lieferantCount INTEGER;
BEGIN 

   select count(*) 
   into lieferantCount 
   from Lieferant 
   where LiefNr = :new.LiefNr
       and Name = :new.Name;

   if lieferantCount = 0 then
      INSERT INTO Lieferant (LiefNr, Name, Adresse)  
      VALUES(:new.LiefNr, :new.Name, ntTAdresse(TAdresse(:new.Straße,:new.PLZ,:new.ORT)));
   else
      UPDATE Lieferant 
      SET Adresse = Adresse MULTISET UNION ntTAdresse(TAdresse(:new.Straße,:new.PLZ,:new.ORT))
      WHERE LiefNr = :new.LiefNr
         and Name = :new.Name;
   end if;

END;

你有什么错误?嘿,我又加了一点代码。得到这个错误:SQL-error:ORA-04098:Trigger'S74040。LIEFERANT_OV_TRIG's ungültig and konnte nicht neu bestätigt werden 04098。00000-“触发器'%s.%s'无效,重新验证失败”是否要插入一行?是的,先生。如果我在没有触发器的情况下插入它,它会工作。如果您已经有了752443 LeifNr的行,会怎么样?要更新行吗?好的,谢谢。否此触发器在此窗体中编译时也没有错误。我有这个几乎一样。但如果我在视图中插入一行,我也会得到一个错误:插入Lieferant_OV值(752443,'Laepple Teublitz','Maxstr.12','93158','Teublitz');