可以用旧的或新的程序调用触发器吗?
It is possible to call trigger with old, or new in procedure?
我想使用程序插入数据。起初我想插入比赛,但足球比赛的 id 是使用触发器自动生成的。其次,我想将此 ID 用于其他 table - stats_footballmatch_club。有可能吗?
INSERT INTO FootballMatch(FootballMatch_Date, Stadium_Id, Tournament_Id) VALUES(TO_DATE('02-04-22','DD-MM-YY'), 1, 1);
INSERT INTO STATS_FOOTBALLMATCH_CLUB(FootballMatch_Id, Club_Id , Goals, Shots, BallControl, Pass) VALUES (1, 1, 0, 0, 0, 0);
INSERT INTO STATS_FOOTBALLMATCH_CLUB(FootballMatch_Id, Club_Id , Goals, Shots, BallControl, Pass) VALUES (1, 2, 0, 0, 0, 0);
例如,如果我的触发器名称是 FOOTBALLMATCHTRIGGER,我可以这样做吗?
INSERT INTO STATS_FOOTBALLMATCH_CLUB(FootballMatch_Id, Club_Id , Goals, Shots, BallControl, Pass) VALUES (FOOTBALLMATCHTRIGGER:new, 2, 0, 0, 0, 0);
这是足球比赛的触发器:
CREATE OR REPLACE TRIGGER FootballMatchTrigger
BEFORE INSERT
ON FootballMatch
FOR EACH ROW
BEGIN
if :NEW.FootballMatch_Id is null then
SELECT FootballMatchIdSequence.NEXTVAL
INTO :new.FootballMatch_Id
FROM dual;
end if;
END;
还有一场足球赛table:
CREATE TABLE FootballMatch(
FootballMatch_Id NUMBER(4) PRIMARY KEY,
FootballMatch_Date DATE,
Stadium_Id NUMBER(4) REFERENCES Stadium(Stadium_Id) on delete cascade,
Tournament_Id NUMBER(4) REFERENCES Tournament(Tournament_Id) on delete cascade
);
它也指其他 tables,如体育场和锦标赛。
简短回答:不,你不能为此使用触发器。无法在代码中引用触发器。
解决方案:使用RETURNING INTO
子句。
简化示例:
DROP TABLE stats_footballmatch_club;
DROP TABLE footballmatch;
DROP SEQUENCE footballmatch_s;
CREATE TABLE footballmatch(
footballmatch_id NUMBER(4) PRIMARY KEY,
footballmatch_date DATE
);
CREATE SEQUENCE footballmatch_s;
CREATE OR REPLACE TRIGGER footballmatch_bi BEFORE
INSERT ON footballmatch
FOR EACH ROW
BEGIN
:new.footballmatch_id := footballmatch_s.nextval;
END footballmatch_bi;
/
CREATE TABLE stats_footballmatch_club(
stats_id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY,
goals NUMBER,
club VARCHAR2(100),
footballmatch_id NUMBER(4) REFERENCES footballmatch(footballmatch_id) on delete cascade
);
DECLARE
l_footballmatch_id footballmatch.footballmatch_id%TYPE;
BEGIN
INSERT INTO footballmatch(footballmatch_date) VALUES(TO_DATE('02-04-22','DD-MM-YY'))
RETURNING footballmatch_id INTO l_footballmatch_id;
INSERT INTO stats_footballmatch_club (footballmatch_id, goals, club) VALUES (l_footballmatch_id,3, 'Real Madrid');
INSERT INTO stats_footballmatch_club (footballmatch_id, goals, club) VALUES (l_footballmatch_id,2, 'PSG');
END;
/
备注:
- 不需要
SELECT INTO
分配sequence.NEXTVAL。只需使用 := sequence.NEXTVAL
分配
- 甚至不需要主键的触发器 - 标识列要方便得多(参见 table stats_footballmatch_club 主键)
我想使用程序插入数据。起初我想插入比赛,但足球比赛的 id 是使用触发器自动生成的。其次,我想将此 ID 用于其他 table - stats_footballmatch_club。有可能吗?
INSERT INTO FootballMatch(FootballMatch_Date, Stadium_Id, Tournament_Id) VALUES(TO_DATE('02-04-22','DD-MM-YY'), 1, 1);
INSERT INTO STATS_FOOTBALLMATCH_CLUB(FootballMatch_Id, Club_Id , Goals, Shots, BallControl, Pass) VALUES (1, 1, 0, 0, 0, 0);
INSERT INTO STATS_FOOTBALLMATCH_CLUB(FootballMatch_Id, Club_Id , Goals, Shots, BallControl, Pass) VALUES (1, 2, 0, 0, 0, 0);
例如,如果我的触发器名称是 FOOTBALLMATCHTRIGGER,我可以这样做吗?
INSERT INTO STATS_FOOTBALLMATCH_CLUB(FootballMatch_Id, Club_Id , Goals, Shots, BallControl, Pass) VALUES (FOOTBALLMATCHTRIGGER:new, 2, 0, 0, 0, 0);
这是足球比赛的触发器:
CREATE OR REPLACE TRIGGER FootballMatchTrigger
BEFORE INSERT
ON FootballMatch
FOR EACH ROW
BEGIN
if :NEW.FootballMatch_Id is null then
SELECT FootballMatchIdSequence.NEXTVAL
INTO :new.FootballMatch_Id
FROM dual;
end if;
END;
还有一场足球赛table:
CREATE TABLE FootballMatch(
FootballMatch_Id NUMBER(4) PRIMARY KEY,
FootballMatch_Date DATE,
Stadium_Id NUMBER(4) REFERENCES Stadium(Stadium_Id) on delete cascade,
Tournament_Id NUMBER(4) REFERENCES Tournament(Tournament_Id) on delete cascade
);
它也指其他 tables,如体育场和锦标赛。
简短回答:不,你不能为此使用触发器。无法在代码中引用触发器。
解决方案:使用RETURNING INTO
子句。
简化示例:
DROP TABLE stats_footballmatch_club;
DROP TABLE footballmatch;
DROP SEQUENCE footballmatch_s;
CREATE TABLE footballmatch(
footballmatch_id NUMBER(4) PRIMARY KEY,
footballmatch_date DATE
);
CREATE SEQUENCE footballmatch_s;
CREATE OR REPLACE TRIGGER footballmatch_bi BEFORE
INSERT ON footballmatch
FOR EACH ROW
BEGIN
:new.footballmatch_id := footballmatch_s.nextval;
END footballmatch_bi;
/
CREATE TABLE stats_footballmatch_club(
stats_id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY,
goals NUMBER,
club VARCHAR2(100),
footballmatch_id NUMBER(4) REFERENCES footballmatch(footballmatch_id) on delete cascade
);
DECLARE
l_footballmatch_id footballmatch.footballmatch_id%TYPE;
BEGIN
INSERT INTO footballmatch(footballmatch_date) VALUES(TO_DATE('02-04-22','DD-MM-YY'))
RETURNING footballmatch_id INTO l_footballmatch_id;
INSERT INTO stats_footballmatch_club (footballmatch_id, goals, club) VALUES (l_footballmatch_id,3, 'Real Madrid');
INSERT INTO stats_footballmatch_club (footballmatch_id, goals, club) VALUES (l_footballmatch_id,2, 'PSG');
END;
/
备注:
- 不需要
SELECT INTO
分配sequence.NEXTVAL。只需使用:= sequence.NEXTVAL
分配
- 甚至不需要主键的触发器 - 标识列要方便得多(参见 table stats_footballmatch_club 主键)