从另一个 table 查找触发
Trigger with lookup from another table
我正在学习 PL/SQL 专门的触发器,我想学习如何使用触发器对多个 table 进行操作,但我无法理解该过程。这是一个例子:
CREATE TABLE Sess
(code INTEGER NOT NULL,
dateStart DATE NOT NULL,
dateEnd DATE NOT NULL,
CONSTRAINT KeySess PRIMARY KEY(code)
)
CREATE TABLE Ins
(codeIns CHAR(12) NOT NULL,
code INTEGER NOT NULL,
dateIns DATE NOT NULL,
dateAb DATE,
note INTEGER,
CONSTRAINT KeyIns PRIMARY KEY (codeIns, code)
)
1/ 我正在尝试构建一个触发器来确保这一点:
before Insert or Update Ins
dateAb is between dateStart and dateEnd
2/ 我也想 ALTER TABLE
并锁定代码,并在 Ins 中输入代码,这样就没人可以更新它们了,但我不知道命令。
对于第一个触发器,我尝试了类似的方法:
CREATE OR REPLACE TRIGGER test
BEFORE INSERT OR UPDATE OF dateAb ON Ins
FOR EACH ROW
DECLARE
start date;
BEGIN
SELECT DISTINCT s.dateStart INTO start
WHERE Ins.code = s.code
IF (:NEW.dateAb < start) THEN
raise_application_error(-20101,'dateAb incorrect');
END IF;
END;
注意:我没有声明一个变量 end 来检查它是否介于两者之间,我在这里的目的是测试正确的语法
注2:table为空。
我有 Warning: Trigger created with compilation errors.
和 3 个错误:
PL/SQL: SQL Statement ignored
4/40 PL/SQL: ORA-00923: key-word FROM absent
9/5 PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
最后就像我说的那样,我不知道在 table 上锁定列以防止更新或可能的正确语法。
我正在学习,所以如果你们中的一位可以教我正确的方法来处理我的两个请求,我将不胜感激。
谢谢
PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
此错误是因为您在 select 语句
之后缺少 ;
试试这个:
create or replace trigger test
before insert or update of dateab on ins
for each row
declare
l_sess_start date;
begin
select s.datestart into l_sess_start
from sess s
where s.code = :new.code;
if :new.dateab < l_sess_start then
raise_application_error
( -20101
, 'Start date ' || to_char(:new.dateab,'DD-MON-YYYY') ||
' cannot be before ' || to_char(l_sess_start,'DD-MON-YYYY'));
end if;
end;
测试:
insert into sess values (1, date '2018-04-22', date '2018-04-30');
insert into ins values ('Z', 1, date '2018-04-01', date '2018-04-01', null);
ERROR at line 1:
ORA-20101: Start date 01-APR-2018 cannot be before 22-APR-2018
ORA-06512: at "WILLIAM.TEST", line 10
ORA-04088: error during execution of trigger 'WILLIAM.TEST'
我正在学习 PL/SQL 专门的触发器,我想学习如何使用触发器对多个 table 进行操作,但我无法理解该过程。这是一个例子:
CREATE TABLE Sess
(code INTEGER NOT NULL,
dateStart DATE NOT NULL,
dateEnd DATE NOT NULL,
CONSTRAINT KeySess PRIMARY KEY(code)
)
CREATE TABLE Ins
(codeIns CHAR(12) NOT NULL,
code INTEGER NOT NULL,
dateIns DATE NOT NULL,
dateAb DATE,
note INTEGER,
CONSTRAINT KeyIns PRIMARY KEY (codeIns, code)
)
1/ 我正在尝试构建一个触发器来确保这一点:
before Insert or Update Ins
dateAb is between dateStart and dateEnd
2/ 我也想 ALTER TABLE
并锁定代码,并在 Ins 中输入代码,这样就没人可以更新它们了,但我不知道命令。
对于第一个触发器,我尝试了类似的方法:
CREATE OR REPLACE TRIGGER test
BEFORE INSERT OR UPDATE OF dateAb ON Ins
FOR EACH ROW
DECLARE
start date;
BEGIN
SELECT DISTINCT s.dateStart INTO start
WHERE Ins.code = s.code
IF (:NEW.dateAb < start) THEN
raise_application_error(-20101,'dateAb incorrect');
END IF;
END;
注意:我没有声明一个变量 end 来检查它是否介于两者之间,我在这里的目的是测试正确的语法
注2:table为空。
我有 Warning: Trigger created with compilation errors.
和 3 个错误:
PL/SQL: SQL Statement ignored
4/40 PL/SQL: ORA-00923: key-word FROM absent
9/5 PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
最后就像我说的那样,我不知道在 table 上锁定列以防止更新或可能的正确语法。
我正在学习,所以如果你们中的一位可以教我正确的方法来处理我的两个请求,我将不胜感激。 谢谢
PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
此错误是因为您在 select 语句
之后缺少;
试试这个:
create or replace trigger test
before insert or update of dateab on ins
for each row
declare
l_sess_start date;
begin
select s.datestart into l_sess_start
from sess s
where s.code = :new.code;
if :new.dateab < l_sess_start then
raise_application_error
( -20101
, 'Start date ' || to_char(:new.dateab,'DD-MON-YYYY') ||
' cannot be before ' || to_char(l_sess_start,'DD-MON-YYYY'));
end if;
end;
测试:
insert into sess values (1, date '2018-04-22', date '2018-04-30');
insert into ins values ('Z', 1, date '2018-04-01', date '2018-04-01', null);
ERROR at line 1:
ORA-20101: Start date 01-APR-2018 cannot be before 22-APR-2018
ORA-06512: at "WILLIAM.TEST", line 10
ORA-04088: error during execution of trigger 'WILLIAM.TEST'