SQLite3 C/C++ 开发接口简介

http://liufei-fir.iteye.com/blog/1171175

1.0 总览

SQLite3是SQLite一个全新的版本,它虽然是在SQLite 2.8.13的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和API. SQLite3是为了满足以下的需求而开发的:

支持UTF-16编码.
用户自定义的文本排序方法.
可以对BLOBs字段建立索引.
因此为了支持这些特性我改变了数据库的格式,建立了一个与之前版本不兼容的3.0版. 至于其他的兼容性的改变,例如全新的API等等,都将在理论介绍之后向你说明,这样可以使你最快的一次性摆脱兼容性问题.
3.0版的和2.X版的API非常相似,但是有一些重要的改变需要注意. 所有API接口函数和数据结构的前缀都由"sqlite_"改为了"sqlite3_". 这是为了避免同时使用SQLite 2.X和SQLite 3.0这两个版本的时候发生链接冲突.
由于对于C语言应该用什么数据类型来存放UTF-16编码的字符串并没有一致的规范. 因此SQLite使用了普通的void* 类型来指向UTF-16编码的字符串. 客户端使用过程中可以把void*映射成适合他们的系统的任何数据类型.
2.0 C/C++ 接口
SQLite 3.0一共有83个API函数,此外还有一些数据结构和预定义(#defines). (完整的API介绍请参看另一份文档.) 不过你们可以放心,这些接口使用起来不会像它的数量所暗示的那么复杂. 最简单的程序仍然使用三个函数就可以完成: sqlite3_open(),sqlite3_exec(),和 sqlite3_close(). 要是想更好的控制数据库引擎的执行,可以使用提供的sqlite3_prepare()函数把SQL语句编译成字节码,然后在使用sqlite3_step()函数来执行编译后的字节码. 以sqlite3_column_开头的一组API函数用来获取查询结果集中的信息. 许多接口函数都是成对出现的,同时有UTF-8和UTF-16两个版本. 并且提供了一组函数用来执行用户自定义的SQL函数和文本排序函数.
2.1 如何打开关闭数据库
C代码
  1. typedefstructsqlite3sqlite3;
  2. intsqlite3_open(constchar*,sqlite3**);
  3. intsqlite3_open16(constvoid*,87); font-weight:bold">intsqlite3_close(sqlite3*);
  4. char*sqlite3_errmsg(sqlite3*);
  5. void*sqlite3_errmsg16(sqlite3*);
  6. intsqlite3_errcode(sqlite3*);

sqlite3_open() 函数返回一个整数错误代码,而不是像第二版中一样返回一个指向sqlite3结构体的指针. sqlite3_open() 和 sqlite3_open16() 的不同之处在于sqlite3_open16() 使用UTF-16编码(使用本地主机字节顺序)传递数据库文件名. 如果要创建新数据库,sqlite3_open16() 将内部文本转换为UTF-16编码,反之sqlite3_open() 将文本转换为UTF-8编码.
打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行. 而且允许使用PRAGMA声明来设置如本地文本编码或默认内存页面大小等选项和参数.
sqlite3_errcode() 通常用来获取最近调用的API接口返回的错误代码. sqlite3_errmsg() 则用来得到这些错误代码所对应的文字说明. 这些错误信息将以 UTF-8 的编码返回,并且在下一次调用任何SQLite API函数的时候被清除. sqlite3_errmsg16() 和 sqlite3_errmsg() 大体上相同,除了返回的错误信息将以 UTF-16 本机字节顺序编码.
SQLite3的错误代码相比SQLite2没有任何的改变,它们分别是:
#defineSQLITE_OK0/*Successfulresult*/
  • #defineSQLITE_ERROR1/*SQLerrorormissingdatabase*/
  • #defineSQLITE_INTERNAL2/*AninternallogicerrorinSQLite*/
  • #defineSQLITE_PERM3/*Accesspermissiondenied*/
  • #defineSQLITE_ABORT4/*Callbackroutinerequestedanabort*/
  • #defineSQLITE_BUSY5/*Thedatabasefileislocked*/
  • #defineSQLITE_LOCKED6/*Atableinthedatabaseislocked*/
  • #defineSQLITE_NOMEM7/*Amalloc()failed*/
  • #defineSQLITE_READONLY8/*Attempttowriteareadonlydatabase*/
  • #defineSQLITE_INTERRUPT9/*Operationterminatedbysqlite_interrupt()*/
  • #defineSQLITE_IOERR10/*SomekindofdiskI/Oerroroccurred*/
  • #defineSQLITE_CORRUPT11/*Thedatabasediskimageismalformed*/
  • #defineSQLITE_NOTFOUND12/*(InternalOnly)Tableorrecordnotfound*/
  • #defineSQLITE_FULL13/*Insertionfailedbecausedatabaseisfull*/
  • #defineSQLITE_CANTOPEN14/*Unabletoopenthedatabasefile*/
  • #defineSQLITE_PROTOCOL15/*Databaselockprotocolerror*/
  • #defineSQLITE_EMPTY16/*(InternalOnly)Databasetableisempty*/
  • #defineSQLITE_SCHEMA17/*Thedatabaseschemachanged*/
  • #defineSQLITE_TOOBIG18/*Toomuchdataforonerowofatable*/
  • #defineSQLITE_CONSTRAINT19/*Abortduetocontraintviolation*/
  • #defineSQLITE_MISMATCH20/*Datatypemismatch*/
  • #defineSQLITE_MISUSE21/*Libraryusedincorrectly*/
  • #defineSQLITE_NOLFS22/*UsesOSfeaturesnotsupportedonhost*/
  • #defineSQLITE_AUTH23/*Authorizationdenied*/
  • #defineSQLITE_ROW100/*sqlite_step()hasanotherrowready*/
  • #defineSQLITE_DONE101/*sqlite_step()hasfinishedexecuting*/

  • 2.2 执行 SQL 语句
    typedef int (*sqlite_callback)(void*,int,char**,char**);
    int sqlite3_exec(sqlite3*,const char *sql,sqlite_callback,void*,sans-serif; font-size:14px; line-height:25.200000762939453px">sqlite3_exec 函数依然像它在SQLite2中一样承担着很多的工作. 该函数的第二个参数中可以编译和执行零个或多个SQL语句. 查询的结果返回给回调函数. 更多地信息可以查看API 参考.
    在SQLite3里,sqlite3_exec一般是被准备SQL语句接口封装起来使用的.
    structsqlite3_stmtsqlite3_stmt;
  • intsqlite3_prepare(sqlite3*,int,sqlite3_stmt**,87); font-weight:bold">char**);
  • intsqlite3_prepare16(sqlite3*,85); font-weight:bold">void**);
  • intsqlite3_finalize(sqlite3_stmt*);
  • intsqlite3_reset(sqlite3_stmt*);

  • sqlite3_prepare 接口把一条SQL语句编译成字节码留给后面的执行函数. 使用该接口访问数据库是当前比较好的的一种方法.
    sqlite3_prepare() 处理的SQL语句应该是UTF-8编码的. 而sqlite3_prepare16() 则要求是UTF-16编码的. 输入的参数中只有第一个SQL语句会被编译. 第四个参数则用来指向输入参数中下一个需要编译的SQL语句存放的SQLite statement对象的指针,任何时候如果调用 sqlite3_finalize() 将销毁一个准备好的SQL声明. 在数据库关闭之前,所有准备好的声明都必须被释放销毁. sqlite3_reset() 函数用来重置一个SQL声明的状态,使得它可以被再次执行.
    SQL声明可以包含一些型如"?" 或 "?nnn" 或 ":aaa"的标记, 其中"nnn" 是一个整数,"aaa" 是一个字符串. 这些标记代表一些不确定的字符值(或者说是通配符),可以在后面用sqlite3_bind 接口来填充这些值. 每一个通配符都被分配了一个编号(由它在SQL声明中的位置决定,从1开始),此外也可以用 "nnn" 来表示 "?nnn" 这种情况. 允许相同的通配符在同一个SQL声明中出现多次,在这种情况下所有相同的通配符都会被替换成相同的值. 没有被绑定的通配符将自动取NULL值.
    intsqlite3_bind_blob(sqlite3_stmt*,87); font-weight:bold">intn,85); font-weight:bold">void(*)(void*));
  • intsqlite3_bind_double(sqlite3_stmt*,87); font-weight:bold">double);
  • intsqlite3_bind_int(sqlite3_stmt*,87); font-weight:bold">int);
  • intsqlite3_bind_int64(sqlite3_stmt*,87); font-weight:bold">longintsqlite3_bind_null(sqlite3_stmt*,87); font-weight:bold">intsqlite3_bind_text(sqlite3_stmt*,87); font-weight:bold">intsqlite3_bind_text16(sqlite3_stmt*,87); font-weight:bold">intsqlite3_bind_value(sqlite3_stmt*,85); font-weight:bold">constsqlite3_value*);

  • 以上是 sqlite3_bind 所包含的全部接口,它们是用来给SQL声明中的通配符赋值的. 没有绑定的通配符则被认为是空值. 绑定上的值不会被sqlite3_reset()函数重置. 但是在调用了sqlite3_reset()之后所有的通配符都可以被重新赋值.
    在SQL声明准备好之后(其中绑定的步骤是可选的),需要调用以下的方法来执行:
    int sqlite3_step(sqlite3_stmt*);
    如果SQL返回了一个单行结果集,sqlite3_step() 函数将返回 SQLITE_ROW,如果SQL语句执行成功或者正常将返回 SQLITE_DONE,否则将返回错误代码. 如果不能打开数据库文件则会返回 SQLITE_BUSY . 如果函数的返回值是 SQLITE_ROW,那么下边的这些方法可以用来获得记录集行中的数据:
    void*sqlite3_column_blob(sqlite3_stmt*,87); font-weight:bold">intiCol);
  • intsqlite3_column_bytes(sqlite3_stmt*,87); font-weight:bold">intsqlite3_column_bytes16(sqlite3_stmt*,87); font-weight:bold">intsqlite3_column_count(sqlite3_stmt*);
  • char*sqlite3_column_decltype(sqlite3_stmt*,85); font-weight:bold">void*sqlite3_column_decltype16(sqlite3_stmt*,87); font-weight:bold">doublesqlite3_column_double(sqlite3_stmt*,87); font-weight:bold">intsqlite3_column_int(sqlite3_stmt*,87); font-weight:bold">intsqlite3_column_int64(sqlite3_stmt*,87); font-weight:bold">char*sqlite3_column_name(sqlite3_stmt*,85); font-weight:bold">void*sqlite3_column_name16(sqlite3_stmt*,85); font-weight:bold">constunsignedchar*sqlite3_column_text(sqlite3_stmt*,85); font-weight:bold">void*sqlite3_column_text16(sqlite3_stmt*,87); font-weight:bold">intsqlite3_column_type(sqlite3_stmt*,87); font-weight:bold">intiCol);
  • sqlite3_column_count()函数返回结果集中包含的列数. sqlite3_column_count() 可以在执行了 sqlite3_prepare()之后的任何时刻调用. sqlite3_data_count()除了必需要在sqlite3_step()之后调用之外,其他跟sqlite3_column_count() 大同小异. 如果调用sqlite3_step() 返回值是 SQLITE_DONE 或者一个错误代码,则此时调用sqlite3_data_count() 将返回 0 ,然而 sqlite3_column_count() 仍然会返回结果集中包含的列数.
    返回的记录集通过使用其它的几个 sqlite3_column_***() 函数来提取,所有的这些函数都把列的编号作为第二个参数. 列编号从左到右以零起始. 请注意它和之前那些从1起始的参数的不同.
    sqlite3_column_type()函数返回第N列的值的数据类型. 具体的返回值如下:
    #defineSQLITE_INTEGER1
  • #defineSQLITE_FLOAT2
  • #defineSQLITE_TEXT3
  • #defineSQLITE_BLOB4
  • #defineSQLITE_NULL5
  • sqlite3_column_decltype() 则用来返回该列在 CREATE TABLE 语句中声明的类型. 它可以用在当返回类型是空字符串的时候. sqlite3_column_name() 返回第N列的字段名. sqlite3_column_bytes() 用来返回 UTF-8 编码的BLOBs列的字节数或者TEXT字符串的字节数. sqlite3_column_bytes16() 对于BLOBs列返回同样的结果,但是对于TEXT字符串则按 UTF-16 的编码来计算字节数. sqlite3_column_blob() 返回 BLOB 数据. sqlite3_column_text() 返回 UTF-8 编码的 TEXT 数据. sqlite3_column_text16() 返回 UTF-16 编码的 TEXT 数据. sqlite3_column_int() 以本地主机的整数格式返回一个整数值. sqlite3_column_int64() 返回一个64位的整数. 最后,sqlite3_column_double() 返回浮点数.
    不一定非要按照sqlite3_column_type()接口返回的数据类型来获取数据. 数据类型不同时软件将自动转换.
    2.3 用户自定义函数
    可以使用以下的方法来创建用户自定义的SQL函数:
    structsqlite3_valuesqlite3_value;
  • intsqlite3_create_function(
  • sqlite3*,
  • char*zFunctionName,87); font-weight:bold">intnArg,87); font-weight:bold">inteTextRep,85); font-weight:bold">void(*xFunc)(sqlite3_context*,sqlite3_value**),85); font-weight:bold">void(*xStep)(sqlite3_context*,85); font-weight:bold">void(*xFinal)(sqlite3_context*)
  • );
  • intsqlite3_create_function16(
  • void*zFunctionName,250); line-height:18px"> #defineSQLITE_UTF81
  • #defineSQLITE_UTF162
  • #defineSQLITE_UTF16BE3
  • #defineSQLITE_UTF16LE4
  • #defineSQLITE_ANY5
  • nArg 参数用来表明自定义函数的参数个数. 如果参数值为0,则表示接受任意个数的参数. 用 eTextRep 参数来表明传入参数的编码形式. 参数值可以是上面的五种预定义值. SQLite3 允许同一个自定义函数有多种不同的编码参数的版本. 数据库引擎会自动选择转换参数编码个数最少的版本使用.
    普通的函数只需要设置 xFunc 参数,而把 xStep 和 xFinal 设为NULL. 聚合函数则需要设置 xStep 和 xFinal 参数,然后把 xFunc 设为NULL. 该方法和使用sqlite3_create_aggregate() API一样.
    sqlite3_create_function16()和sqlite_create_function()的不同就在于自定义的函数名一个要求是 UTF-16 编码,而另一个则要求是 UTF-8.
    请注意自定函数的参数目前使用了sqlite3_value结构体指针替代了SQLite version 2.X中的字符串指针. 下面的函数用来从sqlite3_value结构体中提取数据:
    void*sqlite3_value_blob(sqlite3_value*);
  • intsqlite3_value_bytes(sqlite3_value*);
  • intsqlite3_value_bytes16(sqlite3_value*);
  • doublesqlite3_value_double(sqlite3_value*);
  • intsqlite3_value_int(sqlite3_value*);
  • intsqlite3_value_int64(sqlite3_value*);
  • char*sqlite3_value_text(sqlite3_value*);
  • void*sqlite3_value_text16(sqlite3_value*);
  • intsqlite3_value_type(sqlite3_value*);
  • Java代码
    上面的函数调用以下的API来获得上下文内容和返回结果:
    void*sqlite3_aggregate_context(sqlite3_context*,87); font-weight:bold">intnbyte);
  • void*sqlite3_user_data(sqlite3_context*);
  • voidsqlite3_result_blob(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_double(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_error(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_error16(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_int(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_int64(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_null(sqlite3_context*);
  • voidsqlite3_result_text(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_text16(sqlite3_context*,85); font-weight:bold">voidsqlite3_result_value(sqlite3_context*,sqlite3_value*);
  • void*sqlite3_get_auxdata(sqlite3_context*,85); font-weight:bold">voidsqlite3_set_auxdata(sqlite3_context*,85); font-weight:bold">void*));
  • 2.4 用户自定义排序规则
    下面的函数用来实现用户自定义的排序规则:
    sqlite3_create_collation(sqlite3*,87); font-weight:bold">char*zName,87); font-weight:bold">int(*xCompare)( sqlite3_create_collation16(sqlite3*,85); font-weight:bold">void*zName,250); line-height:18px"> sqlite3_collation_needed(sqlite3*,sqlite3*,87); font-weight:bold">char*));
  • sqlite3_collation_needed16(sqlite3*,sans-serif; font-size:14px; line-height:25.200000762939453px">sqlite3_create_collation() 函数用来声明一个排序序列和实现它的比较函数. 比较函数只能用来做文本的比较. eTextRep 参数可以取如下的预定义值 SQLITE_UTF8,SQLITE_UTF16LE,SQLITE_UTF16BE,SQLITE_ANY,用来表示比较函数所处理的文本的编码方式. 同一个自定义的排序规则的同一个比较函数可以有 UTF-8,UTF-16LE 和 UTF-16BE 等多个编码的版本. sqlite3_create_collation16()和sqlite3_create_collation() 的区别也仅仅在于排序名称的编码是 UTF-16 还是 UTF-8.
    可以使用 sqlite3_collation_needed() 函数来注册一个回调函数,当数据库引擎遇到未知的排序规则时会自动调用该函数. 在回调函数中可以查找一个相似的比较函数,并激活相应的sqlite_3_create_collation()函数. 回调函数的第四个参数是排序规则的名称,同样sqlite3_collation_needed采用 UTF-8 编码. sqlite3_collation_need16() 采用 UTF-16 编码.
    -----------------------------------------------------
    SQLite 不支持的 SQL 特性
    相对于试图列出 SQLite 支持的所有 SQL92 特性,只列出不支持的部分要简单得多。下面显示的就是 SQLite 所不支持的 SQL92 特性。
    这个列表的顺序关系到何时一个特性可能被加入到SQLite。接近列表顶部的特性更可能在不远的将来加入。接近列表底部的特性尚且没有直接的计划。
    外键约束(FOREIGN KEY constraints)
    外键约束会被解析但不会被执行。
    完整的触发器支持(Complete trigger support)
    现在有一些触发器的支持,但是还不完整。 缺少的特性包括 FOR EACH STATEMENT 触发器(现在所有的触发器都必须是 FOR EACH ROW ), 在表上的 INSTEAD OF 触发器(现在 INSTEAD OF 触发器只允许在视图上), 以及递归触发器——触发自身的触发器。
    完整的 ALTER TABLE 支持(Complete ALTER TABLE support)
    只支持 ALTER TABLE 命令的 RENAME TABLE 和 ADD COLUMN。 其他类型的 ALTER TABLE 操作如 DROP COLUMN,ALTER COLUMN,ADD CONSTRAINT 等等均被忽略。
    嵌套事务(Nested transactions)
    现在的实现只允许单一活动事务。
    RIGHT 和 FULL OUTER JOIN(RIGHT and FULL OUTER JOIN)
    LEFT OUTER JOIN 已经实现,但还没有 RIGHT OUTER JOIN 和 FULL OUTER JOIN。
    可写视图(Writing to VIEWs)
    SQLite 中的视图是只读的。无法在一个视图上执行 DELETE,INSERT,UPDATE。 不过你可以创建一个试图在视图上 DELETE,INSERT,UPDATE 时触发的触发器,然后在触发器中完成你所需要的工作。
    GRANT 和 REVOKE(GRANT and REVOKE)
    由于 SQLite 读和写的是一个普通的磁盘文件, 因此唯一可以获取的权限就是操作系统的标准的文件访问权限。 一般在客户机/服务器架构的关系型数据库系统上能找到的 GRANT 和 REVOKE 命令对于一个嵌入式的数据库引擎来说是没有意义的, 因此也就没有去实现。
    -------------------------------
    ---------------------------------------------------------------------------------
    SQLite第三版中的数据类型
    1.存储类别
    第二版把所有列的值都存储成ASCII文本格式。第三版则可以把数据存储成整数和实数,还可以存储BLOB数据.
    Each value stored in an SQLite数据库中存储的每个值都有一个属性,都属于下面所列类中的一种,(被数据库引擎所控制)
    空.这个值为空值
    整数.值被标识为整数,依据值的大小可以依次被存储为1,2,3,4,5,6,7,8.
    实数. 所有值都是浮动的数值,被存储为8字节的IEEE浮动标记序号.
    文本. 值为文本字符串,使用数据库编码存储(TUTF-8,UTF-16BE or UTF-16-LE).
    BLOB. 值是BLOB数据,如何输入就如何存储,不改变格式.
    像SQLite2.0版一样,在3.0版中,除了INTEGER PRIMARY KEY,数据库中的任何列都可以存储任何类型的数据.这一规则也有例外,在下面的"严格相似模式"中将描述.
    输入SQLite的所有值,不管它是嵌入 SQL语句中的文字还是提前编译好的绑定在SQL语句中的值,在SQL语句执行前都被存储为一个类.在下面所描述的情况下,数据库引擎将在执行时检查并把值在数字存储类(整数和实数)和文本类间转换.
    存储的类别最初被分类为如下:
    具体的值比如SQL语句部分的带双引号或单引号的文字被定义为文本,如果文字没带引号并没有小数点或指数则被定义为整数,如果文字没带引号但有小数点或指数则被定义为实数,如果值是空则被定义为空值.BLOB数据使用符号X'ABCD'来标识.
    Values supplied using the 被输入的值使用sqlite3_bind_* APIs的被分类一个存储等级,这等级是和原来的类基本相一致的. (比如sqlite3_bind_blob()绑定一个BLOB的值).
    值的分类是SQL分等级操作的结果,决定于最远的操作表达式.用户定义的功能也许会把值返回任意的类.在编译的时候来确定表达式的存储类基本是不可能的.
    2. 列之间的亲和性
    在SQLite3.0版中,值被定义为什么类型只和值自身有关,和列没有关系,和变量也没有关系. (这有时被称作
    弱类型.)所有其它的我们所使用的数据库引擎都受静态类型系统的限制,其中的所有值的类是由其所属列的属性决定的,而和值无关.
    为了最大限度的增加SQLite数据库和其他数据库的兼容性,SQLite支持列的"类型亲和性". 列的亲和性是为该列所存储的数据建议一个类型.我们要注意是建议而不是强迫.在理论上来讲,任何列依然是可以存储任何类型的数据的. 只是针对某些列,如果给建议类型的话,数据库将按所建议的类型存储.这个被优先使用的数据类型则被称为"亲和类型".
    文本
    数字的
    整数

    一个具有类型亲和性的列按照无类型,文本,或BLOB存储所有的数据.如果数字数据被插入一个具有文本类型亲和性的列,在存储之前数字将被转换成文本.
    一个具有数字类型亲和性的列也许使用所有的五个存储类型存储值.当文本数据被插入一个数字列时,在存储之前,数据库将尝试着把文本转换成整数或实数.如果能成功转换的话,值将按证书活实数的类型被存储. 如果不能 成功转换的话,值则只能按文本类型存储了,而不会被转换成无类型或BLOB类型来存储.
    一个具有整数亲和力的列在转换方面和具有数字亲和力的列是一样的,但也有些区别,比如没有浮动量的实值(文本值转换的值)被插入具有整数亲和力的列时,它将被转换成整数并按整数类型存储.
    一个具有无类型亲和力的列不会优先选择使用哪个类型.在数据被输入前它不会强迫数据转换类型.
    2.1 列的亲和性的决定
    一个列的亲和类型是由该列所宣称的类型决定的.遵守以下规则:
    如果数据类型包括字符串"INT"那么它被定义成具有整数亲和性.
    如果列中的数据类型包括以下任何的字符串 "CHAR","CLOB",or "TEXT" 那么这个列则具有文本亲和性.要注意VARCHAR类型包括字符串"CHAR"因此也具有文本类型亲和性.
    如果一个列的数据类型包括字符串"BLOB"或者如果数据类型被具体化了,那么这个列具有无类型亲和性.
    否则就具有数字类型亲和性.
    如果表格使用If "CREATE TABLE AS SELECT..."语句生成的,那么所有的列则都没有具体的数据类型,则没有类型亲和性.
    2.2 列的亲和性的例子
    Sql代码
      CREATETABLEt1(
    1. tTEXT,250); line-height:18px"> nuNUMERIC,250); line-height:18px"> iINTEGER,85); font-weight:bold">noBLOB
    2. --Storageclassesforthefollowingrow:
    3. --TEXT,REAL,INTEGER,TEXT
    4. INSERTINTOt1VALUES('500.0','500.0','500.0');
    5. VALUES(500.0,500.0,500.0);
    3.比较表达式
    比较的结果决定于被比较的两个值的存储类型。遵循以下规则:
    一个具有空存储类型的值被认为小于任何值(包括另外一个具有空存储类型的值)。
    一个整数值或实数值小于任何文本值和BLOB值。 当一个整数或实数和另一个整数或实数相比较的时候,则按照实际数值来比较。
    一个文本值小于BLOB值。当两个文本值相比较的时候,则用C语言类库中的memcmp()函数来比较。然而,有时候也不是这样的,比如在下面所描述的“用户定义的整理顺序”情况下。
    当两个BLOB文本被比较的时候,结果决定于memcmp()函数。
    在开始比较前,SQLite尝试着把值在数字存储级(整数和实数)和文本之间相互转换。下面列举了关于如何比较二进制值的例子。在着重号below中使用的表达式可以表示SQL标量表达式或是文本但不是一个列值。
    当一个列值被比拟为表达式结果的时候,在比较开始前,列的亲和性将被应用在表达结果中。
    当两个列值比较的时候,如果一个列有整数或数字亲和性的时候,而另外一列却没有,那么数字亲和性适用于从非数字列提取的任何具有文本存储类型的值. P>
    当比较两个表达式的结果时,不发生任何转换,直接比较结果.如果一个字符串和一个数字比较,数字总是小于字符串.
    在SQLite中,表达式"a BETWEEN b AND c"等于表达式 "a >= b AND a <= c",在比较表达式时,a可以是具有任何亲和性.
    表达式 "a IN (SELECT b ....)" 在比较时遵循上面所提到的三条规则,是二进制比较.(例如,在一个相似的样式 "a = b"). 例如,如果'b'是一个列值,'a' 是一个表达式,那么,在开始比较前,'b'的亲和性就被转换为'a'的亲和性了.
    SQLite把表达式 "a IN (x,y,z)" 和 "a = z OR a = y OR a = z"视为相等.
    3.1 比较例子
    CREATETABLEt1(
  • aTEXT,250); line-height:18px"> bNUMERIC,250); line-height:18px"> cBLOB
  • --Storageclassesforthefollowingrow:
  • --TEXT,TEXT
  • INSERTINTOt1VALUES('500','500','500');
  • --60and40areconvertedto'60'and'40'andvaluesarecomparedasTEXT.
  • SELECTa<60,a<40FROMt1;
  • 1|0
  • --Comparisonsarenumeric.Noconversionsarerequired.
  • SELECTb<60,b<600FROMt1;
  • 0|1
  • --Both60and600(storageclassNUMERIC)arelessthan'500'
  • --(storageclassTEXT).
  • SELECTc<60,c<600FROMt1;
  • 0|0
  • 4. 运算符
    所有的数学运算符(所有的运算符而不是连锁作用标记符"||")运算对象首先具有数字亲和性,如果一个或是两个都不能被转换为数字那么操作的结果将是空值。
    对于连接作用操作符,所有操作符将首先具有文本亲和性。如果其中任何一个操作符不能被转换为文本(因为它是空值或是BLOB)连接作用操作符将是空值。
    5. 分类,排序,混合挑选
    当用子句ORDER挑选值时,空值首先被挑选出来,然后是整数和实数按顺序被挑选出来,然后是文本值按memcmp()顺序被挑选出来,最后是BLOB值按memcmp()顺序被挑选出来.在挑选之前,没有存储类型的值都被转换了.
    When grouping values with the 当用GROUP BY子句给值分组时,具有不同存储类型的值被认为是不同的,但也有例外,比如,一个整数值和一个实数值从数字角度来说是相等的,那么它们则是相等的.用GROUP by 子句比较完后,值不具有任何亲和性.
    混合挑选操作符UNION,INTERSECT and EXCEPT 在值之间实行绝对的比较,同样的亲和性将被应用于所有的值,这些值将被存储在一个单独的具有混合SELECT的结果组的列中. 被赋予的亲和性是该列的亲和性,这个亲和性是由剩下的大部分的混合SELECTS返回的,这些混合SELECTS在那个位置上有列值(而不是其它类型的表达式). 如果一个给定的混合SELECT列没有SELECTS的量,那么在比较前,该列的值将不具有任何亲和性.
    6. 其它亲和性模式
    以上的部分所描述的都是数据库引擎在正常亲和性模式下所进行的操作,SQLite将描述其它两种亲和性模式,如下:
    严格亲和性模式.在这种模式下,如果需要值之间相互转换数据存储类型的话,数据库引擎将发送错误报告,当前语句也将会重新运行.
    无亲和性模式.在这种模式下,值的数据存储类型不发生转换.具有不同存储类型的值之间不能比较,但整数和实数之间可以比较.
    7.用户定义的校对顺序
    By default,when 当SQLite比较两个文本值的时候,通过系统设定,不管字符串的编码是什么,用memcmp()来比较. SQLite第三版允许用户提供任意的函数来代替memcmp(),也就是用户定义的比较顺序.
    除了系统预设的BINARY比较顺序,它是用memcmp()函数比较,SQLite还包含了两个额外的内置比较顺序函数,NOCASE和REVERSE:
    BINARY -使用memcmp()比较字符串数据,不考虑文本编码.
    REVERSE -用倒序比较二进制文本.
    NOCASE - 和二进制一样,但在比较之前,26位的大写字母盘要被折合成相应的小写字母盘.
    7.1 分配比较顺序
    每个表格中的每个列都有一个预设的比较类型.如果一个比较类型不是二进制所要求的,比较的子句将被具体化为 列的定义 来定义该列.
    当用SQLite比较两个文本值时,比较顺序将按照以下的规则来决定比较的结果.文档的第三部分和第五部分描述在何种场合下发生这种比较.
    对于二进制比较符(=,<,>,<= and >=),如果每个操作数是一列的话,那么该列的默认比较类型决定于所使用的比较顺序. 如果两个操作数都是列的话,那么左边的操作数的比较类型决定了所要使用的比较顺序.如果两个操作数都不是一列,将使用二进制来比较.
    表达式"x BETWEEN y and z"和 "x >= y AND x <= z"是相同的. 表达式"x IN (SELECT y ...)" 和表达式 "x = y" 使用同样的方法来操作,这是为了决定所要使用的比较顺序.如果X是一列或者二进制的,则"x IN (y,z ...)" 形式的表达式所使用的比较顺序是X的默认的比较类型.
    ORDER BY clause that is part of a SELECT statement may be assigned a collation sequence to be used for the sort operation explicitly. In this case the explicit collation sequence is always used. Otherwise,if the expression sorted by an ORDER BY clause is a column,then the default collation type of the column is used to determine sort order. If the expression is not a column,then the BINARY collation sequence is used.
    7.2 比较顺序的例子
    下面的例子介绍了The examples below identify the collation sequences that would be used to determine the results of text comparisons that may be performed by various SQL statements. Note that a text comparison may not be required,and no collation sequence used,in the case of numeric,blob or NULL values.
    a,--defaultcollationtypeBINARY
  • bCOLLATEBINARY,250); line-height:18px"> cCOLLATEREVERSE,0); padding:0px; margin:0px; width:auto; border:0px">--defaultcollationtypeREVERSE
  • dCOLLATENOCASE--defaultcollationtypeNOCASE
  • --TextcomparisonisperformedusingtheBINARYcollationsequence.
  • SELECT(a=b)FROMt1;
  • --TextcomparisonisperformedusingtheNOCASEcollationsequence.
  • SELECT(d=a)SELECT(a=d)--TextcomparisonisperformedusingtheREVERSEcollationsequence.
  • SELECT('abc'=c)SELECT(c='abc')--GroupingisperformedusingtheNOCASEcollationsequence(i.e.values
  • --'abc'and'ABC'areplacedinthesamegroup).
  • SELECTcount(*)GROUPBYd--GroupingisperformedusingtheBINARYcollationsequence.
  • BY(d||'')--SortingisperformedusingtheREVERSEcollationsequence.
  • SELECT*FROMt1ORDERBYc;
  • --SortingisperformedusingtheBINARYcollationsequence.
  • BY(c||'');
  • --SortingisperformedusingtheNOCASEcollationsequence.
  • BYcCOLLATENOCASE;
  • 版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


    SQLite架构简单,又有Json计算能力,有时会承担Json文件/RESTful的计算功能,但SQLite不能直接解析Json文件/RESTful,需要用Java代码硬写,或借助第三方类库,最后再拼成insert语句插入数据表,代码非常繁琐,这里就不展示了。参考前面的代码可知,入库的过程比较麻烦,不能只用SQL,还要借助Java或命令行。SPL是现代的数据计算语言,属于简化的面向对象的语言风格,有对象的概念,可以用点号访问属性并进行多步骤计算,但没有继承重载这些内容,不算彻底的面向对象语言。...
    使用Python操作内置数据库SQLite以及MySQL数据库。
    破解微信数据库密码,用python导出微信聊天记录
    (Unity)SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。本教程将告诉您如何使用 SQLite 编程,并让你迅速上手。.................................
    安卓开发,利用SQLite实现登陆注册功能
    相比大多数数据库而言,具有等优势,广泛应用于、等领域。
    有时候,一个项目只有一个数据库,比如只有SQLite,或者MySQL数据库,那么我们只需要使用一个固定的数据库即可。但是一个项目如果写好了,有多个用户使用,但是多个用户使用不同的数据库,这个时候,我们就需要把软件设计成可以连接多个数据库的模式,用什么数据库,就配置什么数据库即可。4.Users实体类,这个实体类要和数据库一样的,形成一一对应的关系。11.Sqlite数据库,需要在代码里面创建数据库,建立表,再建立数据。8.我们开启MySQL数据库,然后进行调试,看程序的结果。2.安装SqlSugar。
    基于Android的背单词软件,功能强大完整。
    SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统。说白了就是使用起来轻便简单,
    Android的简单购物车案例
    SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库...
    Qt设计较为美观好看的登录注册界面(包含SQLite数据库以及TCP通信的应用)
    SQLite是用C语言开发的跨平台小型数据库,可嵌入其他开发语言,也可在单机执行。SPL是用Java开发的跨平台的数据计算语言,可嵌入Java,可在单机执行,可以数据计算服务的形式被远程调用。两者的代码都是解释执行的。...
    新建库.openDATA_BASE;新建表createtableLIST_NAME(DATA);语法:NAME关键字...<用逗号分割>删除表droptableNAME;查看表.schema查看表信息新建数据insertintoLIST_NAMEvalues();语法:CLASS,PARAMETER...,CLASS是类别,PARAMETER是参数<用逗号分割新建的
    importsqlite3classDemo01:def__init__(self):self.conn=sqlite3.connect("sql_demo_001.db")self.cursor1=self.conn.cursor()self.cursor1.execute("select*fromtable_001wherename=?andid=?",('ssss&#0
     在客户端配置文件<configuration>节点下,添加:<connectionStrings>      <add name="localdb" connectionString="Data Source=config/local.db;Version=3;UseUTF16Encoding=True;" providerName="System.Data.SQLite.SQLiteFactory"/&g
    提到锁就不得不说到死锁的问题,而SQLite也可能出现死锁。下面举个例子:连接1:BEGIN(UNLOCKED)连接1:SELECT...(SHARED)连接1:INSERT...(RESERVED)连接2:BEGIN(UNLOCKED)连接2:SELECT...(SHARED)连接1:COMMIT(PENDING,尝试获取EXCLUSIVE锁,但还有SHARED锁未释放,返回SQLITE_BUSY)连接2:INSERT...
    SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成。Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表
    设计思想————首先要确定有几个页面、和每个页面的大致布局由于是入门,我也是学习了不是很长的时间,所以项目比较low。。。。第一个页面,也就是打开APP的首页面:今天这个博客,先实现添加功能!:首先对主界面进行布局:其中activity_main.xml的代码为<?xmlversion="1.0"encoding="