2 つの列の 2 つの値の組み合わせに対して一意の制約を作成するにはどうすればよいですか。
意味
column1 column2
2 1
禁止する制約を探しています
column1 column2
1 2
2 つの列の 2 つの値の組み合わせに対して一意の制約を作成するにはどうすればよいですか。
意味
column1 column2
2 1
禁止する制約を探しています
column1 column2
1 2
データベースがインデックスで式を許可している場合、次のようなことができます (ANSI SQL):
CREATE UNIQUE INDEX on your_table (least(column1, column2)
, greatest(column1, column2));
これは一意の制約ではなく、一意のインデックスであることに注意してください。ほとんどの DBMS の唯一の違いは、外部キーのターゲットとして一意のインデックスを持つことができないことですが、それ以外は同じ目的を果たします。
DBMS にない場合、least()
またはgreatest()
CASE 式を使用して置き換えることができる場合:
create unique index on your_table
(case column1 < column2 then column1 else column2 end,
case column2 > column1 then column2 else column1 end));
ドキュメントを見ると、ORACLE SGBD でこれが見つかりました。
CREATE TABLE b(
b1 INT,
b2 INT,
CONSTRAINT bu1 UNIQUE (b1, b2)
USING INDEX (create unique index bi on b(b1, b2)),
CONSTRAINT bu2 UNIQUE (b2, b1) USING INDEX bi);
ORACLEドキュメンテーションページの「制約に関連付けられた索引の指定」の章。
このヘルプをホップします。
2 つの列に対する一意の制約は、正確な 2 つの値が挿入されるのを防ぐだけです (それらの切り替えは許可されます)。
したがって、次のようなトリガーが必要です(ORACLE):
CREATE TRIGGER trig1
BEFORE INSERT ON TAB
REFERENCING NEW AS NEW
FOR EACH ROW
DECLARE
FOUND NUMBER;
BEGIN
SELECT COUNT(1) into FOUND FROM TAB WHERE
(COLUMN1=:NEW.column2 AND COLUMN2=:NEW.column1)
OR (COLUMN1=:NEW.column1 AND COLUMN2=:NEW.column2);
IF FOUND>0 THEN
raise_application_error (-20001,'INSERT not allowed');
END IF;
END trig1;
警告: 構文がチェックされていません。