如何防止列b包含与Oracle中任何列a相同的值?

Jan*_*cki 5 oracle data-integrity

什么是防止具有2列的表(a(唯一)和b)的任何记录,其中列b等于列a中的任何值?这将用于这样的更正表,

MR   -> Mr
Prf. -> Prof.
MRs  -> Mrs
Run Code Online (Sandbox Code Playgroud)

我可以看到如何使用触发器和子查询来完成它,假设没有并发活动,但更多的声明性方法更可取.

这是应该预防的一个例子,

Wing Commdr. -> Wing Cdr.
Wing Cdr.    -> Wing Commander
Run Code Online (Sandbox Code Playgroud)

理想情况下,该解决方案适用于并发插入和更新.

Vin*_*rat 2

您可以使用物化视图来执行您的要求(使用 10.2.0.1 进行测试)。

\n\n
SQL> CREATE TABLE t (a VARCHAR2(20) NOT NULL PRIMARY KEY,\n  2                  b VARCHAR2(20) NOT NULL);\nTable created\n\nSQL> CREATE MATERIALIZED VIEW LOG ON t WITH (b), ROWID INCLUDING NEW VALUES;     \nMaterialized view log created\n\nSQL> CREATE MATERIALIZED VIEW mv\n  2     REFRESH FAST ON COMMIT\n  3  AS\n  4  SELECT 1 umarker, COUNT(*) c, count(a) cc, a val_col\n  5    FROM t\n  6   GROUP BY a\n  7  UNION ALL\n  8  SELECT 2 umarker, COUNT(*), COUNT(b), b\n  9    FROM t\n 10    GROUP BY b;     \nMaterialized view created\n\nSQL> CREATE UNIQUE INDEX idx ON mv (val_col);     \nIndex created \n
Run Code Online (Sandbox Code Playgroud)\n\n

唯一索引将确保两列(两行)中不能具有相同的值。

\n\n
SQL> INSERT INTO t VALUES (\'Wing Commdr.\', \'Wing Cdr.\');     \n1 row inserted\n\nSQL> COMMIT;     \nCommit complete\n\nSQL> INSERT INTO t VALUES (\'Wing Cdr.\', \'Wing Commander\');     \n1 row inserted\n\nSQL> COMMIT;     \n\nORA-12008: erreur dans le chemin de r\xc3\xa9g\xc3\xa9n\xc3\xa9ration de la vue mat\xc3\xa9rialis\xc3\xa9e\nORA-00001: violation de contrainte unique (VNZ.IDX)\n\nSQL> INSERT INTO t VALUES (\'X\', \'Wing Commdr.\');     \n1 row inserted\n\nSQL> COMMIT;\n\nORA-12008: erreur dans le chemin de r\xc3\xa9g\xc3\xa9n\xc3\xa9ration de la vue mat\xc3\xa9rialis\xc3\xa9e\nORA-00001: violation de contrainte unique (VNZ.IDX)\n
Run Code Online (Sandbox Code Playgroud)\n\n

它将在提交期间进行序列化,但仅对 A 列和 B 列的值进行序列化(即:通常它不应阻止并发不相交活动)。

\n\n

只会在提交时检查唯一性,并且某些工具不希望提交失败并且可能表现不正常。此外,当 COMMIT 失败时,整个事务将回滚,并且您将丢失任何未提交的更改(您无法“重试”)。

\n