将行复制到另一行时删除或转换复制的值 table

Drop or convert copied value when copying row to another table

我正在迁移数据库。我的其中一个列类型正在从 TEXT 更改为 INTEGER。

我的策略是重命名旧的 table 并创建一个新的,然后将旧的 table 的行插入到新的

假设我的新 table 是这样的:

CREATE TABLE Item (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    count INTEGER NOT NULL DEFAULT '0'
)

我传输数据的代码可能如下所示:

INSERT INTO Item (id, count)
    SELECT id, count FROM old_Item

我最初将计数定义为 TEXT,而我可能应该将其定义为 INTEGER。由于 dynamic typing,只要 count 条目可解析为整数,我希望这没问题,但我不能保证 [=13= 输入的不是整数] 专栏,而无需花费大量时间回顾十年前的许多旧版本应用程序。

当旧 table 中的列具有无效的 TEXT 值时,是否有办法使此列替换为某个默认整数值?

我知道如果我在语句中使用 ON CONFLICT REPLACE(或者是 UPSERT ON CONFLICT REPLACE?),NULL 值可以自动替换为默认值,但我不知道这会产生什么影响类型不匹配。

或者我需要用困难的方式做事而不是使用 SELECT,查询旧的 table 并手动解析 Java/Kotlin 中返回的 Cursor 的每一行,然后逐行插入?

您可以使用 CAST 函数

SELECT id, CAST(count AS int) FROM old_Item  

如果值为文本,则CAST的结果将为0。如果值为实数,则将其转换为整数

例如

INSERT INTO old_Item (count) values ('2');
INSERT INTO old_Item (count) values ('5.03');
INSERT INTO old_Item (count) values ('tXt22');
INSERT INTO old_Item (count) values (' 5.8');
INSERT INTO old_Item (count) values ('0x533');

SELECT CAST(count as INT) from old_Item 的结果将是

2
5
0
5
0

所以,在你的情况下你可以

查询

INSERT INTO Item SELECT id, CAST(count as int) FROM old_Item

如果无法识别为int,则值为0。 如果要将 0 替换为某个值,则需要进行此查询

select id, 
(case when count_int = 0 then your_default_value else count_int end) 
from (select id, cast(count as integer) count_int from old_Item);

完整解释 CAST 函数在 sqllite 中的工作原理,您可以在此处找到

https://sqlite.org/lang_expr.html#castexpr

type-name 的转换处理中的文本 - INTEGER