【问题标题】:How to check for overlapping intervals when entering data in SQLite3?在 SQLite3 中输入数据时如何检查重叠间隔?
【发布时间】:2017-06-04 03:38:45
【问题描述】:

我需要在我的 SQLite3 数据库中进行检查,以确保用户无法输入具有重叠间隔的数据。

例如:

hole #  Sample From    To 
1          1     1      2               
1          2     2      3               
1          3    2.2    2.9      

在上面的示例中,我已经进行了检查,可以在每个孔中捕获任何重复的“From”,但样本 #3 不是重复的,因此不会被捕获,但它是一个重叠间隔。

我不希望将其用于查询,而是将其用作表中内置的数据输入检查。

到目前为止,我已尝试添加('From' NOT BETWEEN 'From' and 'To) 的约束检查,但无济于事。我不明白检查是尝试逐行应用,我想要,还是在主键的基础上。

这是我正在尝试的表定义:

 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]
    )
);

这是具有更新约束的表(在提交之前):

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 中逐行应用约束检查?

【问题讨论】:

  • 你试过什么?你在哪里卡住了?
  • 我已经尝试过('From' NOT BETWEEN 'From' and 'To'),但它不起作用,我不确定下一步该做什么。
  • 显示实际的表定义,以及您尝试添加的实际约束。
  • 对于我对问题的解释质量不佳,我深表歉意。总的来说,我对 sql 和数据库是全新的,我相信你可以说出来。

标签: sqlite sqlitestudio


【解决方案1】:

在SQL中,双引号用于引用表名和列名;单引号用于字符串值。所以检查

('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;

【讨论】:

  • 感谢富有成效的反馈和回答!
猜你喜欢
  • 1970-01-01
  • 2016-08-25
  • 2020-09-13
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 2014-08-29
  • 2017-11-26
  • 1970-01-01
相关资源
最近更新 更多