1、SQLite不支持关键字AUTO_INCREMENT

1)AUTO_INCREMENT不生效的问题

SQL语句:

CREATE TABLE todo
(
    id INTEGER AUTO_INCREMENT,
    title TEXT,
    PRIMARY KEY (id)
);

问题描述:按照上述SQL语句创建表todo,用INSERT INTO todo (title) VALUES ('xxx')插入记录,但查询该记录后得到的id为NULL(即Python中的None)

实验脚本:

#!/usr/bin/python
# -*- encoding: utf-8 -*- import sqlite3
con = sqlite3.connect(":memory:") # 创建表
con.execute("""
CREATE TABLE todo
(
id INTEGER AUTO_INCREMENT,
title TEXT,
PRIMARY KEY (id)
);""") # 插入记录
con.execute("INSERT INTO todo (title) VALUES ('shopping');") # 查询记录
for row in con.execute("SELECT * FROM todo"):
print row

运行结果:

$ python auto_increment_null.py
(None, u'shopping')

2)AUTO_INCREMENT导致语法错误的问题

SQL语句:

CREATE TABLE todo
(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
title TEXT
);

问题描述:根据SQL的语法,按理说上述SQL语句应该与1)中的SQL语句等效,但运行结果却是语法错误

实验脚本:

#!/usr/bin/python
# -*- encoding: utf-8 -*- import sqlite3
con = sqlite3.connect(":memory:") # 创建表
con.execute("""
CREATE TABLE todo
(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
title TEXT
);""") # 插入记录
con.execute("INSERT INTO todo (title) VALUES ('shopping');") # 查询记录
for row in con.execute("SELECT * FROM todo"):
print row

运行结果:

