2011-11-15 14 views
1

私は2ユニークなint型フィールドがSQL複雑なユニーク制約

# SQLAlchemy example 
mytable = Table('mytable', meta, 

# per-column anonymous unique constraint 
Column('col1', Integer, unique=True), 
Column('col2', Integer, unique=True), 

# explicit/composite unique constraint. 'name' is optional. 
UniqueConstraint('col1', 'col2', name='uix_1') 
) 

である。このような制限を行うにはどのようにmytableテーブルがあります。

 
col1 col2 
1  
2  6 
3  1 
4  5 
5 
6  1 -- FAIL: becouse 3-1 is exist and 2-6 is exist!!! 

ユニーク((COL1、COL2)組合(COL2を、COL1))

+0

なぜ(3,1)が失敗しないのですか? – gbn

+2

なぜ6-1が失敗したのか分かりませんか? –

+0

私は理解のための同様の例を見つけましたhttp://stackoverflow.com/questions/8108205/sql-structuring-a-bi-driectional-graph – uralbash

答えて

5

あなたは制約として、このようなものを使用することができます。

create table example (
    col1 integer, 
    col2 integer, 
    CHECK (col1 < col2), 
    UNIQUE(col1, col2) 
); 

col1を自動的にcol2より小さくしたい場合は、トリガーを使用してください:

1

私は制約を使ってこれを達成できないと思います。あなたも更新情報をチェックする必要があり

CREATE TABLE test (a int, b int); 

CREATE OR REPLACE FUNCTION fun_test() 
    RETURNS trigger 
    LANGUAGE plpgsql 
AS 
$body$ 
BEGIN 
    if (TG_OP = 'INSERT') then 
     if (exists(SELECT 1 FROM test t WHERE t.b = NEW.a) -- or whatever condition you want 
      and exists(SELECT 1 FROM test t WHERE t.b = NEW.b)) 
      then 
      RAISE EXCEPTION 'Can''t insert (%,%)', NEW.a, NEW.b; 
     end if; 
    return NEW; 
    end if; 
END;  
$body$ 

    CREATE TRIGGER tgr_test BEFORE INSERT 
     ON test FOR EACH ROW 
EXECUTE PROCEDURE fun_test(); 

注:

あなたはトリガーを使用することができます。

+0

注: 'CREATE TRIGGER'の前にセミコロンがありません。さもなければ正常に動作します(postgres 9.1.13) – Kenney