解析SQLite中的常见问题与总结详解

1、 创建数据
如果不往数据库里面添加任何的表,这个数据库等于没有建立,不会在硬盘上产生任何文件,如果数据库已经存在,则会打开这个数据库。

2、 如何通过sqlite3.dll与sqlite3.def生成sqlite3.lib文件
LIB /DEF:sqlite3.def /machine:IX86

3、 sqlite3_open打开一个数据库时,如果数据库不存在就会新生成一个数据库文件。如果接着执行其他查询语句就会失败,比如sqlite3_prepare,编程中出现明明指定了数据库而且里面也有数据,为什么查询失败了,主要是数据库名路径不对引起的。一般的做法是先检查数据库文件是否存在,如果存在就使用sqlite3_open打开数据库;否则创建一个新的数据库。

4、 如何建立自动增长字段
声明为INTEGER PRIMARY KEY的列将会自动增长。

5、SQLite3支持何种数据类型?
NULL
INTEGER
REAL
TEXT
BLOB
但实际上,sqlite3也接受如下的数据类型:
smallint 16位元的整数。
interger 32位元的整数。
decimal(p,s) p精确值和s大小的十进位整数,精确值p是指全部有几个数(digits)大小值,s是指小数点後有几位数。如果没有特别指定,则系统会设为p=5; s=0。
float 32位元的实数。
double 64位元的实数。
char(n) n长度的字串,n不能超过254。
varchar(n)长度不固定且其最大长度为n的字串,n不能超过4000。
graphic(n)和char(n)一样,不过其单位是两个字元double-bytes,n不能超过127。这个形态是为了支援两个字元长度的字体,例如中文字。
vargraphic(n)可变长度且其最大长度为n的双字元字串,n不能超过2000。
date包含了年份、月份、日期。
time包含了小时、分钟、秒。
timestamp包含了年、月、日、时、分、秒、千分之一秒。

