2011-11-15 88 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