根据我的理解,sqlite的数据类型并不与其列相关联,而是与数据本身相关联:这实际上意味着您可以将任何数据插入任何列。
是否有可能禁止这种行为?我的意思是,例如,当我不小心尝试将文本插入整数时,我希望sqlite引发错误(或至少是警告)。
答案 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
);
两列具有相同的约束,但以不同的方式应用于列
通过在CAST到INTEGER时检查列的值来实现约束。如果值不是INTEGER,则结果为0(false)。但是,为了满足0,有效值1将连接到列的值。因此0将导致1。
您还可以使用 TYPEOF
功能,例如
COL3 INTEGER CHECK(typeof(COL3) = 'INTEGER')
以下是一些示例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]
您可能希望看一下: -