我希望有一个表架构,其中两列共享同一个值池。例如,包含两列foo
和bar
且包含整数的表在两列中的编号不应相同。它仅适用于一列(CREATE TABLE test (foo INT UNIQUE);
),但不适用于多列。
例如,我有以下SQL语句,除第一个之外的所有语句都应该失败,因为它们使用已经存在于两列之一中的整数:
sqlite> CREATE TABLE test (foo INTEGER NOT NULL , bar INTEGER DEFAULT NULL);
sqlite> INSERT INTO test VALUES(42, 47);
sqlite> INSERT INTO test VALUES(47, 42);
sqlite> INSERT INTO test VALUES(47, 74);
sqlite> INSERT INTO test(foo) VALUES(42);
标记两列唯一值对我不起作用,因为这只会检查两个值的组合是否已经存在(因此只有第三次插入失败)。
sqlite> CREATE TABLE test (foo INTEGER NOT NULL , bar INTEGER DEFAULT NULL, UNIQUE(foo, bar));
sqlite> INSERT INTO test VALUES(42, 47);
sqlite> INSERT INTO test VALUES(47, 42);
sqlite> INSERT INTO test VALUES(42, 47);
Error: columns foo, bar are not unique
sqlite> INSERT INTO test(foo) VALUES(42);
将每列唯一标记也无济于事,因为两列都应共享相同的值池。
sqlite> CREATE TABLE test (foo INTEGER NOT NULL UNIQUE, bar INTEGER DEFAULT NULL UNIQUE);
sqlite> INSERT INTO test VALUES (42, 47);
sqlite> INSERT INTO test VALUES (42, 47);
Error: column bar is not unique
sqlite> INSERT INTO test VALUES (42, 74);
Error: column foo is not unique
sqlite> INSERT INTO test VALUES (47, 42);
这比组合版本更接近我的目标,因为它在第三次插入时失败了,但它并不是我需要的。
我要求这个,因为我想保存硬件端口的数量。每条线至少有一个输出端口,但也可以有一个输入端口。显然,一个端口不能同时存在。
答案 0 :(得分:2)
您需要使用trigger:
CREATE TRIGGER very_unique
BEFORE INSERT ON test
WHEN NEW.foo IN (SELECT foo FROM test)
OR NEW.foo IN (SELECT bar FROM test)
OR NEW.bar IN (SELECT foo FROM test)
OR NEW.bar IN (SELECT bar FROM test)
OR NEW.foo = NEW.bar
BEGIN
SELECT RAISE(FAIL, 'foo or bar not unique');
END;
如果在两列上都放置UNIQUE约束,则WHEN子句中只需要两次SELECT检查。
答案 1 :(得分:0)
只需声明每一个都是唯一的:
CREATE TABLE test (
foo INTEGER NOT NULL UNIQUE,
bar INTEGER DEFAULT NULL UNIQUE
);