Sqlite:触发以限制行中值的数量

Sqlite: Trigger to restrict number of values in row

我有一个 sqlite table,其中指定了产品特性。功能,例如颜色,在布尔列中。列为“1”或 "NULL"。有些功能是专有的。由于 table 结构是固定的,我试图创建一个引发异常的触发器,但它不起作用。我做错了什么?

示例:

CREATE TABLE productColor(
    productId INTEGER PRIMARY KEY,
    isRed INTEGER,
    isBlue INTEGER,
    isYellow INTEGER,
    isBrown INTEGER)

产品只能有一种颜色。我的想法是对指定了不止一种颜色的列进行计数,即少于三个 NULL 值。如果至少有一个这样的行,触发器将引发异常。这就是我的触发器的样子:

CREATE TRIGGER onlyOneColor
    BEFORE INSERT ON productColor
    WHEN 
        (SELECT COUNT (*) FROM 
        (SELECT ((CASE WHEN isBrown IS NULL THEN 1 ELSE 0 END) +
        (CASE WHEN isRed IS NULL THEN 1 ELSE 0 END) +
        (CASE WHEN isBlue IS NULL THEN 1 ELSE 0 END) +
        (CASE WHEN isYellow IS NULL THEN 1 ELSE 0 END))
        AS sumOfNulls FROM productColor) WHERE sumOfNulls<3)
    >=1
    BEGIN
    SELECT RAISE(FAIL, 'More then one color specified');
    END;

你不需要触发器;这可以通过检查约束来完成:

CREATE TABLE productColor (
    productId INTEGER PRIMARY KEY,
    isRed     INTEGER  CHECK (isRed    = 1 OR isRed    IS NULL),
    isBlue    INTEGER  CHECK (isBlue   = 1 OR isBlue   IS NULL),
    isYellow  INTEGER  CHECK (isYellow = 1 OR isYellow IS NULL),
    isBrown   INTEGER  CHECK (isBrown  = 1 OR isBrown  IS NULL),
    CHECK (ifnull(isRed,    0) + ifnull(isBlue,  0) +
           ifnull(isYellow, 0) + ifnull(isBrown, 0) <= 1)
);

如果将所有值都存储为 0 或 1,这些检查会更简单。 (0 不需要比 NULL 更多的存储空间 space。)


如果确实需要触发器,可以将倒置条件放在WHEN子句中。 (请注意,要插入的行中的值可以使用 NEW.isRed 等访问)