【发布时间】:2011-03-28 01:31:38
【问题描述】:
我认为这有点深奥,但我想把它扔掉,以防有人尝试过这样的事情,或者如果有人已经尝试过并且发现这是不可能的。
我们有一个表需要对一组特定的列进行唯一性约束,但它也有一个“软删除”指示符。已标记为“已删除”的记录不应包含在唯一性检查中。
没关系,我可以使用唯一的基于函数的索引轻松解决这个问题。然而,更复杂的是,如果我们要在数据库中实现这个约束,它必须是一个延迟约束,因为 Hibernate 的工作方式。如果做不到,我们将不得不省略约束,如果可能的话,我宁愿不这样做。
例如:
CREATE TABLE jkemp_test
( id NUMBER NOT NULL
, deleted_ind CHAR(1) DEFAULT 'N' NOT NULL);
CREATE UNIQUE INDEX jkemp_test_funique
ON jkemp_test
(CASE WHEN deleted_ind = 'N' THEN id END);
-- make this use the function-based index, maybe?
ALTER TABLE jkemp_test
ADD CONSTRAINT jkemp_test_unique
UNIQUE (id)
DEFERRABLE INITIALLY DEFERRED;
INSERT INTO jkemp_test VALUES (1,'N');
INSERT INTO jkemp_test VALUES (2,'N');
COMMIT;
UPDATE jkemp_test SET deleted_ind='Y' WHERE id=1;
COMMIT;
-- depending on whether the constraint is deferred or not, either
-- the insert or the commit will fail "unique constraint violated"
INSERT INTO jkemp_test VALUES (1,'N');
COMMIT;
双赢的情况是最后一次提交成功,同时仍然允许延迟约束。 (我知道唯一索引的存在意味着当前没有延迟约束。)
目前我们唯一的选择是使用应用程序来实现约束,这不会那么可靠。此外,我们不想过多地更改数据模型(例如,我们可以将已删除的行移动到不同的表中,例如 JKEMP_TEST_DELETED,但这会在应用程序中涉及太多复杂性)。
这是在 Oracle 11.2.0.1.0 上。
【问题讨论】:
标签: sql oracle unique-constraint