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
等访问)
我有一个 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
等访问)