在 SQLite3 中输入数据时如何检查重叠间隔?
How to check for overlapping intervals when entering data in SQLite3?
我需要在我的 SQLite3 数据库中进行检查,以确保用户不能输入间隔重叠的数据。
例如:
hole # Sample From To
1 1 1 2
1 2 2 3
1 3 2.2 2.9
在上面的示例中,我进行了检查,可以在每个孔中捕获任何重复项 'From',但示例 #3 不是重复项,因此不会被捕获,但它是一个重叠间隔。
我不希望将其用于查询,而是将其作为内置于 table 中的数据输入检查。
到目前为止,我已经尝试添加 ('From' NOT BETWEEN 'From' and 'To)
的约束检查但无济于事。我不明白检查是试图按我想要的逐行应用,还是按主键应用。
这是我正在尝试的 table 定义:
CREATE TABLE assay (
BHID TEXT NOT NULL
CONSTRAINT [Check BHID] REFERENCES collar (BHID) ON DELETE CASCADE
ON UPDATE CASCADE
MATCH SIMPLE,
[Sample #] TEXT UNIQUE,
[FROM] NUMERIC NOT NULL
CONSTRAINT [Interval Check] CHECK ( ("TO" > "FROM") ),
[TO] NUMERIC NOT NULL,
Ag NUMERIC CONSTRAINT [Max Silver] CHECK ( (Ag < 1000) ),
Zn NUMERIC CONSTRAINT [Max Zinc] CHECK ( (Zn < 50) ),
Pb NUMERIC CONSTRAINT [Max Lead] CHECK ( (Pb < 50) ),
Fe NUMERIC,
PRIMARY KEY (
BHID,
[FROM]
)
);
这是 table 更新后的约束(提交前):
CREATE TABLE assay (
BHID TEXT NOT NULL
CONSTRAINT [Check BHID] REFERENCES collar (BHID) ON DELETE CASCADE
ON UPDATE CASCADE
MATCH SIMPLE,
[Sample #] TEXT UNIQUE,
[FROM] NUMERIC NOT NULL
CONSTRAINT [Interval Check] CHECK ( ("TO" > "FROM") )
CONSTRAINT [Not Between] CHECK ( ('From' NOT BETWEEN 'From' AND 'To') ),
[TO] NUMERIC NOT NULL,
Ag NUMERIC CONSTRAINT [Max Silver] CHECK ( (Ag < 1000) ),
Zn NUMERIC CONSTRAINT [Max Zinc] CHECK ( (Zn < 50) ),
Pb NUMERIC CONSTRAINT [Max Lead] CHECK ( (Pb < 50) ),
Fe NUMERIC,
PRIMARY KEY (
BHID,
[FROM]
)
);
我删除了具有冲突数据的数据行(从:2.2,到:2.9)并在尝试添加新的约束检查之前提交了更改。但它不会让我提交新的约束,我相信是因为它试图将它应用到整个列。
所以我的问题应该是这样的:有没有办法在 sql 中逐行应用约束检查?
在SQL中,双引号用于引用table和列名;单引号用于字符串值。所以检查
('FROM' NOT BETWEEN 'FROM' AND 'TO')
只是比较这些常量字符串值。此检查总是失败。
无论如何,CHECK 约束只能访问当前行中的值。
为了能够查看其他行,您必须使用触发器:
CREATE TRIGGER no_overlaps
BEFORE INSERT ON Assay
WHEN EXISTS (SELECT *
FROM Assay
WHERE "From" <= NEW."To"
AND "To" >= NEW."From")
BEGIN
SELECT RAISE(FAIL, "overlapping intervals");
END;
我需要在我的 SQLite3 数据库中进行检查,以确保用户不能输入间隔重叠的数据。
例如:
hole # Sample From To
1 1 1 2
1 2 2 3
1 3 2.2 2.9
在上面的示例中,我进行了检查,可以在每个孔中捕获任何重复项 'From',但示例 #3 不是重复项,因此不会被捕获,但它是一个重叠间隔。
我不希望将其用于查询,而是将其作为内置于 table 中的数据输入检查。
到目前为止,我已经尝试添加 ('From' NOT BETWEEN 'From' and 'To)
的约束检查但无济于事。我不明白检查是试图按我想要的逐行应用,还是按主键应用。
这是我正在尝试的 table 定义:
CREATE TABLE assay (
BHID TEXT NOT NULL
CONSTRAINT [Check BHID] REFERENCES collar (BHID) ON DELETE CASCADE
ON UPDATE CASCADE
MATCH SIMPLE,
[Sample #] TEXT UNIQUE,
[FROM] NUMERIC NOT NULL
CONSTRAINT [Interval Check] CHECK ( ("TO" > "FROM") ),
[TO] NUMERIC NOT NULL,
Ag NUMERIC CONSTRAINT [Max Silver] CHECK ( (Ag < 1000) ),
Zn NUMERIC CONSTRAINT [Max Zinc] CHECK ( (Zn < 50) ),
Pb NUMERIC CONSTRAINT [Max Lead] CHECK ( (Pb < 50) ),
Fe NUMERIC,
PRIMARY KEY (
BHID,
[FROM]
)
);
这是 table 更新后的约束(提交前):
CREATE TABLE assay (
BHID TEXT NOT NULL
CONSTRAINT [Check BHID] REFERENCES collar (BHID) ON DELETE CASCADE
ON UPDATE CASCADE
MATCH SIMPLE,
[Sample #] TEXT UNIQUE,
[FROM] NUMERIC NOT NULL
CONSTRAINT [Interval Check] CHECK ( ("TO" > "FROM") )
CONSTRAINT [Not Between] CHECK ( ('From' NOT BETWEEN 'From' AND 'To') ),
[TO] NUMERIC NOT NULL,
Ag NUMERIC CONSTRAINT [Max Silver] CHECK ( (Ag < 1000) ),
Zn NUMERIC CONSTRAINT [Max Zinc] CHECK ( (Zn < 50) ),
Pb NUMERIC CONSTRAINT [Max Lead] CHECK ( (Pb < 50) ),
Fe NUMERIC,
PRIMARY KEY (
BHID,
[FROM]
)
);
我删除了具有冲突数据的数据行(从:2.2,到:2.9)并在尝试添加新的约束检查之前提交了更改。但它不会让我提交新的约束,我相信是因为它试图将它应用到整个列。
所以我的问题应该是这样的:有没有办法在 sql 中逐行应用约束检查?
在SQL中,双引号用于引用table和列名;单引号用于字符串值。所以检查
('FROM' NOT BETWEEN 'FROM' AND 'TO')
只是比较这些常量字符串值。此检查总是失败。
无论如何,CHECK 约束只能访问当前行中的值。 为了能够查看其他行,您必须使用触发器:
CREATE TRIGGER no_overlaps
BEFORE INSERT ON Assay
WHEN EXISTS (SELECT *
FROM Assay
WHERE "From" <= NEW."To"
AND "To" >= NEW."From")
BEGIN
SELECT RAISE(FAIL, "overlapping intervals");
END;