我正在尝试创建一个触发器,仅允许用户在第一次插入后将相同的值插入到列中。例如,在下表中,用户输入了姓名 = Jake 和年龄 = 29。
姓名 | 年龄 |
---|---|
杰克 | 29 |
从现在开始,名称列上的触发器现在应该只允许用户输入 Name = Jake。
姓名 | 年龄 |
---|---|
杰克 | 29 |
杰克 | 36 |
下面的代码是我尝试过的,但我收到了 ORA-04091 错误,但我想这是因为我在触发器中引用了表本身?虽然我也不确定
CREATE TRIGGER my_table
BEFORE INSERT OR UPDATE OF name ON my_table
FOR EACH ROW
DECLARE
a_CurrName VARCHAR2(20BYTE);
BEGIN
SELECT name INTO a_CurrName FROM my_table WHERE ROWNUM=1;
IF a_CurrName IS NOT NULL THEN
IF :new.name != a_CurrName
THEN
RAISE_APPLICATION_ERROR( -20001, 'This table can only hold one unique name at any point' );
END IF;
END IF;
END;
用例是特定的,并且插入只能手动完成(即一次一条记录)
如果是这样,那么这可能适用于这个特定的用例。
样本表:
SQL> CREATE TABLE test
2 (
3 name VARCHAR2 (20) NOT NULL,
4 age NUMBER
5 );
Table created.
触发:
SQL> CREATE OR REPLACE TRIGGER trg_biu_test
2 BEFORE INSERT OR UPDATE
3 ON test
4 FOR EACH ROW
5 DECLARE
6 l_name test.name%TYPE;
7 BEGIN
8 SELECT MAX (t.name)
9 INTO l_name
10 FROM test t
11 WHERE ROWNUM = 1;
12
13 IF :new.name <> l_name
14 THEN
15 raise_application_error (
16 -20001,
17 'This table can only hold one unique name at any point, and that''s ' || l_name);
18 END IF;
19 END;
20 /
Trigger created.
测试:
SQL> INSERT INTO test (name, age) VALUES ('Jake', 29);
1 row created.
根据要求,从现在开始只允许Jake的:
SQL> INSERT INTO test (name, age) VALUES ('Jake', 36);
1 row created.
我可以插入其他人吗?否:
SQL> INSERT INTO test (name, age) VALUES ('Mike', 18);
INSERT INTO test (name, age) VALUES ('Mike', 18)
*
ERROR at line 1:
ORA-20001: This table can only hold one unique name at any point, and that's
Jake
ORA-06512: at "SCOTT.TRG_BIU_TEST", line 11
ORA-04088: error during execution of trigger 'SCOTT.TRG_BIU_TEST'
但是,如果您所说的并不完全正确,并且有人一次输入多于一行,您将会收到一个变异表错误(尽管只插入了 Jake):
SQL> INSERT INTO test (name, age)
2 SELECT 'Jake', 50 FROM DUAL
3 UNION ALL
4 SELECT 'Jake', 60 FROM DUAL;
INSERT INTO test (name, age)
*
ERROR at line 1:
ORA-04091: table SCOTT.TEST is mutating, trigger/function may not see it
ORA-06512: at "SCOTT.TRG_BIU_TEST", line 4
ORA-04088: error during execution of trigger 'SCOTT.TRG_BIU_TEST'
SQL>