是否可以强制数据类型?

时间:2018-03-12 07:45:58

标签: sqlite

根据我的理解,sqlite的数据类型并不与其列相关联,而是与数据本身相关联:这实际上意味着您可以将任何数据插入任何列。

是否有可能禁止这种行为?我的意思是,例如,当我不小心尝试将文本插入整数时,我希望sqlite引发错误(或至少是警告)。

2 个答案:

答案 0 :(得分:4)

您可以使用CHECK约束和typeof()来检查实际数据类型:

CREATE TABLE MyTable (
    Col1 INTEGER  CHECK (typeof(Col1) = 'integer'),
    Col2 TEXT     CHECK (typeof(Col2) IN ('text', 'null')
);

答案 1 :(得分:2)

我相信您可以使用CHECK约束,例如

CREATE TABLE testinsert (
    COL1 INTEGER, 
    COL2 INTEGER CHECK (CAST(COL2||1 AS INTEGER) <> 0) -- column constraint
    CHECK (CAST(COL1||1 AS INTEGER) <> 0) -- table constraint
);
  • 这将创建一个包含两列COL1和COL2的表。
  • 两列具有相同的约束,但以不同的方式应用于列

    • COL1将CHECK约束应用为表约束
    • COL2将CHECK约束应用为列约束
  • 通过在CAST到INTEGER时检查列的值来实现约束。如果值不是INTEGER,则结果为0(false)。但是,为了满足0,有效值1将连接到列的值。因此0将导致1。

您还可以使用 TYPEOF 功能,例如

COL3 INTEGER CHECK(typeof(COL3) = 'INTEGER')
  • 注意到使用CAST和TYPEOF之间存在细微差别。前面的示例使用CAST,允许以字符串形式提供整数,而使用 typeof 函数只允许整数。

以下是一些示例INSERTS,结果如下: -

INSERT INTO testinsert VALUES(100,100); -- OK
INSERT INTO testinsert VALUES('100',100); -- OK
INSERT INTO testinsert VALUES('100','abc'); -- ouch for COL2 (abc)
INSERT INTO testinsert VALUES(0,100); -- OK
INSERT INTO testinsert VALUES('0',100); -- OK
INSERT INTO testinsert VALUES('abc',100); -- ouch  for COL1 (abc)

将COL3添加到表格中: -

INSERT INTO testinsert VALUES(100,100,100); -- OK (all integers)
INSERT INTO testinsert VALUES('100','100',100); -- OK (CAST can accept integers as strings)
INSERT INTO testinsert VALUES('100','100','100'); -- Ouch typeof will consider '100' as a string, not an integer

如果你想忽略而不是中止(默认),那么你可以使用: -

INSERT OR IGNORE INTO testinsert VALUES('100','abc'); -- insert Skipped - no fail

SQLite Manager用于测试上述内容。

以下是CONFLICT失败的一个例子: -

SQLiteManager:  -- OK
INSERT INTO testinsert VALUES('100','abc'); [ CHECK constraint failed: testinsert ]
Exception Name: NS_ERROR_STORAGE_CONSTRAINT
Exception Message: Component returned failure code: 0x80630003 (NS_ERROR_STORAGE_CONSTRAINT) [mozIStorageStatement.execute]

您可能希望看一下: -