防止插入触发器
Prevent Insert Trigger
如何获取此触发器以防止在advance 不大于0 或小于100 的情况下插入?谢谢
DROP TRIGGER CheckAdvance;
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
WHEN (new.advance<0 OR new.advance>100)
BEGIN
dbms_output.put_line('Advance is Invalid.');
END;
你不应该为此使用触发器。 Oracle(和一般的 SQL)支持检查约束:
alter table titles
add constraint chk_titles_advance check (advance > 0 and advance <= 100);
"it was a class question."
我在一次会议上作了演讲后,与教 PL/SQL 的大学讲师聊了聊。我的演讲是关于 PL/SQL 良好实践;我的一张幻灯片只是说“不要使用触发器”。讲师告诉我,他发现这样的建议很难与课程的需要相协调。他们必须教学生所有语法,但他承认,他们经常设置任务,要求我们在专业编写软件时不会使用的解决方案。
这样的问题。正确的做法是使用检查约束,如Gordon's answer shows。约束更有效,也更惯用。但是你的老师要你写一个触发器,所以这是你的代码,已更正。
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
BEGIN
IF :new.advance < 0
THEN
raise_application_error(-20000
, 'Advance cannot be less than zero');
ELSIF :new.advance > 100
THEN
raise_application_error(-20001
, 'Advance cannot be greater than one hundred.');
END IF;
END;
注意事项:
- CREATE OR REPLACE 意味着我们可以在没有初步 DROP 语句的情况下更改触发器代码。
- 代码的 BEGIN 和 END 帧块,例如触发器主体。
静态条件用 IF ... END IF 关键字构成; WHEN 用于退出循环结构。 不完全正确,请参阅下面的更新。
- 使用 :NEW(和 :OLD)关键字引用 table 列值 - 注意冒号。
- 使用RAISE_APPLICATION_ERROR抛出异常;错误号必须在 -20999 到 -20000 范围内,Oracle 为 user-defined 例外保留。
- 让您的错误消息有意义:告诉您的用户他们做错了什么,而不是让他们猜测。
- 学习使用缩进使代码可读。你的未来 co-workers 会感谢你的。
@yadipp 提醒我,搜索者问题中使用的 WHEN 子句是有效的语法,所以我迟早要扩展我的解决方案以展示它的外观。需要注意的最重要的一点是 NEW 和 OLD 不被视为绑定变量,因此不要使用 :
.
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
WHEN (new.advance < 0 OR new.advance > 100)
BEGIN
raise_application_error(-20000
, 'Advance cannot be less than zero or greater than one hundred.');
END;
(我调整了我的原始解决方案以显示在触发器主体中使用 IF 的一个原因:以不同方式处理不同的条件。)
如何获取此触发器以防止在advance 不大于0 或小于100 的情况下插入?谢谢
DROP TRIGGER CheckAdvance;
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
WHEN (new.advance<0 OR new.advance>100)
BEGIN
dbms_output.put_line('Advance is Invalid.');
END;
你不应该为此使用触发器。 Oracle(和一般的 SQL)支持检查约束:
alter table titles
add constraint chk_titles_advance check (advance > 0 and advance <= 100);
"it was a class question."
我在一次会议上作了演讲后,与教 PL/SQL 的大学讲师聊了聊。我的演讲是关于 PL/SQL 良好实践;我的一张幻灯片只是说“不要使用触发器”。讲师告诉我,他发现这样的建议很难与课程的需要相协调。他们必须教学生所有语法,但他承认,他们经常设置任务,要求我们在专业编写软件时不会使用的解决方案。
这样的问题。正确的做法是使用检查约束,如Gordon's answer shows。约束更有效,也更惯用。但是你的老师要你写一个触发器,所以这是你的代码,已更正。
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
BEGIN
IF :new.advance < 0
THEN
raise_application_error(-20000
, 'Advance cannot be less than zero');
ELSIF :new.advance > 100
THEN
raise_application_error(-20001
, 'Advance cannot be greater than one hundred.');
END IF;
END;
注意事项:
- CREATE OR REPLACE 意味着我们可以在没有初步 DROP 语句的情况下更改触发器代码。
- 代码的 BEGIN 和 END 帧块,例如触发器主体。
静态条件用 IF ... END IF 关键字构成; WHEN 用于退出循环结构。不完全正确,请参阅下面的更新。- 使用 :NEW(和 :OLD)关键字引用 table 列值 - 注意冒号。
- 使用RAISE_APPLICATION_ERROR抛出异常;错误号必须在 -20999 到 -20000 范围内,Oracle 为 user-defined 例外保留。
- 让您的错误消息有意义:告诉您的用户他们做错了什么,而不是让他们猜测。
- 学习使用缩进使代码可读。你的未来 co-workers 会感谢你的。
@yadipp 提醒我,搜索者问题中使用的 WHEN 子句是有效的语法,所以我迟早要扩展我的解决方案以展示它的外观。需要注意的最重要的一点是 NEW 和 OLD 不被视为绑定变量,因此不要使用 :
.
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
WHEN (new.advance < 0 OR new.advance > 100)
BEGIN
raise_application_error(-20000
, 'Advance cannot be less than zero or greater than one hundred.');
END;
(我调整了我的原始解决方案以显示在触发器主体中使用 IF 的一个原因:以不同方式处理不同的条件。)