c语言sqlite
㈠ c璇瑷涓璁块梾鏁版嵁搴挞兘鐢ㄥ埌浜嗗摢浜涚被锛
鍦–璇瑷涓锛岃块梾鏁版嵁搴挞氩父娑夊强浣跨敤鏁版嵁搴撴搷浣滃簱锛岃繖浜涘簱鎻愪緵浜嗕竴浜涚被鍜屽嚱鏁版潵镓ц屾暟鎹搴撴搷浣溿傛渶甯哥敤镄勬暟鎹搴撴搷浣滃簱鏄疧DBC锛圤pen Database Connectivity锛夛纴瀹冨厑璁镐娇鐢ㄦ爣鍑嗙殑API鎺ュ彛𨱒ヨ繛鎺ュ拰镎崭綔涓嶅悓绫诲瀷镄勬暟鎹搴撱备互涓嬫槸鍦–璇瑷涓璁块梾鏁版嵁搴撴椂鍙鑳芥秹鍙婄殑涓浜涚被鍜岀浉鍏虫傚康锛
1. **ODBC API锛** ODBC API鏄鏁版嵁搴撹块梾镄勬牳蹇冿纴瀹冩彁渚涗简涓绯诲垪鍑芥暟鐢ㄤ簬杩炴帴鏁版嵁搴撱佹墽琛孲QL镆ヨ銆佽幏鍙栨煡璇㈢粨鏋灭瓑镎崭綔銆
2. **鏁版嵁搴撹繛鎺ョ被锛** 鏁版嵁搴撹繛鎺ョ被鐢ㄤ簬寤虹珛鍜岀$悊涓庢暟鎹搴撶殑杩炴帴銆傚湪ODBC涓锛屽彲浠ヤ娇鐢╜sqlHDBC`鏁版嵁绫诲瀷琛ㄧず鏁版嵁搴撹繛鎺ュ彞镆勚
3. **SQL璇鍙ユ墽琛岀被锛** 杩欎簺绫荤敤浜庢墽琛孲QL镆ヨ㈣鍙ワ纴鍖呮嫭SELECT銆両NSERT銆乁PDATE銆丏ELETE绛夈傚彲浠ヤ娇鐢╜SQLExecDirect`鍑芥暟镓ц孲QL璇鍙ャ
4. **缁撴灉闆嗙被锛** 褰撴墽琛孲ELECT镆ヨ㈡椂锛屼细鐢熸垚涓涓缁撴灉闆嗭纴琛ㄧず镆ヨ㈢粨鏋溿傚彲浠ヤ娇鐢╜SQLHSTMT`鏁版嵁绫诲瀷琛ㄧず缁撴灉闆嗗彞镆勶纴骞朵娇鐢╜SQLFetch`鍑芥暟銮峰彇缁撴灉闆嗕腑镄勬暟鎹銆
5. **阌栾澶勭悊绫伙细** 鐢ㄤ簬澶勭悊鏁版嵁搴撴搷浣滀腑镄勯敊璇鍜屽纾甯搞傚彲浠ヤ娇鐢╜SQLHENV`鏁版嵁绫诲瀷琛ㄧず鐜澧冨彞镆勶纴骞朵娇鐢╜SQLError`鍑芥暟銮峰彇阌栾淇℃伅銆
6. **鍙傛暟鍖栨煡璇㈢被锛** 鐢ㄤ簬镓ц屽弬鏁板寲镄凷QL镆ヨ锛岄槻姝SQL娉ㄥ叆绛夊畨鍏ㄩ梾棰樸
7. **浜嫔姟绠$悊绫伙细** 鐢ㄤ簬绠$悊鏁版嵁搴撶殑浜嫔姟镎崭綔锛屽寘𨰾鎻愪氦鍜屽洖婊氢簨锷°
8. **鏁版嵁搴撹繛鎺ユ睁绫伙细** 鏁版嵁搴撹繛鎺ユ睁鐢ㄤ簬绠$悊澶氢釜鏁版嵁搴撹繛鎺ワ纴鎻愰珮镐ц兘鍜岃祫婧愬埄鐢ㄧ巼銆
闇瑕佹敞镒忕殑鏄锛孋璇瑷链韬骞舵病链夌被镄勬傚康锛岃屾槸浣跨敤缁撴瀯浣撱佹寚阍埚拰鍑芥暟绛夋潵瀹炵幇闱㈠悜瀵硅薄镄勫姛鑳姐傛暟鎹搴撴搷浣滃簱浼氭彁渚涗竴浜涙暟鎹绫诲瀷鍜屽嚱鏁版潵灏佽呮暟鎹搴撶浉鍏虫搷浣滐纴浣呜繖浜涘苟涓嶆槸浼犵粺镒忎箟涓婄殑绫汇傚湪瀹为檯寮鍙戜腑锛屽彲浠ユ牴鎹镓浣跨敤镄勬暟鎹搴撴搷浣滃簱镄勬枃妗e拰绀轰緥𨱒ヤ简瑙e备綍杩涜屾暟鎹搴撴搷浣溿
㈡ 如何编译SQLite-How To Compile SQLite
SQLite是ANSI-C的源代码。在使用之前必须要编译成机器码。这篇文章是用于各种编译SQLite方法的指南。
这篇文章不包含编译SQLite的每个步骤的反馈,那样可能会困难因为每种开发场景都不同。所以这篇文章描述和阐述了编译Sqlite的原则。典型的编译命令已经作为例子提供了,以期望应用开发者能够使用这些例子作为完成他们自己定制的编译过程的的一个指南。换句话说,这篇文章提供了想法和见解,而不是交钥匙的解决方法。
融合VS单独源文件
Sqlite是由超过一百个c源码文件以及众多的目录下的脚本构建的。Sqlite的实现是纯粹的ANSI-C,但是许多c语言源代码文件是由辅助的C程序生成或者转换来的,并且AWK,SED和TCL脚本会融合到完成的sqlite库中。对Sqlite构建需要的C程序和转换和创建C语言源码是一个复杂的过程。
为了简化这些,sqlite也通过一个预打包的合并后的源码文件:sqlite3.c。这个合并文件是一个ANSI-C源码实现整个SQLite库的唯一文件。合并后的文件更容易处理。所有的东西都包含在这一个文件里,所以很容易进入一个更大的C或者C++程序的源码树。所有的代码生成和转换步骤都已经实现了,因此没有辅助的C程序需要去配置和变异,也没有脚本需要去运行。并且,因此所有哭都包含在一个翻译单元,编译器可以做更多高级的优化从而提升5%到10%的性能。因为这些原因,融合后的源码文件sqlite3.c对所有程序来讲都是值得推荐的。
推荐所有的应用程序使用融合文件。
直接从单独的源码文件中构建sqlite当然可以,但是并不推荐。对一些特殊的应用程序,可能需要修改构建程序去处理使用那些从网站上下载的预构建的源码文件不能完成的情况。对于这些情况,推荐构建和使用一个定制过的合并文件。换句话说,即使一个工程需要以单独的源码文件构建sqlite,仍然推荐使用一个融合后的源码文件作为一个中间步骤。
编译命令行接口(CLI)
构建命令行接口需要三个源码文件:
sqlite3.c:Sqlite融合的源码文件
sqlite3.h:匹配sqlite3.c以及定义sqlite的c语言接口的头文件
shell.c:命令行接口程序本身。这个c源码文件包含一个main()的例程和每轮循环的用户输入的提示符并将输入传给sqlite数据库引擎用于处理。
所有的上述源码的三个文件都被包含在下载页面的amalgamation tarball中。
为了构建CLI,简单的将这三个文件放置在相同的目录下然后一起编译他们。用MSVC:
cl shell.c sqlite3.c -Fesqlite3.exe
在unix系统上(或者在windows上用cygwin或者mingw+msys)典型的命令会有些像这样:
gcc shell.c sqlite3.c -lpthread -ldl
为了SQLite线程安全,需要pthreads库。但是因为CLI是一个单线程的,我们可以指示SQLite构建一个非线程安全的库并因此护绿pthreads库:
gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl
-ldl库是在支持动态装载时需要,例如sqlite3_load_extension() 接口和load_extension()
SQL function。如果这些特性都不要求,那么我们也可以使用SQLITE_OMIT_LOAD_EXTENSION编译时间选项忽略他们。
gcc -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c
有人可能想要提供其他的编译时间选项(compile-time options),例如SQLITE_ENABLE_FTS3去全文本搜索或者SQLITE_ENABLE_RTREE用于R*树搜索引擎扩展。而有人将正常指定一些编译优化开关。(预编译的CLI可以从选择sqlite网站上使用“-Os”下载下来)有无数种可能的变数在这里。
关键点在这里:构建CLI需要编译一起两个C语言文件。shell.c文件包含入口的定义和用户输入的loop,而sqlite融合文件sqlite3.c包含完整的sqlite库的实现。
编译TCL接口
sqlite的tcl接口是一个小的模块被添加到一般的融合文件中。结果是一个新的融合后的源码文件,称之为“tclsqlite3.c”。这个源码文件是生成一个可以使用TCL
load命令去加载到一个标准的tclsh或者wish中,或者随着sqlite构建成功生成一个单独唯一的tclsh的共享库所需要的。一个tcl的融合的副本被包含在下载页的TEA
tarball中作为一个文件。
为了生成一个linux上的sqlite的TCL-loadable库,下面的命令需要满足:
gcc -o libtclsqlite3.so -shared tclsqlite3.c -lpthread -ldl -ltcl
不幸的是构建Mac OS X 和 Windows的共享库并不是如此简单。对于这些平台最好使用包含在TEA tarball中的configure脚本和makefile.
为了生成一个单独的tclsh,可以用于sqlite静态链接,使用如下的编译器调用:
gcc -DTCLSH=1 tclsqlite3.c -ltcl -lpthread -ldl -lz -lm
这里的技巧是-DTCLSH=1选项。sqlite的TCL接口模块包含一个main的过程,用于初始化一个TCL解释器并在以-DTCLSH=1编译后进入到一个命令行loop。上述命令可以工作在Linux和Mac
OS X,虽然有时可能需要依赖于平台调整库选项以及编译的TCL的哪一个版本。
构建融合文件
下载页提供的sqlite融合文件的版本对大多数用户来说是足够的。然而,一些工程可能想要或者需要构建他们自己的融合文件。一个常见的构建一个定制的融合文件的理由是为了使用特定的compile-time options来定制sqlite库。回想sqlite融合文件中包含了许多C代码由辅助程序和脚本生成。许多的编译时间选项影响这一成圣代码而且必须在融合文件组装前提供给代码生成器。这一系列必须传给代码生成器的编译时间相关的选项会使得sqlite的发布版本各不相同,但是在写这边文章的时候,代码生成器需要知道的这组选项包括:
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
SQLITE_OMIT_ALTERTABLE
SQLITE_OMIT_ANALYZE
SQLITE_OMIT_ATTACH
SQLITE_OMIT_AUTOINCREMENT
SQLITE_OMIT_CAST
SQLITE_OMIT_COMPOUND_SELECT
SQLITE_OMIT_EXPLAIN
SQLITE_OMIT_FOREIGN_KEY
SQLITE_OMIT_PRAGMA
SQLITE_OMIT_REINDEX
SQLITE_OMIT_SUBQUERY
SQLITE_OMIT_TEMPDB
SQLITE_OMIT_TRIGGER
SQLITE_OMIT_VACUUM
SQLITE_OMIT_VIEW
SQLITE_OMIT_VIRTUALTABLE
为了构建一个定制的融合文件,先下载原始的独立源码文件到一个unix或者类unix开发平台。确定获取的原始源码文件不是“预编译过的源文件”。任何人都可以通过到下载页或者直接从configuration management system.获取完整的一套原始源码文件。
假设sqlite源码树被存在一个名为“sqlite”的目录下。计划构建一个平行目录下的名为“bld”的融合文件。首先通过运行sqlite源码树种的configure脚本运行或者通过制作一份源码树顶层的的makfile模板的一份,来构建一个合适的makefile.然后手动编辑这个Makfile去包含需要的编译时间相关的选项。最终运行:
make sqlite3.c
在windows上使用MSVC:
nmake /f Makefile.msc sqlite3.c
sqlite3.c的make
target会自动构造一般的“sqlite3.c”合并的源码文件,以及它的头文件“sqlite3.h”,和包含TCL接口的融合源码文件“tclsqlite3.c”。之后,需要的文件可以被拷贝到文件目录下然后根据上述勾勒的过程编译。
构建一个windows的动态链接库DLL
为了在windows构建一个sqlite的dll使用,首先获取对应的融合过的源码文件,sqlit3.c和sqlite.h。这些可以从SQLite website上下载或者和上述告知的一样去定制生成。
使用工作目录下的源码文件,一个dll可以在msvc中使用如下命令生成:
cl sqlite3.c -link -dll -out:sqlite3.dll
上述命令需要运行在msvc的MSVC Native Tools Command
Prompt.如何你已经在机器上安装了msvc,你可能有多个版本的这种命令提示符,针对于x86和x64的自带构建的,或者交叉编译到ARM的。依赖要求的DLL去使用对应合适的命令提示符工具。
如果使用MinGW编译器,命令是这样的:
gcc -shared sqlite3.c -o sqlite3.dll
注意MinGW只生成32位的dll。另有一个分开的MinGW64工程可以用来生成64位的dll。可以推断其命令行语法是类似的。需要注意的是最近的MSVC的版本生成的DLLs可能不能工作到WinXP或者更早版本的windows上。因此为了最大限度的兼容你的生成的dll,推荐MinGW。一个好的经验法则是使用MinGW去生成32位的dlls,使用msvc去生成64位的dlls。
㈢ 玩转SQLite-11:C语言高效API之sqlite3_prepare系列函数
SQLite数据库是一个轻量级的数据库,其C/C++开发支持使其适用于嵌入式系统。本文将介绍一种更为高效的使用SQLite的方法,与上一篇文章中介绍的简单实例相比,这种方式能提供更好的性能。
传统的使用方法是通过sqlite3_exec函数来执行SQL语句。它将SQL命令字符串与对应的回调函数结合在一起。然而,这种做法存在效率问题,因为解析和编译操作在每次调用时都需重复进行,降低了执行效率。
为了提高效率,引入了sqlite3_prepare_v2函数。通过该函数,可以将SQL语句解析和编译为可以重复执行的实例,从而大大减少了解析和编译的次数。这意味着在重复执行SQL查询时,性能得到了显着提升。
在使用sqlite3_prepare_v2时,还需使用sqlite3_bind函数来绑定变量值到预处理语句中。先创建并初始化一个sqlite3_stmt变量,然后通过sqlite3_bind_xxx函数对变量进行参数绑定。
对于SQL查询的结果,可以使用sqlite3_step函数来执行查询并获取结果。返回值与错误码相关,用于检查执行状态。
在执行完查询后,sqlite3_reset函数用于将准备语句重置到初始状态,以便重新执行。此操作不会改变绑定值,可能用于重置到某个特定状态。
查询结果的特定列可以通过sqlite3_column函数获取。该函数用于查询结果集并返回特定列的数据。
本文总结了高效API函数的核心点,并介绍了这些函数的使用方法。下一篇文章将通过实际案例,展示这些函数如何在实践中提高性能。
㈣ SQLITE数据库C语言API 想使当数据库不存在时 sqlite3_open 不创建数据库
改用sqlite3_open_v2函数打开
int sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags,const char *zVfs);
前两个参数与sqllite3_open一样,flags设置为SQLITE_OPEN_READWRITE,如果数据库不存在就不创建,只返回一个error
参数zVfs允许应用程序命名一个虚拟文件系统(Virtual File System)模块,用来与数据库连接。VFS作为SQlite library和底层存储系统(如某个文件系统)之间的一个抽象层,通常客户应用程序可以简单的给该参数传递一个NULL指针,以使用默认的VFS模块。