在sqlite3 faq中,提到了一个为空值提供的整数主键会自动增加。但这不会发生在我身上。
复制,sqlite3中的表,CREATE TABLE dummy( serial_num INTEGER PRIMARY KEY, name TEXT);
并使用python填充它,
import sqlite3 as lite
con = lite.connect('some.db')
cur=con.cursor()
data = "someone's name"
cur.execute("INSERT INTO dummy VALUES(NULL, ?)", data)
con.commit()
第一个属性serial_num显示为空白,而name属性正常。当我做SELECT serial_num FROM dummy
时,我只是得到了一堆空格。我做错了什么?
答案 0 :(得分:26)
这是SQLite的一个怪癖。来自fine manual:
根据SQL标准,PRIMARY KEY应始终表示NOT NULL。不幸的是,由于长期的编码监督,在SQLite中并非如此。除非列是INTEGER PRIMARY KEY,否则SQLite允许在PRIMARY KEY列中使用NULL值。我们可以改变SQLite以符合标准(我们将来也可以这样做),但是当发现疏忽时,SQLite的使用范围很广,如果我们解决问题,我们担心会破坏遗留代码。
INTEGER PRIMARY KEY上的文档有点不清楚列是什么精确需要这个特殊的INTEGER PRIMARY KEY自动递增,但实际情况是如果你想要列,则列需要为NOT NULL插入时使用NULL值表示“给我下一个自动递增值”:
create table dummy (
serial_num integer primary key not null,
name text
);
如果遗漏not null
,则需要按照以下方式进行插入:
insert into dummy (name) values (?)
获取serial_num
的自动增量值。否则,SQLite无法区分NULL意味着“给我下一个自动增量值”和NULL意味着“将NULL值放在serial_num
中,因为该列允许NULL”。
答案 1 :(得分:2)
在没有not null
的情况下,上面提供的插入语法似乎不起作用。
以下是一个示例 - 请注意,即使我使用您在上面指定的插入格式,ID字段也不会自动增加。
sqlite> .schema logTable
CREATE TABLE logTable (ID INTEGER PRIMARY_KEY, ts REAL, level TEXT, message TEXT);
sqlite> INSERT into LOGTABLE (ts, level, message) VALUES (111, "autoinc test", "autoinc test");
sqlite> select * from logtable where ts = 111;
|111.0|autoinc test|autoinc test
sqlite>
它适用于NOT NULL解决方法。
sqlite> create TABLE logTable (ID INTEGER PRIMARY KEY NOT NULL, ts REAL, level TEXT, message TEXT);
sqlite> INSERT into LOGTABLE (ts, level, message) VALUES (222, "autoinc test", "autoinc test");
sqlite> select * from logtable where ts = 222;
1|222.0|autoinc test|autoinc test
我很抱歉将此作为新答案发布而不是评论之前的答案,但我的声誉评分太低而无法添加评论,我认为重要的是要注意备用插入语句不是一个适当的解决方法