MFC中,如何连接sqlite3的数据库,并对此数据库操作??

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC中,如何连接sqlite3的数据库,并对此数据库操作??相关的知识,希望对你有一定的参考价值。

这个比较容易。按照网上提供的方法把sqlite编译成dll和lib
将dll和lib在项目的输入中添加好
在要操作的文件中#include “sqlite3.h”就可以了。我做过这方面的项目,虽然是嵌入式wince使用,但是基本和windows相同。
下面是详细的用法:
一. 编译动态链接库库文件
1). 打开VC新建一个“Win32 Dynamic-Link Library”工程,命名为:sqlite3(也可以是其他的,注意这个就是编译后的dll和lib的名字)
2). 在接下来的对话框中选择"An empty DLL project",点 FINISH->OK
3). 将源码中所有的 *.c *.h *.def 复制到工程文件夹下
4). 在工程的Source File中添加你下载到的SQLite源文件中所有*.c文件,
注意这里不要添加shell.c和tclsqlite.c这两个文件。*注意需要将tclsqlite.c和shell.c、icu.c去掉。其中tclsqlite.c用于生成基于tcl的api,如果要编译,这需要另外下载tcl.h;shell.c用于生成命令行模式的sqlite.exe,如果是静态库形式则可以选择; icu是internationalcomponents forunicode,如果需要则需另外下载相关头文件。

5). 将 SQLite 源文件中的 sqlite3.def 文件添加到在工程的Source File中
6). 在Header File中添加你下载到的SQLite源文件中所有*.h文件,
7). 开始编译,Build(F7)一下
也许到这里会遇到一个错误:

e:\zieckey\sqlite\sqlite3\sqlite3ext.h(22) : fatal error C1083: Cannot open include file: 'sqlite3.h': No such file or directory

经检查发现,源码中包含sqlite3.h都是以 #include <sqlite3.h> 方式包含的,
这就是说编译器在系统默认路径中搜索,这样当然搜索不到 sqlite3.h 这个头文件啦,
这时可以改为 #include "sqlite3.h" ,让编译器在工程路径中搜索,
但是如果还有其他地方也是以 #include <sqlite3.h> 方式包含的,那么改源码就显得有点麻烦,
好了,我们可以这样,在菜单栏依次选择:Tools->Options...->Directeries
在下面的Directeries选项中输入你的 sqlite3.h 的路径,这里也就是你的工程目录.
添加好后,我们在编译一下就好了,
最后我们在工程目录的 Debug 目录生成了下面两个重要文件:
动态链接库文件 sqlite3.dll 和引入库文件 sqlite3.lib

二. 使用动态链接库

下面我们来编写个程序来测试下我们的动态链接库.

在VC下新建一个空的"Win32 Console Application" Win32控制台程序,工程命名为:TestSqliteOnWindows
再新建一个 test.cpp 的C++语言源程序,源代码如下:

// name: test.cpp
// This prog is used to test C/C++ API for sqlite3 .It is very simple,ha !
// Author : zieckey
// data : 2006/11/28

#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
#define _DEBUG_

int main( void )

sqlite3 *db=NULL;
char *zErrMsg = 0;

int rc;

rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
if( rc )

fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return (1);

else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");

//创建一个表,如果该表存在,则不创建,并给出提示信息,存储在 zErrMsg 中
char *sql = " CREATE TABLE SensorData(ID INTEGER PRIMARY KEY,SensorID INTEGER,SiteNum INTEGER,Time VARCHAR(12),SensorParameter REAL);" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

#ifdef _DEBUG_
printf("zErrMsg = %s \n", zErrMsg);
#endif

//插入数据
sql = "INSERT INTO \"SensorData\" VALUES(NULL , 1 , 1 , '200605011206', 18.9 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

sql = "INSERT INTO \"SensorData\" VALUES(NULL , 23 , 45 , '200605011306', 16.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

sql = "INSERT INTO \"SensorData\" VALUES(NULL , 34 , 45 , '200605011306', 15.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

int nrow = 0, ncolumn = 0;
char **azResult; //二维数组存放结果

//查询数据
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
int i = 0 ;
printf( "row:%d column=%d \n" , nrow , ncolumn );
printf( "\nThe result of querying is : \n" );
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s\n", i , azResult[i] );

