Oracle 使用触发器屏蔽数据

Oracle masking data using a trigger

我正在尝试创建一个屏蔽数据的进程。当我创建触发器时出现错误。

ORA-04072: 触发器类型无效

我不确定为什么,希望有人能解释问题是什么以及如何解决。

最终结果是,当用户查询卡片时,他们应该看到屏蔽的数据,而当他们查询 CARDS_TBL 时,他们应该看到所有数据(未屏蔽)


Original implementation 

  CREATE TABLE CARDS (
    CARD_ID NUMBER
    GENERATED BY DEFAULT AS IDENTITY,
  CARD_STR VARCHAR2(16) NOT NULL,
  PRIMARY KEY (CARD_ID)
);

INSERT INTO CARDS(CARD_STR) VALUES('4024007187788590');
INSERT INTO CARDS(CARD_STR) VALUES('5432223398564536');
INSERT INTO CARDS(CARD_STR) VALUES('5430445512530934');
INSERT INTO CARDS(CARD_STR) VALUES('4020156755227854');
INSERT INTO CARDS(CARD_STR) VALUES('5431248766892318');

CREATE OR REPLACE VIEW CARDS_V AS
  SELECT
    CARD_ID,
    REGEXP_REPLACE(CARD_STR, '(^\d{3})(.*)(\d{4}$)', '**********') AS CARD_STR
  FROM CARDS;

CREATE OR REPLACE TRIGGER CARDS_TRG_INSERT INSTEAD OF
  INSERT ON CARDS_V
  FOR EACH ROW
BEGIN
  INSERT INTO CARDS (CARD_STR) VALUES (:NEW.CARD_STR);
END;

INSERT INTO CARDS_V (CARD_STR) VALUES ('4011589733550908');

CREATE OR REPLACE TRIGGER CARDS_TRG_UPDATE INSTEAD OF
  UPDATE ON CARDS_V
  FOR EACH ROW
BEGIN
  UPDATE CARDS
  SET CARD_STR = :NEW.CARD_STR
  WHERE CARD_ID = :OLD.CARD_ID;
END;



CREATE TABLE CARDS_TBL (
  CARD_ID NUMBER
    GENERATED BY DEFAULT AS IDENTITY,
  CARD_STR VARCHAR2(16) NOT NULL,
  PRIMARY KEY (CARD_ID)
);

INSERT INTO CARDS_TBL(CARD_STR) VALUES('4024007187788590');
INSERT INTO CARDS_TBL(CARD_STR) VALUES('5432223398564536');
INSERT INTO CARDS_TBL(CARD_STR) VALUES('5430445512530934');
INSERT INTO CARDS_TBL(CARD_STR) VALUES('4020156755227854');
INSERT INTO CARDS_TBL(CARD_STR) VALUES('5431248766892318');


CREATE OR REPLACE VIEW CARDS AS
  SELECT
    CARD_ID,
    REGEXP_REPLACE(CARD_STR, '(^\d{3})(.*)(\d{4}$)', '**********') AS CARD_STR
  FROM CARDS_TBL;

CREATE OR REPLACE TRIGGER CARDS_TBL_TRG_UPDATE  BEFORE UPDATE ON CARDS_TBL 
FOR EACH ROW
BEGIN
  UPDATE CARDS_TBL
  SET CARD_STR = :NEW.CARD_STR
  WHERE CARD_ID = :OLD.CARD_ID;
END;
/

CREATE OR REPLACE TRIGGER CARDS_TBL_TRG_INSERT  BEFORE INSERT ON CARDS 
 FOR EACH ROW
BEGIN
  INSERT INTO CARDS_TBL (CARD_STR) VALUES (:NEW.CARD_STR);
END;


INSERT INTO CARDS_TBL (CARD_STR) VALUES ('2222333344445555');

SELECT * FROM CARDS_TBL;

UPDATE CARDS_TBL 
  SET CARD_STR = '2222333344445566'
  WHERE CARD_ID = 6;
/

SELECT * FROM CARDS;

至少在这个特定示例中,触发器 CARDS_TBL_TRG_UPDATE 不执行任何操作(除了引发 MUTATING TABLE 异常)并且可以免除。摆脱它,您的示例将按预期运行。 See this db<>fiddle