Oracle - CHECK 约束 - 如果不同列中的值不为空,则只允许更改列
Oracle - CHECK Constraint - Only allow column to be changed if value in different column is not null
所以我有以下 table:
CREATE TABLE Projects (
ID INTEGER CONSTRAINT ProjPK PRIMARY KEY,
Column1 VARCHAR2(30) NOT NULL ,
Column2 VARCHAR2(10) NOT NULL ,
Column3 INTEGER NULL ,
Column4 VARCHAR2(20) NULL ,
Column5 INTEGER NOT NULL ,
Column6 INTEGER NULL ,
Column7 DATE NULL
);
我需要为 Column7 提出一个检查约束,它只允许在第 4 列和第 6 列不为 NULL 时将 Column7 更改为不同的值。
我想表达的是,如果第 4 列或第 6 列为 NULL,则第 7 列必须为 NULL,如果第 4 列和第 6 列为 NOT NULL,则分别只能为 NOT NULL。我希望这是有道理的。
任何帮助将不胜感激。
我会说这是触发器的任务。
简化table:
SQL> CREATE TABLE projects
2 (
3 id INTEGER CONSTRAINT projpk PRIMARY KEY,
4 column1 VARCHAR2 (30),
5 column2 VARCHAR2 (10),
6 column3 INTEGER,
7 column4 VARCHAR2 (20),
8 column5 INTEGER,
9 column6 INTEGER,
10 column7 DATE
11 );
Table created.
触发器:
SQL> CREATE OR REPLACE TRIGGER trg_ch7
2 BEFORE UPDATE
3 ON projects
4 FOR EACH ROW
5 BEGIN
6 IF :old.column7 <> :new.column7
7 THEN
8 IF :new.column4 IS NULL
9 AND :new.column6 IS NULL
10 THEN
11 NULL;
12 ELSE
13 raise_application_error (
14 -20000,
15 'Col 7 can not be changed because cols 4 and 6 are not empty');
16 END IF;
17 END IF;
18 END;
19 /
Trigger created.
SQL>
测试:
SQL> INSERT INTO projects (id, column1, column7)
2 VALUES (1, 'test', SYSDATE);
1 row created.
SQL>
SQL> UPDATE projects
2 SET column7 = SYSDATE + 1
3 WHERE id = 1;
1 row updated.
SQL>
SQL> UPDATE projects
2 SET column4 = 'not empty'
3 WHERE id = 1;
1 row updated.
SQL>
SQL> UPDATE projects
2 SET column7 = SYSDATE + 2
3 WHERE id = 1;
UPDATE projects
*
ERROR at line 1:
ORA-20000: Col 7 can not be changed because cols
4 and 6 are not empty
ORA-06512: at "SCOTT.TRG_CH7", line 9
ORA-04088: error during execution of trigger
'SCOTT.TRG_CH7'
SQL>
使用定义限制的简单检查约束
alter table projects add CONSTRAINT check_null
CHECK ( (column4 is null and column6 is null and column7 is null) or
(column4 is not null and column6 is not null and column7 is not null) );
一些测试
第 7 列定义失败,第 4,6 列未定义
INSERT INTO projects (id, column1, column7) VALUES (1, 'fail', SYSDATE);
--ORA-02290: check constraint (xxx.CHECK_NULL) violated
好的,因为所有列都是 NULL
INSERT INTO projects (id, column1, column7) VALUES (1, 'OK', null);
-- 1 row inserted.
.. 或全部定义。
INSERT INTO projects (id, column1,column4, column6, column7) VALUES (2, 'OK','x',1, SYSDATE);
-- 1 row inserted.
注意 从不 使用 触发器 如果简单的 CHECK 约束就足够了。
所以我有以下 table:
CREATE TABLE Projects (
ID INTEGER CONSTRAINT ProjPK PRIMARY KEY,
Column1 VARCHAR2(30) NOT NULL ,
Column2 VARCHAR2(10) NOT NULL ,
Column3 INTEGER NULL ,
Column4 VARCHAR2(20) NULL ,
Column5 INTEGER NOT NULL ,
Column6 INTEGER NULL ,
Column7 DATE NULL
);
我需要为 Column7 提出一个检查约束,它只允许在第 4 列和第 6 列不为 NULL 时将 Column7 更改为不同的值。
我想表达的是,如果第 4 列或第 6 列为 NULL,则第 7 列必须为 NULL,如果第 4 列和第 6 列为 NOT NULL,则分别只能为 NOT NULL。我希望这是有道理的。 任何帮助将不胜感激。
我会说这是触发器的任务。
简化table:
SQL> CREATE TABLE projects
2 (
3 id INTEGER CONSTRAINT projpk PRIMARY KEY,
4 column1 VARCHAR2 (30),
5 column2 VARCHAR2 (10),
6 column3 INTEGER,
7 column4 VARCHAR2 (20),
8 column5 INTEGER,
9 column6 INTEGER,
10 column7 DATE
11 );
Table created.
触发器:
SQL> CREATE OR REPLACE TRIGGER trg_ch7
2 BEFORE UPDATE
3 ON projects
4 FOR EACH ROW
5 BEGIN
6 IF :old.column7 <> :new.column7
7 THEN
8 IF :new.column4 IS NULL
9 AND :new.column6 IS NULL
10 THEN
11 NULL;
12 ELSE
13 raise_application_error (
14 -20000,
15 'Col 7 can not be changed because cols 4 and 6 are not empty');
16 END IF;
17 END IF;
18 END;
19 /
Trigger created.
SQL>
测试:
SQL> INSERT INTO projects (id, column1, column7)
2 VALUES (1, 'test', SYSDATE);
1 row created.
SQL>
SQL> UPDATE projects
2 SET column7 = SYSDATE + 1
3 WHERE id = 1;
1 row updated.
SQL>
SQL> UPDATE projects
2 SET column4 = 'not empty'
3 WHERE id = 1;
1 row updated.
SQL>
SQL> UPDATE projects
2 SET column7 = SYSDATE + 2
3 WHERE id = 1;
UPDATE projects
*
ERROR at line 1:
ORA-20000: Col 7 can not be changed because cols
4 and 6 are not empty
ORA-06512: at "SCOTT.TRG_CH7", line 9
ORA-04088: error during execution of trigger
'SCOTT.TRG_CH7'
SQL>
使用定义限制的简单检查约束
alter table projects add CONSTRAINT check_null
CHECK ( (column4 is null and column6 is null and column7 is null) or
(column4 is not null and column6 is not null and column7 is not null) );
一些测试
第 7 列定义失败,第 4,6 列未定义
INSERT INTO projects (id, column1, column7) VALUES (1, 'fail', SYSDATE);
--ORA-02290: check constraint (xxx.CHECK_NULL) violated
好的,因为所有列都是 NULL
INSERT INTO projects (id, column1, column7) VALUES (1, 'OK', null);
-- 1 row inserted.
.. 或全部定义。
INSERT INTO projects (id, column1,column4, column6, column7) VALUES (2, 'OK','x',1, SYSDATE);
-- 1 row inserted.
注意 从不 使用 触发器 如果简单的 CHECK 约束就足够了。