例如,说我有类似的东西
CREATE TABLE COMPANY(id int not null primary key, ...);
CREATE TABLE DEPARTMENT(id int not null primary key, company_id int not null,
CONSTRAINT FK_DEP_COMPANY_ID FOREIGN KEY(company_id) REFERENCES COMPANY(id),...);
CREATE TABLE EMPLOYEE(id int not null primary key, department_id int not null,
username varchar(30) NOT NULL, ...,
CONSTRAINT FK_EMPLOYEE_DEP_ID FOREIGN KEY(department_id) REFERENCES DEPARTMENT(id));
Run Code Online (Sandbox Code Playgroud)
我必须EMPLOYEE.username
在一家公司内实现唯一性。
我看到 2 种方式。
1.AFTER
在EMPLOYEE
表上使用语句级触发器(类似于http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936 , case1)
2. 只是添加company_id
到EMPLOYEE
它们对我来说都不理想,我想知道在这种情况下实现唯一性的正确方法是什么。
谢谢。
主要只是为了我自己的娱乐,您可以使用具有唯一索引的物化视图来完成此操作:
CREATE MATERIALIZED VIEW LOG ON COMPANY
WITH PRIMARY KEY, ROWID
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LOG ON DEPARTMENT
WITH PRIMARY KEY, ROWID (company_id)
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LOG ON EMPLOYEE
WITH PRIMARY KEY, ROWID (department_id, username)
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW xcheck_mv
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS SELECT c.id as company_id, lower(e.username) as username,
c.rowid as c_rowid, d.rowid as d_rowid, e.rowid as e_rowid
from company c, department d, employee e
where d.company_id = c.id
and e.department_id = d.id;
CREATE UNIQUE INDEX xcheck_ind ON xcheck_mv(company_id, username);
Run Code Online (Sandbox Code Playgroud)
然后尝试使用employee
相同的用户名插入不同部门的记录会导致唯一约束违规,尽管在您提交之前不会发生:
insert into company (id) values(1);
1 row created.
SQL> insert into department (id, company_id) values(1, 1);
1 row created.
SQL> insert into department (id, company_id) values(2, 1);
1 row created.
SQL> insert into employee (id, department_id, username) values(1,1,'Joe Bloggs');
1 row created.
SQL> insert into employee (id, department_id, username) values(2,2,'Joe Bloggs');
1 row created.
SQL> commit;
commit
*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-00001: unique constraint (STACKOVERFLOW.XCHECK_IND) violated
Run Code Online (Sandbox Code Playgroud)
只是为了好玩,我放入lower()
MV 定义来捕获最基本的解决方法 - 因此尝试插入'joe bloggs'
也会失败 - 但这个模型永远不会非常健壮。
我并不是说这是一个好主意,只是说这是可能的......
归档时间: |
|
查看次数: |
360 次 |
最近记录: |