//删除数据
sql = "DELETE FROM SensorData WHERE SensorID = 1 ;" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
#ifdef _DEBUG_
printf("zErrMsg = %s \n", zErrMsg);
#endif
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
printf( "\n\n\n\nrow:%d column=%d " , nrow , ncolumn );
printf( "\nAfter deleting , the result of querying is : \n" );
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s\n", i , azResult[i] );

//释放掉 azResult 的内存空间
sqlite3_free_table( azResult );

#ifdef _DEBUG_
printf("zErrMsg = %s \n", zErrMsg);
#endif

sqlite3_close(db); //关闭数据库
return 0;


另外,将sqlite3.h sqlite3.lib sqlite3.dll文件复制到我们的工程目录.
最后 Project->Settings 在Link选项卡找到Object/library modules : 在最后填入sqlite3.lib 。
如果原来就有链接,请使用空格分隔。
现在可以编译了.
运行结果如下:
You have opened a sqlite3 database named zieckey.db successfully!
Congratulations! Have fun ! ^-^
zErrMsg = (null)
row:3 column=5

The result of querying is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = SiteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = 1
azResult[6] = 1
azResult[7] = 1
azResult[8] = 200605011206
azResult[9] = 18.9
azResult[10] = 2
azResult[11] = 23
azResult[12] = 45
azResult[13] = 200605011306
azResult[14] = 16.4
azResult[15] = 3
azResult[16] = 34
azResult[17] = 45
azResult[18] = 200605011306
azResult[19] = 15.4
zErrMsg = (null)

row:2 column=5
After deleting , the result of querying is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = SiteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = 2
azResult[6] = 23
azResult[7] = 45
azResult[8] = 200605011306
azResult[9] = 16.4
azResult[10] = 3
azResult[11] = 34
azResult[12] = 45
azResult[13] = 200605011306
azResult[14] = 15.4
zErrMsg = (null)
Press any key to continue
在上面的第五步
5). 将 SQLite 源文件中的 sqlite3.def 文件添加到在工程的Source File中
是必须的, sqlite3.def 这个文件的加入会生成 *.lib引入库文件,这个对于*.dll文件是很重要的.否则你光有*.dll文件在程序调用的时候就不是那么方便了,因为这样你只能通过动态加载dll的方式调用dll库中函数

这个程序,我们先创建一个数据库,然后新建一个表,然后插入一些数据,
再查询看看插入的数据是否正确,然后又删除一些数据,删除后我们再查询了一下,
发现我们的删除操作也是成功的.
这个程序简单的调用 sqlite 的函数接口来实现对数据库的管理,
包括创建数据库、创建表格、插入数据、查询数据、删除数据等。
参考技术A 用sprintf吧
比如
char s[64];
sprintf(s,"where a=%d",100);
....
那么最后s的内容就是: "where a=100"
参考技术B 能不能把工程案例给我一份啊 参考技术C sqlitemanager

SQLite - 你如何连接来自不同数据库的表?

【中文标题】SQLite - 你如何连接来自不同数据库的表?【英文标题】:SQLite - How do you join tables from different databases? 【发布时间】:2011-10-13 01:47:45 【问题描述】:

我有一个使用 SQLite 数据库的应用程序,并且一切正常。我现在正在添加需要第二个 SQLite 数据库的新功能,但我很难弄清楚如何连接来自不同数据库的表。

如果有人能帮我解决这个问题,我将不胜感激!

编辑:请参阅this question,以了解当您按照已接受的答案中所述附加数据库时可以适应您的语言的示例。

【问题讨论】:

数据库是什么样的?有没有可以用来加入它们的通用列?每个列的列是否相同,以便您可以使用联合? sqlite.org/syntaxdiagrams.html 是的,有些列可以使用 USING 关键字连接,因为它们的名称相同。我的问题不是我不知道如何加入,因为我的程序已经经常在同一个数据库中的表上执行此操作,而是我似乎无法找到如何链接两个数据库,因此一个数据可以从另一个数据库中使用(例如加入) 示例:第一个数据库有一个名为“schedule”的表,其中包含日期列、团队 ID 和车道编号等列。第二个数据库有一个表格,记录用户为他们的团队比赛输入的分数。所以这个表也有一个日期和一个teamID。我想通过这两列加入他们,以了解每支球队应该在哪条车道上比赛。为了其他目的,还必须连接其他表,但您可以从这个示例中了解我需要什么。 【参考方案1】:

