首页 > 解决方案 > SQLite UPDATE 现在工作或者我做错了

问题描述

当前表格问题:

rowid: 1 | 2 | 3 | 4 | 5
id:    3 | 4 | 7 | 9 | 10 

试图实现以下目标:

rowid: 1 | 2 | 3 | 4 | 5

id:    1 | 2 | 3 | 4 | 5 

我尝试了许多不同的 SQL 变体但没有成功,这是我正在测试的最新版本:

更新问题 SET id = rowid;

有人可以建议我如何解决这个问题,因为我已经用谷歌搜索并且找不到解决方案吗?

标签: sqlite

解决方案


我不相信你的问题完全涵盖了问题的所有方面。

理论上有一个表(前表),其中SELECT rowid, id结果

rowid: 1 | 2 | 3 | 4 | 5
id:    3 | 4 | 7 | 9 | 10 

id列不能是rowid列的别名(否则值将相同)

但是,如果 id 列是rowid列的别名,则两列将相同,因此上面的前表将与上面不同。

作为一个例子使用: -

--<<<<<<<<<< WORKS >>>>>>>>>>
-- as ID is not an alias of the rowid column update changes id column
DROP TABLE IF EXISTS questionsv3;
CREATE TABLE IF NOT EXISTS questionsv3 (ID INTEGER);
INSERT INTO questionsv3 VALUES (3),(4),(7),(9),(10);
SELECT rowid, id FROM questionsv3;
UPDATE questionsv3 SET id = rowid;
SELECT rowid, id FROM questionsv3;

根据以下结果产生预期结果:-

首先选择(更新前):-

在此处输入图像描述

第二次选择(更新后)

在此处输入图像描述

其他潜在原因

  1. rowid实际上不是 SQLITE 中的rowid,而是一个概念上的想法,它应该是 1,2,3 ......(在这种情况下使用 VACUUM,如果 rowid 没有别名,可能会导致对 rowid 列进行所需的重新编号,如果随后进行更新,则可能导致 id 被重新排序)。

  2. 更新是在尚未提交并回滚的事务中完成的。

您可能希望考虑以下不同表创建的排列(见评论):-

-- as ID is an alias of rowid, then rowid is set according to ID so update does nothing
DROP TABLE IF EXISTS questionsv1;
CREATE TABLE IF NOT EXISTS questionsv1 (ID INTEGER PRIMARY KEY);
INSERT INTO questionsv1 VALUES (3),(4),(7),(9),(10);
SELECT rowid, id FROM questionsv1;
UPDATE questionsv1 SET id = rowid;
SELECT rowid, id FROM questionsv1;

-- as ID is an alias of the rowid column, then rowid is set according to the ID so update does nothing
DROP TABLE IF EXISTS questionsv2;
CREATE TABLE IF NOT EXISTS questionsv2 (ID INTEGER PRIMARY KEY AUTOINCREMENT);
INSERT INTO questionsv2 VALUES (3),(4),(7),(9),(10);
SELECT rowid, id FROM questionsv2;
UPDATE questionsv2 SET id = rowid;
SELECT rowid, id FROM questionsv2;

--<<<<<<<<<< WORKS >>>>>>>>>>
-- as ID is not an alias of the rowid column update changes id column
DROP TABLE IF EXISTS questionsv3;
CREATE TABLE IF NOT EXISTS questionsv3 (ID INTEGER);
INSERT INTO questionsv3 VALUES (3),(4),(7),(9),(10);
SELECT rowid, id FROM questionsv3;
UPDATE questionsv3 SET id = rowid;
SELECT rowid, id FROM questionsv3;

--<<<<<<<<<< WORKS >>>>>>>>>>
-- as ID is not an alias of rowid the ID column is updated accordingly
DROP TABLE IF EXISTS questionsv4;
CREATE TABLE IF NOT EXISTS questionsv4 (ID TEXT PRIMARY KEY); -- not an alias of rowid
INSERT INTO questionsv4 VALUES (3),(4),(7),(9),(10);
SELECT rowid, id FROM questionsv4;
UPDATE questionsv4 SET id = rowid;
SELECT rowid, id FROM questionsv4;

--<<<<<<<<<< FAILS >>>>>>>>>>
DROP TABLE IF EXISTS questionsv13;
CREATE TABLE IF NOT EXISTS questionsv13 (ID INTEGER PRIMARY KEY) WITHOUT ROWID;
INSERT INTO questionsv13 VALUES (3),(4),(7),(9),(10);
SELECT id FROM questionsv13;
UPDATE questionsv13 SET id = rowid; -- would fail no such column
SELECT id FROM questionsv13;

推荐阅读