2011-11-15 108 views
1

我有一個表mytable的哪裏是兩個獨特的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') 
) 

如何做到這樣的限制:

 
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-diriectional-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