如果在您的 Sqlite 构建中 ATTACH 是 activated(它应该在 大多数 构建中),您可以使用 ATTACH 关键字将另一个数据库文件附加到当前连接。 limit on the number of db's that can be attached 是一个编译时间设置 (SQLITE_MAX_ATTACHED),目前默认为 10,但这也可能因您的构建而异。全局限制为 125。

attach 'database1.db' as db1;
attach 'database2.db' as db2;

您可以通过关键字查看所有已连接的数据库

.databases

那么你应该能够做到以下几点。

select
  *
from
  db1.SomeTable a
    inner join 
  db2.SomeTable b on b.SomeColumn = a.SomeColumn;

请注意,“[t]数据库名称 maintemp 保留给主数据库和数据库以保存临时表和其他临时数据对象。这两个数据库名称都存在于每个数据库连接中,不应该用于附件”。

【讨论】:

用户 StanleyD 指出,直到他在文件名周围加上 '(单引号)后,这对他不起作用。我也发现了。 attach语句后可以选择不同的主库吗?【参考方案2】:

这是一个完成此问题的 C# 示例

/// <summary>
/// attachSQL = attach 'C:\\WOI\\Daily SQL\\Attak.sqlite' as db1 */
/// path = "Path of the sqlite database file
/// sqlQuery  = @"Select A.SNo,A.MsgDate,A.ErrName,B.SNo as BSNo,B.Err as ErrAtB from Table1 as A 
///                    inner join db1.Labamba as B on 
///                    A.ErrName = B.Err";
/// </summary>
/// <param name="attachSQL"></param>
/// <param name="sqlQuery"></param>
public static DataTable GetDataTableFrom2DBFiles(string attachSQL, string sqlQuery)

    try
    
        string conArtistName = "data source=" + path + ";";
        using (SQLiteConnection singleConnectionFor2DBFiles = new SQLiteConnection(conArtistName))
        
            singleConnectionFor2DBFiles.Open();
            using (SQLiteCommand AttachCommand = new SQLiteCommand(attachSQL, singleConnectionFor2DBFiles))
            
                AttachCommand.ExecuteNonQuery();
                using (SQLiteCommand SelectQueryCommand = new SQLiteCommand(sqlQuery, singleConnectionFor2DBFiles))
                
                    using (DataTable dt = new DataTable())
                    
                        using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(SelectQueryCommand))
                        
                            adapter.AcceptChangesDuringFill = true;
                            adapter.Fill(dt);
                            return dt;
                        
                    
                
            
        
    
    catch (Exception ex)
    
        MessageBox.Show("Use Process Exception method An error occurred");
        return null;
    


【讨论】:

这行得通 - 谢谢。但顺便说一句,我认为我们不需要这么多嵌套的 using 语句。【参考方案3】:

好吧,我对 SQLite 没有太多经验,你必须在一个查询中访问两个数据库。

你可以有类似的东西:

select name from DB1.table1 as a join DB2.table2 as b where a.age = b.age;

在像 SQLServer 这样的数据库中,您可以以这种分层方式访问其他数据库,这也适用于 SQLite。

我认为您可以使用超过 1 个数据库启动一个 sqlite 实例!

【讨论】:

是的,我看到了 SQL Server 的文档,但找不到 SQLite 的等效查询。该查询的问题是我使用驱动程序管理器来创建连接,因此我有两个指向数据库文件的连接对象,但是由于某种原因,执行 conn1.table 似乎不起作用。

以上是关于MFC中,如何连接sqlite3的数据库,并对此数据库操作??的主要内容,如果未能解决你的问题,请参考以下文章

nodejs sqlite3 备份数据库

如何将SQLite3 创建的数据库与android 程序连接

Access数据库连接错误

如何将 sqlite3 与电子 js 连接起来

如何在 sqlite3 中正确连接这些表 [关闭]

MFC中如何连接access数据库?