6、SQLite允许向一个integer型字段中插入字符串
这是一个特性,而不是一个bug。SQLite不强制数据类型约束。任何数据都可以插入任何列。你可以向一个整型列中插入任意长度的字符串,向布尔型列中插入浮点数,或者向字符型列中插入日期型值。在CREATE TABLE中所指定的数据类型不会限制在该列中插入任何数据。任何列均可接受任意长度的字符串(只有一种情况除外:标志为INTEGER PRIMARY KEY的列只能存储64位整数,当向这种列中插数据除整数以外的数据时,将会产生错误。

但SQLite确实使用声明的列类型来指示你所期望的格式。所以,例如你向一个整型列中插入字符串时,SQLite会试图将该字符串转换成一个整数。如果可以转换,它将插入该整数;否则,将插入字符串。这种特性有时被称为类型或列亲和性(type or column affinity).

7、为什么SQLite不允许在同一个表不同的两行上使用0和0.0作主键?
主键必须是数值类型,将主键改为TEXT型将不起作用。
每一行必须有一个唯一的主键。对于一个数值型列,SQLite认为'0'和'0.0'是相同的,因为他们在作为整数比较时是相等的(参见上一问题)。所以,这样值就不唯一了。

8、多个应用程序或一个应用程序的多个实例可以同时访问同一个数据库文件吗?
 
多个进程可同时打开同一个数据库。多个进程可以同时进行SELECT操作,但在任一时刻,只能有一个进程对数据库进行更改。
 
SQLite使用读、写锁控制对数据库的访问。(在Win95/98/ME等不支持读、写锁的系统下,使用一个概率性的模拟来代替。)但使用时要注意:如果数据库文件存放于一个NFS文件系统上,这种锁机制可能不能正常工作。这是因为fcntl()文件锁在很多NFS上没有正确的实现。在可能有多个进程同时访问数据库的时候,应该避免将数据库文件放到NFS上。在Windows上,Microsoft的文档中说:如果使用FAT文件系统而没有运行share.exe守护进程,那么锁可能是不能正常使用的。那些在Windows上有很多经验的人告诉我:对于网络文件,文件锁的实现有好多Bug,是靠不住的。如果他们说的是对的,那么在两台或多台Windows机器间共享数据库可能会引起不期望的问题。

我们意识到,没有其它嵌入式的SQL数据库引擎能象SQLite这样处理如此多的并发。SQLite允许多个进程同时打开一个数据库,同时读一个数据库。当有任何进程想要写时,它必须在更新过程中锁住数据库文件。但那通常只是几毫秒的时间。其它进程只需等待写进程干完活结束。典型地,其它嵌入式的SQL数据库引擎同时只允许一个进程连接到数据库。

但是,Client/Server数据库引擎(如PostgreSQL, MySQL,或Oracle)通常支持更高级别的并发,并且允许多个进程同时写同一个数据库。这种机制在Client/Server结构的数据库上是可能的,因为总是有一个单一的服务器进程很好地控制、协调对数据库的访问。如果你的应用程序需要很多的并发,那么你应该考虑使用一个Client/Server结构的数据库。但经验表明,很多应用程序需要的并发,往往比其设计者所想象的少得多。

当SQLite试图访问一个被其它进程锁住的文件时,缺省的行为是返回SQLITE_BUSY。可以在C代码中使用sqlite3_busy_handler()或sqlite3_busy_timeout() API函数调整这一行为。

9、SQLite线程安全吗?
线程是魔鬼(Threads are evil)。避免使用它们。
SQLite是线程安全的。由于很多用户会忽略我们在上一段中给出的建议,我们做出了这种让步。但是,为了达到线程安全,SQLite在编译时必须将SQLITE_THREADSAFE预处理宏置为1。在Windows和Linux上,已编译的好的二进制发行版中都是这样设置的。如果不确定你所使用的库是否是线程安全的,可以调用sqlite3_threadsafe()接口找出。

10、在SQLite数据库中如何列出所有的表和索引?
如果你运行sqlite3命令行来访问你的数据库,可以键入“.tables”来获得所有表的列表。或者,你可以输入“.schema”来看整个数据库模式,包括所有的表的索引。输入这些命令,后面跟一个LIKE模式匹配可以限制显示的表。

11、SQLite数据库有已知的大小限制吗?
在Windows和Unix下,版本2.7.4的SQLite可以达到2的41次方字节(2T字节)。老版本的为2的31次方字节(2G字节)。
SQLite版本2.8限制一个记录的容量为1M。SQLite版本3.0则对单个记录容量没有限制。
表名、索引表名、视图名、触发器名和字段名没有长度限制。但SQL函数的名称(由sqlite3_create_function() API函数创建)不得超过255个字符。

12、在SQLite中,VARCHAR字段最长是多少?
SQLite不强制VARCHAR的长度。你可以在SQLITE中声明一个VARCHAR(10),SQLite还是可以很高兴地允许你放入500个字符。并且这500个字符是原封不动的,它永远不会被截断。
 
13、在SQLite中,如何在一个表上添加或删除一列?
SQLite有有限地ALTER TABLE支持。你可以使用它来在表的末尾增加一列,可更改表的名称。如果需要对表结构做更复杂的改变,则必须重新建表。重建时可以先将已存在的数据放到一个临时表中,删除原表,创建新表,然后将数据从临时表中复制回来。

如,假设有一个t1表,其中有"a", "b", "c"三列,如果要删除列c,以下过程描述如何做:

BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
14、在SQLite中支持分页吗?
 
SQLite分页是世界上最简单的。如果我要去11-20的Account表的数据Select * From Account Limit 9 Offset 10;
以上语句表示从Account表获取数据,跳过10行,取9行。这个特性足够让很多的web中型网站使用这个了。也可以这样写 select * from account limit10,9和上面的的效果一样。这种写法MySQL也支持。

(0)

相关推荐

  • SQLite3中自增主键相关知识总结

    一.SQLite清空表并将自增列归零 SQL标准中有TRUNCATE TABLE语句,用来清空表的所有内容.但SQLite不支持这个语句.在SQLite中直接使用 DELETE FROM TableName 就可以了.对于大多数DBMS来说,用DELETE不如用TRUNCATE 速度快,因为TRUNCATE 不用访问整个表,不用记录数据的变动. SQLite虽然不支持TRUNCATE,但它对DELETE做了优化:通常在清空表的时候,还需要把自增列归零.在SQLite中定义自增列的方法如下: 复制

  • 浅谈SQLite时间函数的使用说明与总结分析

    本文主要讲解SQLite中时间函数进行分析与总结并给出使用案例.本文给出的例子都是经过测试.SQLite时间/日期函数种类:1.datetime():产生日期和时间2.date():产生日期3:.time():产生时间4.strftime():对以上三个函数产生的日期和时间进行格式化 SQLite时间/日期函数用法:1.datetime()的用法是:datetime(日期/时间,修正符,修正符...)2.date()和time()的语法与datetime()相同.3.strftime()函数可以

  • 深入SQLite多线程的使用总结详解

    SQLite支持3种线程模式: 单线程:这种模式下,没有进行互斥,多线程使用不安全.禁用所有的mutex锁,并发使用时会出错.当SQLite编译时加了SQLITE_THREADSAFE=0参数,或者在初始化SQLite前调用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)时启用. 多线程:这种模式下,只要一个数据库连接不被多个线程同时使用就是安全的.源码中是启用bCoreMutex,禁用bFullMutex.实际上就是禁用数据库连接和prepared stat

  • 深入SQLite基本操作的总结详解

    sqlite提供的是一些C函数接口,你可以用这些函数操作数据库.通过使用这些接口,传递一些标准 sql 语句(以 char * 类型)给 sqlite 函数,sqlite 就会为你操作数据库.sqlite 跟MS的access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引.触发器等等,但是,它实际上得到的就是一个文件.备份这个文件就备份了整个数据库. sqlite 不需要任何数据库引擎,这意味着如果你需要 sqlite 来保存一些用户数据,甚至都不需

  • SQLITE3 使用总结

    前序: 这里要注明,我是一个跨平台专注者,并不喜欢只用 windows 平台.我以前的工作就是为 unix 平台写代码.下面我所写的东西,虽然没有验证,但是我已尽量不使用任何 windows 的东西,只使用标准 C 或标准C++.但是,我没有尝试过在别的系统.别的编译器下编译,因此下面的叙述如果不正确,则留待以后修改. 下面我的代码仍然用 VC 编写,因为我觉得VC是一个很不错的IDE,可以加快代码编写速度(例如配合 Vassist ).下面我所说的编译环境,是VC2003.如果读者觉得自己习惯

  • 解析SQLite中的常见问题与总结详解

    1. 创建数据如果不往数据库里面添加任何的表,这个数据库等于没有建立,不会在硬盘上产生任何文件,如果数据库已经存在,则会打开这个数据库. 2. 如何通过sqlite3.dll与sqlite3.def生成sqlite3.lib文件LIB /DEF:sqlite3.def /machine:IX86 3. sqlite3_open打开一个数据库时,如果数据库不存在就会新生成一个数据库文件.如果接着执行其他查询语句就会失败,比如sqlite3_prepare,编程中出现明明指定了数据库而且里面也有数据

  • 解析Runtime中shutdown hook的使用详解

    根据 Java API, 所谓 shutdown hook 就是已经初始化但尚未开始执行的线程对象.在Runtime 注册后,如果 jvm 要停止前,这些 shutdown hook 便开始执行.声明:Runtime.addShutdownHook(Thread t)举例如下: 复制代码 代码如下: package john2; /** * test shutdown hook * All rights released and correctness not guaranteed. */pub

  • Android使用Realm数据库实现App中的收藏功能(代码详解)

    前 言 App数据持久化功能是每个App必不可少的功能,而Android最常用的数据持久化方式主要有以下的五种方式: 使用SharedPreferences存储数据: 文件存储数据: SQLite数据库存储数据: 使用ContentProvider存储数据: 网络存储数据. 其中前四种都是缓存数据到本地,这篇主要讲的是使用第三种方式来实现App中的收藏功能,不过不用Android原生自带SQLite数据库来存储数据,而是使用第三方的Realm数据库来来存储数据. Realm 本质上是一个嵌入式数

  • Oracle中游标Cursor基本用法详解

    查询 SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的 返回值被赋予INTO子句中的变量,变量的声明是在DELCARE中.SELECT INTO语法如下: SELECT [DISTICT|ALL]{*|column[,column,...]} INTO (variable[,variable,...] |record) FROM {table|(sub-query)}[alias] WHERE............ PL/SQL

  • python中模块的__all__属性详解

    python模块中的__all__属性,可用于模块导入时限制,如: from module import * 此时被导入模块若定义了__all__属性,则只有__all__内指定的属性.方法.类可被导入. 若没定义,则导入模块内的所有公有属性,方法和类 # kk.py class A(): def __init__(self,name,age): self.name=name self.age=age class B(): def __init__(self,name,id): self.nam

  • python编程之requests在网络请求中添加cookies参数方法详解

    哎,好久没有学习爬虫了,现在想要重新拾起来.发现之前学习爬虫有些粗糙,竟然连requests中添加cookies都没有掌握,惭愧.废话不宜多,直接上内容. 我们平时使用requests获取网络内容很简单,几行代码搞定了,例如: import requests res=requests.get("https://cloud.flyme.cn/browser/index.jsp") print res.content 你没有看错,真的只有三行代码.但是简单归简单,问题还是不少的. 首先,这

  • Android通过json向MySQL中读写数据的方法详解【读取篇】

    本文实例讲述了Android通过json向MySQL中读取数据的方法.分享给大家供大家参考,具体如下: 首先 要定义几个解析json的方法parseJsonMulti,代码如下: private void parseJsonMulti(String strResult) { try { Log.v("strResult11","strResult11="+strResult); int index=strResult.indexOf("[");

  • java 中enum的使用方法详解

    java 中enum的使用方法详解 enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性,存放在 java.lang 包中. 下面是我在使用 enum 过程中的一些经验和总结. 原始的接口定义常量 public interface IConstants { String MON = "Mon"; String TUE = "Tue"; String WED = "Wed"; String THU = "Thu

  • 使用Java构造和解析Json数据的两种方法(详解二)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Json数据的方法

  • 使用Java构造和解析Json数据的两种方法(详解一)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Json数据的方法

随机推荐