使用sqlite检查来验证是否在列中输入了具有适当格式的日期

时间:2014-12-29 06:46:21

标签: sqlite date constraints

我创建了一个表格如下:

CREATE TABLE case_status(data_entry_timestamp DATETIME DEFAULT (datetime('now','localtime')) NOT NULL,
                         case_number TEXT PRIMARY KEY NOT NULL, 
                         case_name TEXT DEFAULT MISSING, 
                         death_reportdate DATE CONSTRAINT death_reportdate_chk CHECK (death_reportdate==strftime('%Y-%m-%d',death_reportdate)),
                         );

death_reportdate需要具有预定义格式的日期(例如2000-12-31)。我创建了表,插入了一些数据行,然后尝试修改death_reportdate中的数据,当我输入一些随机字符串时,检查规则似乎被绕过了。

我做错了什么?

4 个答案:

答案 0 :(得分:3)

最后你有一个额外的逗号。正确的代码:

CREATE TABLE case_status(data_entry_timestamp DATETIME DEFAULT (datetime('now','localtime')) NOT NULL,
    case_number TEXT PRIMARY KEY NOT NULL, 
    case_name TEXT DEFAULT MISSING, 
    death_reportdate DATE CONSTRAINT death_reportdate_chk CHECK (death_reportdate==strftime('%Y-%m-%d',death_reportdate))
    )

答案 1 :(得分:2)

这是一个旧主题,但我遇到了同样的问题。如果strftime方法无法格式化字符串(输入错误)它返回null,所以你必须检查最后不是null

答案 2 :(得分:0)

这是另一种效果像魅力的解决方案:

`date` DATE CHECK(date IS strftime('%Y-%m-%d', date))

这也适用于time

`time` TIME CHECK(time IS strftime('%H:%M:%S', time))

使用此定义您的列。我认为这是比检查null值更优雅的解决方案。

答案 3 :(得分:0)

首先,两个小笔记。

  1. 我正在使用TEXT类型,因为SQLite没有“真实类型”。 It has 5 column "affinities"INTEGERTEXTBLOBREALNUMERIC。如果您说DATE,那么它使用NUMERIC的行为在我看来可能有点怪异。我发现最好明确使用5种相似性之一。
  2. 我使用date(...)而不是strftime('%Y-%m-%d', ...),因为they are the same thing

让我们解释为什么原始问题不起作用。

DROP TABLE IF EXISTS TEMP.example;
CREATE TEMPORARY TABLE example (
    deathdate TEXT CHECK (deathdate == date(deathdate))
);
INSERT INTO TEMP.example (deathdate) VALUES ('2020-01-01');
INSERT INTO TEMP.example (deathdate) VALUES ('a');
INSERT INTO TEMP.example (deathdate) VALUES (NULL);
SELECT * FROM TEMP.example;

运行此命令可使所有三个值进入数据库。为什么?让我们检查一下CHECK constraints的文档。

如果结果为零(整数值0或实数值0.0),则发生约束冲突。如果CHECK表达式的计算结果为NULL或任何其他非零值,则不是约束冲突。

如果您运行SELECT 'a' == date('a');,则会看到它是NULL。为什么?选中SELECT date('a');,您还会看到它也是NULL。呵呵,也许documentation for ==可以帮上忙吗?

请注意,等于和不等于运算符有两种变体。等于可以是=或==。 [...]

IS和IS NOT运算符的工作方式类似于=和!=,但当一个或两个操作数为NULL时除外。在这种情况下,如果两个操作数均为NULL,则IS运算符的计算结果为1(true),而IS NOT运算符的计算结果为0(false)。如果一个操作数为NULL而另一个操作数为NULL,则IS运算符的计算结果为0(假),而IS NOT运算符的计算结果为1(真)。 IS或IS NOT表达式无法计算为NULL。

我们需要使用IS,而不是==,并尝试使'a'不再进入。

DROP TABLE IF EXISTS TEMP.example;
CREATE TEMPORARY TABLE example (
    deathdate TEXT CHECK (deathdate IS date(deathdate))
);
INSERT INTO TEMP.example (deathdate) VALUES ('2020-01-01');
INSERT INTO TEMP.example (deathdate) VALUES ('a');
INSERT INTO TEMP.example (deathdate) VALUES (NULL);
SELECT * FROM TEMP.example;

如果您不希望NULL进入,只需将其更改为deathdate TEXT NOT NULL CHECK (deathdate IS date(deathdate))

相关问题