可以用旧的或新的程序调用触发器吗?

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 主键)