plsql - PLSQL - 创建触发器抛出错误
问题描述
我有一个需要为其生成触发器的表。下面是我的代码:
CREATE OR REPLACE EDITIONABLE TRIGGER "MYUSER"."REGISTRATION_TRG" BEFORE
INSERT ON REGISTRATIONS FOR EACH ROW BEGIN <<COLUMN_SEQUENCES>> BEGIN IF INSERTING
AND :NEW.REGISTRATIONID IS NULL THEN
SELECT REGISTRATIONS_SEQ.NEXTVAL
INTO :NEW.REGISTRATIONID
FROM SYS.DUAL;
END IF;
END COLUMN_SEQUENCES;
END;
当我运行它时,我收到以下错误:
Error starting at line 0 in command:
CREATE OR REPLACE EDITIONABLE TRIGGER "MYUSER"."REGISTRATIONS_TRG" BEFORE
INSERT ON REGISTRATIONS FOR EACH ROW BEGIN <<COLUMN_SEQUENCES>> BEGIN IF INSERTING
AND :NEW.REGISTRATIONID IS NULL THEN
SELECT REGISTRATIONS_SEQ.NEXTVAL
INTO :NEW.REGISTRATIONID
FROM SYS.DUAL
Error report:
SQL Command: CREATE OR REPLACE EDITIONABLE
Failed: Warning: execution completed with warning
Error starting at line 7 in command:
END IF
Error report:
Unknown Command
Error starting at line 8 in command:
END COLUMN_SEQUENCES
Error report:
Unknown Command
Error starting at line 9 in command:
END
Error report:
Unknown Command
我究竟做错了什么?
谢谢!
解决方案
首先,它适用于 SQL*Plus 和 PL/SQL Developer:
create table registrations(registrationid integer);
create sequence registrations_seq;
CREATE OR REPLACE EDITIONABLE TRIGGER "REGISTRATION_TRG" BEFORE
INSERT ON REGISTRATIONS FOR EACH ROW BEGIN <<COLUMN_SEQUENCES>> BEGIN IF INSERTING
AND :NEW.REGISTRATIONID IS NULL THEN
SELECT REGISTRATIONS_SEQ.NEXTVAL
INTO :NEW.REGISTRATIONID
FROM SYS.DUAL;
END IF;
END COLUMN_SEQUENCES;
END;
/
(我删除"MYUSER"
是因为我没有使用该名称的用户帐户。)
但是,您可以稍微简化一下。首先,用任何语言整齐地布置代码是值得的,所以第一步是:
create or replace editionable trigger registration_trg
before insert on registrations
for each row
begin
<<column_sequences>>
begin
if inserting and :new.registrationid is null then
select registrations_seq.nextval into :new.registrationid
from sys.dual;
end if;
end column_sequences;
end;
然后,
- 如果它是唯一的块,则不需要命名块。
- 这是一个插入触发器,因此您无需测试
if inserting
. - 在同一列中允许生成的值和用户输入的值是灾难的秘诀,但如果必须,您可以将其定义为
when
触发器规范中的条件。 - PL/SQL 语言有一个赋值运算符
:=
,因此您无需查询即可为变量赋值。
那么为什么不简单地:
create or replace trigger registration_trg
before insert on registrations
for each row
when (new.registrationid is null)
begin
:new.registrationid := registrations_seq.nextval;
end;
更简单地说,从 Oracle 12.1 开始,您甚至不需要触发器:
drop table registrations;
create table registrations (id integer generated always as identity);
insert into registrations values (default);
select * from registrations;
ID
----------
1
推荐阅读
- python - 如何在 pysctp 库中使用 sctpsocket_udp 类
- c# - 使用公司文件与另一台机器连接 QBFC C#
- typescript - 来自 Vue 插件(comp lib)的组件注册但不会挂载
- firebase - firebase 身份验证将其用户的 displayName 存储在哪里?
- node.js - Why can't I access req.body with multer?
- boost - 如何将 boost::posix_time::ptime 转换为 YYMMDDHHMM?
- java - Mapbox Android SymbolLayer Reset Filter
- c# - Where do you add a link to CSS in a default ASP.NET Web Form?
- arrays - MongoDB循环:从变量中保存数据?
- css - How to change ::after of child element