gpt4 book ai didi

Sqlite3 : Creating a new table from an old table is not populating the sqlite_sequence table correctly

转载 作者:行者123 更新时间:2023-12-03 14:54:19 29 4
gpt4 key购买 nike

我正在尝试根据 this answer 删除表上的非空约束.但是,它似乎没有在 sqlite_sequence 中创建条目。这样做之后,即使我可以在使用测试表时让它正常工作。 有趣的是,如果我备份我的表,重新创建它,在其中插入两个假行,然后重复上述过程,sqlite_sequence表已正确填充。但是当我使用原始数据集 时,程序无法正常工作.

例如,这在测试表上运行良好:

CREATE TABLE foo (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
bar VARCHAR NOT NULL
);
INSERT INTO foo (bar) VALUES ('foo');
INSERT INTO foo (bar) VALUES ('bar');

-- As expected, this shows foo | 2
SELECT * FROM sqlite_sequence WHERE name = 'foo';

BEGIN TRANSACTION;
ALTER TABLE foo RENAME TO temp_foo;
CREATE TABLE foo (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
bar VARCHAR
);
INSERT INTO foo SELECT * from temp_foo;

-- As expected, this shows foo | 2
SELECT * FROM sqlite_sequence WHERE name = 'foo';
COMMIT;

但是,当我在我的真实表上执行完全相同的命令时,它无法将条目添加到 sqlite_sequence .
sqlite> .schema post;
CREATE TABLE post (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
title VARCHAR NOT NULL,
url_name VARCHAR NOT NULL,
description VARCHAR NOT NULL,
category_id INTEGER NOT NULL,
content VARCHAR,
is_published BOOLEAN,
creation_date DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
last_modified_date DATETIME DEFAULT CURRENT_TIMESTAMP,
is_commenting_disabled BOOLEAN NOT NULL,
CHECK (title <> ''),
CHECK (url_name <> ''),
CHECK (description <> ''),
CHECK (content <> ''),
FOREIGN KEY(user_id) REFERENCES user (id) ON DELETE CASCADE,
UNIQUE (url_name),
FOREIGN KEY(category_id) REFERENCES category (id) ON DELETE CASCADE,
CHECK (is_published IN (0, 1)),
CHECK (is_commenting_disabled IN (0, 1))
);
sqlite>
sqlite> select * from sqlite_sequence where name = 'post';
post|114
sqlite>
sqlite> BEGIN TRANSACTION;
sqlite>
sqlite> ALTER TABLE post RENAME TO temp_post;
sqlite>
sqlite> CREATE TABLE post (
...> id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
...> user_id INTEGER NOT NULL,
...> title VARCHAR NOT NULL,
...> url_name VARCHAR NOT NULL,
...> description VARCHAR,
...> category_id INTEGER NOT NULL,
...> content VARCHAR,
...> is_published BOOLEAN,
...> creation_date DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
...> last_modified_date DATETIME DEFAULT CURRENT_TIMESTAMP,
...> is_commenting_disabled BOOLEAN NOT NULL,
...> CHECK (title <> ''),
...> CHECK (url_name <> ''),
...> CHECK (description <> ''),
...> CHECK (content <> ''),
...> FOREIGN KEY(user_id) REFERENCES user (id) ON DELETE CASCADE,
...> UNIQUE (url_name),
...> FOREIGN KEY(category_id) REFERENCES category (id) ON DELETE CASCADE,
...> CHECK (is_published IN (0, 1)),
...> CHECK (is_commenting_disabled IN (0, 1))
...> );
sqlite>
sqlite> INSERT INTO post SELECT * FROM temp_post;
sqlite>
sqlite> select * from sqlite_sequence WHERE name in ('temp_post', 'post');
temp_post|114
sqlite> COMMIT;
sqlite>
sqlite> select * from sqlite_sequence WHERE name in ('temp_post', 'post');
temp_post|114

我已经这样做了大约三遍,但我无法让它工作。我最终做了一个
INSERT INTO sqlite_sequence VALUES ('post', 114);

一切似乎都运行良好

但当然,文档有这样的说法:

The content of the sqlite_sequence table can be modified using ordinary UPDATE, INSERT, and DELETE statements. But making modifications to this table will likely perturb the AUTOINCREMENT key generation algorithm. Make sure you know what you are doing before you undertake such changes.



如前所述,如果我备份 post表,然后我重新创建它,然后在其中添加两个假行,然后重复上述过程, sqlite_sequence表是正确的。我的原始数据集似乎有问题,但我不确定如何调试该问题。

最佳答案

对于表格的声明:

INSERT INTO this SELECT * FROM that;

SQLite 有一个特殊的传输优化,可以复制整行,而无需对行值进行解码和编码。
  • 当表结构简单(如 foo )时,总是可以使用这种优化。
  • 某些功能(例如外键约束)与此优化不兼容。
  • 并且在某些情况下,例如当存在 UNIQUE 约束时,这种优化只有在目标表为空时才能起作用。

  • 在第三种情况下,为语句生成的代码检查表是否为空。如果为空,则传输优化完成,程序停止;如果它不为空,则跳转到正常进行读/写的第二部分。但是,执行空表检查的代码 forgot to update the sqlite_sequence table在停止程序之前。

    作为一种解决方法,通过启用外键检查将其移至第二种情况。

    This bug在版本 3.6.16 中引入, was fixed in version 3.15.0 .

    关于Sqlite3 : Creating a new table from an old table is not populating the sqlite_sequence table correctly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39820552/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com