5

a (一意) と b の 2 つの列を持つテーブルに、列 b が列 a の任意の値と等しいレコードが含まれないようにする良い方法は何ですか? これは、次のような修正表に使用されます。

MR   -> Mr
Prf. -> Prof.
MRs  -> Mrs

同時アクティビティがないと仮定してトリガーとサブクエリを使用してどのように実行できるかがわかりますが、より宣言的なアプローチが望ましいでしょう。

これは、防止すべきものの例です。

Wing Commdr. -> Wing Cdr.
Wing Cdr.    -> Wing Commander

理想的には、ソリューションは同時挿入と更新で機能します。

4

2 に答える 2

2

マテリアライズド ビューを使用して要件を適用できます (10.2.0.1 でテスト済み)。

SQL> CREATE TABLE t (a VARCHAR2(20) NOT NULL PRIMARY KEY,
  2                  b VARCHAR2(20) NOT NULL);
Table created

SQL> CREATE MATERIALIZED VIEW LOG ON t WITH (b), ROWID INCLUDING NEW VALUES;     
Materialized view log created

SQL> CREATE MATERIALIZED VIEW mv
  2     REFRESH FAST ON COMMIT
  3  AS
  4  SELECT 1 umarker, COUNT(*) c, count(a) cc, a val_col
  5    FROM t
  6   GROUP BY a
  7  UNION ALL
  8  SELECT 2 umarker, COUNT(*), COUNT(b), b
  9    FROM t
 10    GROUP BY b;     
Materialized view created

SQL> CREATE UNIQUE INDEX idx ON mv (val_col);     
Index created 

一意のインデックスにより、両方の列 (2 つの行) で同じ値を持つことができないことが保証されます。

SQL> INSERT INTO t VALUES ('Wing Commdr.', 'Wing Cdr.');     
1 row inserted

SQL> COMMIT;     
Commit complete

SQL> INSERT INTO t VALUES ('Wing Cdr.', 'Wing Commander');     
1 row inserted

SQL> COMMIT;     

ORA-12008: erreur dans le chemin de régénération de la vue matérialisée
ORA-00001: violation de contrainte unique (VNZ.IDX)

SQL> INSERT INTO t VALUES ('X', 'Wing Commdr.');     
1 row inserted

SQL> COMMIT;

ORA-12008: erreur dans le chemin de régénération de la vue matérialisée
ORA-00001: violation de contrainte unique (VNZ.IDX)

コミット中にシリアル化されますが、列 A と B の値に対してのみシリアル化されます (つまり、一般に、同時のばらばらなアクティビティを妨げてはなりません)。

単一性は COMMIT 時にのみチェックされ、一部のツールはコミットの失敗を予期せず、不適切に動作する可能性があります。また、コミットが失敗すると、トランザクション全体がロールバックされ、コミットされていない変更が失われます (「再試行」できません)。

于 2010-04-24T09:54:48.173 に答える
0

セッション A が ('A', 'B') を挿入するが、コミットしない場合、セッション B はコミットせずに ('B','A') を挿入するとします。どちらのセッションも、他のセッションによって挿入されたレコードを見ることはできません。次に、セッションがコミットされます。

1 つのセッションが挿入するときにテーブル全体をロックすることにより (BEFORE INSERT トリガー)、シリアル化して、AFTER INSERT トリガーでチェックを行うことができます。テーブルに指定したコンテンツが含まれている場合、多くのアクティビティは表示されないため、シリアル化は問題になりません。

于 2010-04-24T00:38:37.733 に答える