#sql #oracle #triggers
#sql #Oracle #триггеры
Вопрос:
Здравствуйте, я новичок в триггерах в SQL, и мне нужна помощь с одним. Я работаю с 3 таблицами, включающими водителей, автомобильные аварии и страховой полис. То, что я пытаюсь сделать, это создать триггер, который не позволит создавать страховые полисы для водителей, попавших в аварию.
Вот что я пробовал до сих пор:
CREATE TABLE insurance_policy(
id INT,
ssn_driver INT,
expiration_date DATE,
PRIMARY KEY (id)
);
CREATE TABLE accident(
id INT,
ssn_driver INT,
accident_date DATE,
details VARCHAR2(64),
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES insurance_policy,
FOREIGN KEY (ssn_driver) REFERENCES driver
);
CREATE TABLE driver(
ssn_driver INT,
name VARCHAR2(64),
age INT CHECK (age>15),
PRIMARY KEY(ssn_driver)
);
CREATE TRIGGER no_insurance_policy
AFTER INSERT OR UPDATE ON insurance_policy
FOR EACH ROW
BEGIN
IF EXISTS (select ssn_driver FROM Inserted INNER JOIN accident)
BEGIN
rollback transaction
raiserror ('some message', 16, 1)
END
END
Это не компилируется, но я просто не понимаю, как действовать дальше. Кто-нибудь может мне помочь с созданием этого триггера?
РЕДАКТИРОВАТЬ: вот ошибка
Error starting at line : 31 in command -
BEGIN
IF EXISTS (select ssn_driver FROM Inserted INNER JOIN accident)
BEGIN
rollback transaction
raiserror ('some message', 16, 1)
END
END
Error report -
ORA-06550: line 2, column 58:
PLS-00103: Encountered the symbol "JOIN" when expecting one of the following:
) , with group having intersect minus start union where
connect
06550. 00000 - "line %s, column %s:n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Комментарии:
1. Что такое ошибка компиляции? Пожалуйста, вставьте точный текст в свой вопрос.
2. Это совершенно некомпетентная идея встроить логику приложения в базу данных и особенно в триггер. Что, если ваш триггер каким-то образом отключится? Вы должны позволить вашему приложению BLL выполнять эти действия. Если вы действительно решили сделать это на уровне базы данных, вы должны, по крайней мере, выполнять все свои действия внутри хранимой процедуры.
3. @KenY-N Я вставил его в свой пост
4. @T.S. Это для домашнего задания, я действительно не имею права голоса по этому поводу. Это именно то, что меня просят сделать.
5. Это даже не синтаксис oracle
BEGIN IF EXISTS (select ssn_driver FROM Inserted INNER JOIN accident) BEGIN rollback transaction raiserror ('some message', 16, 1) END END
, вы извлекли его с веб-сайта sql server
Ответ №1:
Во-первых, вам нужно BEFORE
не AFTER
вставлять. Тогда ваш синтаксис даже не является Oracle. Вот примерно то, что вам нужно сделать. Я его не тестировал.
CREATE TRIGGER no_insurance_policy
BEFORE INSERT OR UPDATE ON insurance_policy
FOR EACH ROW
DECLARE
v_accidentCout NUMBER(10);
BEGIN
Select Count(*) Into v_accidentCout
From accident
Where ssn_driver = old.ssn_driver;
If v_accidentCout > 0 Then
raise_application_error(-12345, 'Driver has accidents');
End If;
END;
/
Я бы оставил commit
/ rollback
для блока, который вызывает insert
/ update
.