使用子查询的Oracle触发器语法

时间:2018-05-10 01:33:25

标签: sql oracle triggers

我正在尝试在Oracle语法中编写一个触发器,在输入到特定表的一行时,检查输入的两个值是否属于另一个表中保存的某个分类。我最初的想法是在包含子查询的表上有一个约束,但Oracle似乎不喜欢这样。

我在下面写的选择查询有效 - 但我不确定如何将它放入触发器 - 但实质上我需要触发器来确保EW1.OrgId和EW2.OrgId是相同的。任何帮助表示赞赏!

CREATE TABLE Organisation (
OrgId INTEGER PRIMARY KEY,
Name VARCHAR(40) NOT NULL
);

CREATE TABLE Person  (
PersonId INTEGER PRIMARY KEY,
FirstName VARCHAR(45) NOT NULL,
LastName VARCHAR(45) NOT NULL
);

CREATE TABLE Employee (
PersonId INTEGER PRIMARY KEY REFERENCES PERSON (PersonId) ON DELETE CASCADE
);

CREATE TABLE Manager (
PersonId INTEGER PRIMARY KEY REFERENCES PERSON (PersonId) ON DELETE CASCADE
);

CREATE TABLE EnlistedWith (
OrgId INTEGER REFERENCES ORGANISATION (OrgId) ON DELETE CASCADE,
PersonId INTEGER REFERENCES PERSON (PersonId) ON DELETE CASCADE,
PRIMARY KEY(OrgId,PersonId)
);

CREATE TABLE SupervisedBy (
EmployeeId INTEGER REFERENCES Employee (PersonId) ON DELETE CASCADE,
ManagerId INTEGER REFERENCES Manager (PersonId) ON DELETE CASCADE,
CONSTRAINT PK_SupervisedBy PRIMARY KEY (EmployeeId, ManagerId)
);

CREATE TRIGGER SupervisorCompany 
AFTER INSERT ON SupervisedBy
   FOR EACH ROW
     BEGIN
       declare qty INTEGER := 0;
            BEGIN
            SELECT COUNT (*) into qty
        FROM SupervisedBy SB
        INNER JOIN EnlistedWith EW1 ON SB.ManagerId = EW1.PersonId
        INNER JOIN EnlistedWith EW2 ON SB.EmployeeId = EW2.PersonId
        and EW1.OrgId <> EW2.OrgId
        IF qty <> 0
        then Raise_Error (1234567, 'Manager and Employee are not Enlisted with same Organisation');
            END IF;
        END;
END;

2 个答案:

答案 0 :(得分:1)

您可以使用:NEW / :OLD来引用触发器所有者的列。因此,您的触发器可以重写为

CREATE OR REPLACE TRIGGER supervisorcompany AFTER 
INSERT 
ON supervisedby FOR EACH ROW 
 DECLARE qty INTEGER := 0; 
BEGIN 
  SELECT count (*) 
  INTO   qty 
  FROM   enlistedwith ew1 
  WHERE  ew1.personid = :NEW.managerid 
  AND    EXISTS 
         ( 
                SELECT 1 
                FROM   enlistedwith ew2 
                WHERE  ew2.personid = :NEW.employeeid 
                AND    ew1.orgid <> ew2.orgid ) ;
IF qty <> 0 THEN 
   raise_application_error (1234567, 'Manager and Employee are not Enlisted with same Organisation');
END IF; 
END;
/

答案 1 :(得分:0)

涉及一些猜测......也许是这样的事情

CREATE TRIGGER SupervisorCompany 
               AFTER INSERT
               ON SupervisedBy
                  FOR EACH ROW
BEGIN
  IF (SELECT OrgId
             FROM EnlistedWith
             WHERE PersonId = New.ManagerId)
     <>
     (SELECT OrgId
             FROM EnlistedWith
             WHERE PersonId = New.EmployeeId) THEN
    RAISE_ERROR(1234567, 'Manager and Employee are not Enlisted with same Organisation');
  END IF;
END;

你想要什么?它会检查OrgId等于新输入的PersonId的行的ManagerId是否与新输入的EmployeeId相同。如果没有,则会引发错误。

(未经测试,因为没有提供表格的DDL。)