sqlite3中的Integer主键没有自动增量

9q78igpj  于 2023-06-30  发布在  SQLite
关注(0)|答案(3)|浏览(151)

在sqlite3常见问题解答中,提到了一个整数主键被提供一个空值将自动递增。但我不会这样的。
要复制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时,我只得到一堆空格。我做错了什么?

s6fujrry

s6fujrry1#

这是SQLite的怪癖之一。从精细手册:
根据SQL标准,PRIMARY KEY应该始终隐含NOT NULL。不幸的是,由于长期的编码疏忽,SQLite中并非如此。除非列是INTEGER PRIMARY KEY,否则SQLite允许在PRIMARY KEY列中使用NULL值。我们可以改变SQLite以符合标准(我们将来可能会这样做),但当发现疏忽时,SQLite的使用如此广泛,以至于我们担心如果我们解决这个问题,就会破坏遗留代码。
关于INTEGER PRIMARY KEY的文档有点不清楚一个列是自动递增的特殊INTEGER PRIMARY KEY所需的确切条件,但实际情况是,如果你想在插入时使用NULL值表示“给予我下一个自动递增的值”,那么该列需要为NOT 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(表示“在serial_num中放置NULL值,因为该列允许NULL”)之间的区别。

aor9mmx1

aor9mmx12#

上面提供的插入语法在没有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

我很抱歉把这个作为一个新的答案而不是对以前的答案进行评论,但是我的信誉分数太低,无法添加评论,我认为重要的是要注意备用插入语句不是一个足够的解决方案。

4dc9hkyq

4dc9hkyq3#

你应该写如下
整数主键自动递增NOT NULL =======================
例如:

cx01_registro = 0               # pic 9(06)
cx01_codigolancamento = ""      # pic x(02)
cx01_descricaolancamento = ""   # pic x(15)
cx01_tipolancamento = ""        # pic x(01) <+> deposito <-> retirada
conn = sqlite3.connect('caixa.db')
c = conn.cursor()
c.execute("CREATE TABLE IF NOT EXISTS TABCOD"
          "(cx01_registro INTEGER PRIMARY KEY  AUTOINCREMENT NOT NULL,"
           "cx01_codigolancamento CHAR(02),"
           "cx01_descricaolancamento CHAR(15),"
           "cx01_tipolancamento CHAR(01))")
conn.close()
#///////////////////////////
conn = sqlite3.connect('caixa.db')
print("Opened database successfully")
conn.execute("INSERT INTO TABCOD (cx01_registro,cx01_codigolancamento,"
             "cx01_descricaolancamento,cx01_tipolancamento) \
             VALUES (NULL, 'dp', 'deposito', '+')")
conn.execute("INSERT INTO TABCOD (cx01_registro,cx01_codigolancamento,"
             "cx01_descricaolancamento,cx01_tipolancamento) \
             VALUES (NULL, 'rt', 'retirada', '-')")
conn.commit()

这样就行了
如果你写如下
整数主键非空自动递增=
那是行不通的。

相关问题