Синтаксис триггера Oracle с использованием подзапроса - PullRequest
0 голосов
/ 10 мая 2018

Я пытаюсь написать триггер в синтаксисе 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 голосов
/ 10 мая 2018

Вы можете обратиться к столбцам владельца триггера, используя :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;
/
0 голосов
/ 10 мая 2018

Есть некоторые догадки ... Может быть, что-то вроде этого

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 для таблиц.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...