条件约束唯一性

3
我有一个表格:
create table use_flags3 (
    id INTEGER,
    flag_name VARCHAR NOT NULL,        
    flag_description VARCHAR NOT NULL,
    flag_type_id INTEGER NOT NULL,
    package_id INTEGER,
    FOREIGN KEY (flag_type_id) REFERENCES use_flags_types(id),
    FOREIGN KEY (package_id) REFERENCES packages(id),
    PRIMARY KEY (id)
);

当flag_type_id等于1时,我希望flag_name列是唯一的仅限于。我尝试使用以下约束条件实现此目标:

CONSTRAINT idx1_chk CHECK (
    flag_type_id in (select id from use_flags_types where flag_type="local") or
    flag_type_id in (select id from use_flags_types where flag_type="expand") or
    flag_type_id in (select id from use_flags_types where flag_type="expand_hidden") or
    (
         flag_type_id in (select id from use_flags_types where flag_type="global") and
         flag_name not in (select flag_name from use_flags)
    )
)

sqlite表示“CHECK约束中不允许子查询”。我可以替换。
flag_type_id in (select id from use_flags_types where flag_type="local")

使用

flag_type_id = ${ID_HERE} -- id from `select id from use_flags_types where flag_type="local"`

但是我无法对最后约束的第二个子部分进行相同的处理技巧。
flag_name not in (select flag_name from use_flags)

有没有可能在一个表格中实现我最初想要的功能(我真的不想把这些数据分成2个或更多个表格)?// 希望说明很清楚
1个回答

4
如果您有复杂的约束条件,应该使用触发器: http://sqlfiddle.com/#!7/2094c
CREATE TABLE use_flags3 (
    id INTEGER,
    flag_name VARCHAR NOT NULL,
    flag_description VARCHAR NOT NULL,
    flag_type_id INTEGER NOT NULL,
    package_id INTEGER,
    FOREIGN KEY (flag_type_id) REFERENCES use_flags_types(id),
    FOREIGN KEY (package_id) REFERENCES packages(id),
    PRIMARY KEY (id)
);

/* TRIGGER BEFORE UPDATE version omitted */

CREATE TRIGGER fake_unique
BEFORE INSERT ON use_flags3
FOR EACH ROW
WHEN (
    EXISTS (SELECT NULL
            FROM use_flags_types
            WHERE flag_type IN( "local", "expand", "expand_hidden")
              AND flag_type_id = id
           )
    OR (
         EXISTS (SELECT NULL
                 FROM use_flags_types
                 WHERE flag_type="global"
                 AND flag_type_id = id)
         AND flag_name NOT IN (SELECT flag_name FROM use_flags)
    )
)
BEGIN
  SELECT RAISE( ABORT, 'duplicate rows' );
END;

目前我只允许 flag_name 字段不唯一。在所有数据插入后,我会运行一个简单的检查(在我的情况下这种方式是可接受的;至少现在是这样,因为它只是一个原型)。无论如何,感谢您的回复。 - ZuBB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接