$ python auto_increment_error.py
Traceback (most recent call last):
File "auto_increment_error.py", line , in <module>
);""")
sqlite3.OperationalError: near "AUTO_INCREMENT": syntax error

上述两个问题在《AUTO_INCREMENT in sqlite problem with python》中得到了解释和解答:在SQLite中,自增字段需要使用关键字INTEGER PRIMARY KEY。

2、自增关键字INTEGER PRIMARY KEY

SQL语句:

CREATE TABLE todo
(
id INTEGER PRIMARY KEY,
title TEXT
);

或者

CREATE TABLE todo
(
id INTEGER PRIMARY KEY NOT NULL,
title TEXT
);

按照上述SQL语句创建表todo,用INSERT INTO todo (title) VALUES ('xxx')或者INSERT INTO todo (id, title) VALUES (NULL, 'xxx')插入记录,查询记录后得到的id为自增的整型值。

实验脚本:

#!/usr/bin/python
# -*- encoding: utf-8 -*- import sqlite3
con = sqlite3.connect(":memory:") # 创建表
con.execute("""
CREATE TABLE todo
(
id INTEGER PRIMARY KEY,
title TEXT
);""") # 创建表:效果相同
'''
con.execute("""
CREATE TABLE todo
(
id INTEGER PRIMARY KEY NOT NULL,
title TEXT
);""")
''' # 插入记录:shopping
con.execute("INSERT INTO todo (title) VALUES ('shopping');") # 插入记录:working
con.execute("INSERT INTO todo (id, title) VALUES (NULL, 'working');") # 查询记录
for row in con.execute("SELECT * FROM todo"):
print row

运行结果:

$ python integer_primary_key_ok.py
(, u'shopping')
(, u'working')

注意:之前看《No autoincrement for Integer Primary key in sqlite3》中有提到“SQLite的自增字段定义为NULL或NOT NULL是有区别的”,根据上面的实验,这个问题好像已经不存在了。

3、关键字AUTOINCREMENT与内部表sqlite_sequence

SQLite中,在INTEGER PRIMARY KEY的基础上添加AUTOINCREMENT后(即INTEGER PRIMARY KEY AUTOINCREMENT),可以在表的整个生命周期内保证“自增字段”的唯一性(create keys that are unique over the lifetime of the table)。

SQLite内部用一个叫作sqlite_sequence的表来保存所有表的自增字段的取值基准(the largest ROWID),如果清空sqlite_sequence的记录,可以实现将所有表的自增字段的取值归零的效果(这种行为具有破坏性,请谨慎使用)。

关于这一主题,更详细的介绍可以参考《How do I create an AUTOINCREMENT field》《SQLite Autoincrement》

实验脚本:

#!/usr/bin/python
# -*- encoding: utf-8 -*- import sqlite3
con = sqlite3.connect(":memory:") def new_and_show(tbl_name):
"""插入并显示记录"""
# 插入记录到表
con.execute("INSERT INTO " + tbl_name + " (title) VALUES ('shopping');")
# 查询表记录
for row in con.execute("SELECT * FROM " + tbl_name):
print row def clr(tbl_name):
"""清除表记录"""
con.execute("DELETE FROM " + tbl_name) print "--表todo--"
# 1. 创建表
con.execute("""
CREATE TABLE todo
(
id INTEGER PRIMARY KEY,
title TEXT
);""")
# 2. 插入并显示记录
new_and_show("todo")
# 3. 清除表记录
clr("todo")
# 4. 插入并显示记录
new_and_show("todo")
# 5. 清除表记录
clr("todo")
# 6. 插入并显示记录
new_and_show("todo") print "--表todo_auto--"
# 1. 创建表
con.execute("""
CREATE TABLE todo_auto
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT
);""")
# 2. 插入并显示记录
new_and_show("todo_auto")
# 3. 清除表记录
clr("todo_auto")
# 4. 插入并显示记录
new_and_show("todo_auto") # 将所有表的自增列都归零
#clr("sqlite_sequence") # 5. 清除表记录
clr("todo_auto")
# 6. 插入并显示记录
new_and_show("todo_auto")

运行结果:

$ python autoincrement_diff.py
--表todo--
(, u'shopping')
(, u'shopping')
(, u'shopping')
--表todo_auto--
(, u'shopping')
(, u'shopping')
(, u'shopping')

如果去掉clr("sqlite_sequence")这一行的注释,则运行结果会变成:

$ python autoincrement_diff.py
--表todo--
(, u'shopping')
(, u'shopping')
(, u'shopping')
--表todo_auto--
(, u'shopping')
(, u'shopping')
(, u'shopping')    ## 由于clr("sqlite_sequence")将表todo_auto的自增字段的取值归零,因此这一行又变成了1

另外,SQLite不支持SQL标准语句“TRUNCATE TABLE tbl_name”,只能使用“DELETE FROM tbl_name”来删除表记录,具体可以参考《SQLite清空表并将自增列归零》

SQLite中的自增关键字:AUTO_INCREMENT、INTEGER PRIMARY KEY与AUTOINCREMENT的更多相关文章

  1. 如何在SQLite中创建自增字段

      SQLite 简单的回答:一个声明为 INTEGER PRIMARY KEY 的字段将自动增加. 这里是详细的答案: 从 SQLite 的 2.3.4 版本开始,如果你将一个表中的一个字段声明为 ...

  2. sqlite中的自增主键

    http://stackoverflow.com/questions/8519936/sqlite-autoincrement-primary-key-questions I'm not sure w ...

  3. SQLite主键自增需要设置为integer PRIMARY KEY

    按照正常的SQL语句,创建一个数据表,并设置主键是这样的语句: ), EventType )) 但使用这种办法,在SQLite中创建的的数据表,如果使用Insert语句插入记录,如下语句: INSER ...

  4. SQLite3中自增主键相关知识总结,清零的方法、INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用

    这篇文章主要介绍了SQLite3中自增主键相关知识总结,清零的方法.INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用等,需要的朋友可以参考下 一.SQLite清空表 ...

  5. (转)Sqlite中INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用

    原文:http://www.cnblogs.com/peida/archive/2008/11/29/1343832.html Sqlite中INTEGER PRIMARY KEY AUTOINCRE ...

  6. mongdb创建自增主键(primary key)的相关讨论 - Jason.Zhi

    根据mongodb官方文档介绍,如果在插入(insert)操作时,没有指定主键id,那么它会自动给插入行自动附上一个主键id.看起来不错,但是详细看看,就会发现这个id值有点复杂. 如下图: mong ...

  7. SQLite中的增删改查

    虽然android提供了sql查询的封装方法,但是理解起来还是麻烦,所以我这里用sql语句来完成工作. 首先是建立一个类,继承SQLiteOpenHelper 这里面会建立一个数据库,并且初始化一个表 ...

  8. EF6 在 SQLite中使用备忘

    == 菜鸟级选手试验在EF6中使用Sqlite,零EF基础,少量Sqlite基础.经过断断续续的很长时间 - _ -! >>连接 1. 安装 使用目前最新版本EF6.1,Sqlite1.0 ...

  9. 谈数据库索引和Sqlite中索引的使用

    要使用索引对数据库的数据操作进行优化,那必须明确几个问题:1.什么是索引2.索引的原理3.索引的优缺点4.什么时候需要使用索引,如何使用围绕这几个问题,来探究索引在数据库操作中所起到的作用. 1.数据 ...

随机推荐

  1. Spring学习(五)-----注入bean属性的三种方式( 1: 正常的方式 2: 快捷方式 3: “p” 模式)

    在Spring中,有三种方式注入值到 bean 属性. 正常的方式 快捷方式 “p” 模式 看到一个简单的Java类,它包含两个属性 - name 和 type.稍后将使用Spring注入值到这个 b ...

  2. java.lang.Boolean.valueOf(String s)

    简单说,就是s为true(这四个字母大小写任意)时,返回值为true,否则为false public class one { public static void main(String[] args ...

  3. TCP/IP三次握手四次挥手分析

    流程图 全部11种状态 客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT 服务器独有的:(1)LISTEN (2 ...

  4. python之奇思妙想

    一.概述 本篇主要介绍自己平常所遇到的各种有趣的关于python的简短例子 二.正文 chapter 1 解决思路: s='{:,.2f}'.format(100000.0) print(s) cod ...

  5. 树形dp入门两题

    题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...

  6. 利用xlsxwriter生成数据报表

    #!/usr/bin/env python# -*- coding:utf-8 -*-import os,xlsxwriter,datetimeimport ConfigParserfrom send ...

  7. css 元素水平垂直方向居中

    html部分 <div class="parent"> <div class="child"> - -居中- - </div> ...

  8. c# 导入第三方插件(例如pdf控件),莫名有时候成功有时候出错

    问题情境: 正如标题所述: 解决办法: 怀疑是adobe acrobat 9 pro安装文件出错:重新安装,成功. 在这过程中,尝试过福听阅读器,adobe reader等,均正常. 注:1.第三方的 ...

  9. dcom初步窥探一

    一.问题带入: 从delphi 5开始,有许多人都面临过这样的问题:com应用开发出来并且在本机上运行一切正常,但是一旦分发出去实施远程访问时,就无法正常运行了.我自己有段时间在看到“拒绝访问”错误提 ...

  10. Java中按值传递与按引用传递的区别

    值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响 ...