链接sqlite

news2024/11/25 20:31:34

一.sqlite库函数

1.sqlite3_open()函数

语法:*sqlite3_open(const char *filename, sqlite3 *ppDb)

作用:该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。

参数1:如果 filename 参数是 NULL或":memory:",那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。如果文件名 filename 不为 NULL,而是你创建的数据库文件名,那么 sqlite3_open() 将使用这个参数值尝试打开对应数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。

参数2:sqlite3_open() 函数的第二个参数是一个指向 SQLite 数据库连接的指针。如果 sqlite3_open() 调用成功,该指针将指向新创建的数据库连接,您可以使用该指针执行其他 SQLite 操作,如执行 SQL 查询、管理数据库事务等。

返回值:sqlite3_open() 函数的返回值是一个整数,用于指示函数调用的结果。以下是可能的返回值:

  • SQLITE_OK:函数调用成功,已打开指定的数据库连接。
  • SQLITE_ERROR:发生了错误,无法打开数据库连接。例如,文件名无效或无法访问文件系统。
  • SQLITE_CANTOPEN:无法打开数据库文件。这可能是因为磁盘已满、权限不足或数据库文件损坏等原因导致的。
  • SQLITE_MISUSE:发生了程序错误,例如传递给函数的参数无效或在多线程环境中不正确地使用库函数。
  • 其他错误码:SQLite 库定义了许多其他可能的错误代码,每个代码表示一个特定类型的错误。

通常来说,如果您调用 sqlite3_open() 并且它返回 SQLITE_OK,这个你作为0理解,其他错误代表返回值为1,只是不同类型的1代表的错误不同而已,则可以开始使用通过该函数创建的数据库连接进行其他 SQLite 操作,否则需要检查返回值并根据具体情况采取必要的措施。

2. sqlite3_errmsg()函数

语法:const char *sqlite3_errmsg(sqlite3*);

参数:参数是一个 sqlite3 类型的指针,该指针代表与 SQLite 数据库关联的连接。

返回值:它返回一个指向包含最近一次执行 SQLite API 函数时发生的错误消息的静态字符串的指针。

3. sqlite3_close()函数

语法:sqlite3_close(sqlite3*)

作用:关闭之前调用 sqlite3_open() 打开的数据库连接

参数:一个 sqlite3 类型的指针

4. sqlite3_exec()函数

sqlite3_exec函数是SQLite库中的一个高级封装函数,用于执行SQL语句并返回执行结果。

函数原型:

int sqlite3_exec(
  sqlite3*,                                  // 数据库连接对象
  const char *sql,                           // 要执行的SQL语句
  int (*callback)(void*,int,char**,char**),  // 回调函数指针
  void *,                                    // 回调函数参数
  char **errmsg                              // 错误信息输出缓冲区
);

参数说明:

  • sqlite3*:已经打开的数据库连接对象;
  • const char *sql:要执行的SQL语句,可以是一条或多条SQL语句,语句之间用分号隔开;
  • int (*callback)(void*,int,char**,char**):回调函数指针,当SQL语句执行完毕后会调用该函数,该函数可以用于处理查询结果或者操作完成的回调;
  • void*:回调函数所需的参数;
  • char **errmsg:如果执行过程中发生错误,将会把错误信息存到该变量所指向的内存空间中。(注意,这里是一个二级指针)

函数返回值为整数类型,表示执行结果。如果执行成功,则返回 SQLITE_OK(0); 如果执行失败,则返回其他的错误码,例如 SQLITE_ERROR(-1) 等。

注意事项:

  1. 在使用sqlite3_exec函数时,需要特别注意SQL注入问题,应该避免直接在SQL语句中拼接用户输入的字符串,而应该采用参数绑定的方式。
  2. 在使用回调函数时,需要根据具体情况做好内存管理,避免内存泄漏等问题。

5.连接测试代码

#include <stdio.h>
#include <sqlite3.h>

int main()
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;

   rc = sqlite3_open("test.db", &db);

   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      exit(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }
   sqlite3_close(db);
}

此代码仅完成测试功能,没有实现其他功能。

二.链接数据库

1.下载sqlite3.h文件

下载链接在我上一篇博客里面有,可以查看上一篇博客sqlite基础

下载后记得解压到和你准备链接的数据库.db文件同一目录下。

2.链接

如果此时你运行测试文件,结果绝对报错,因为大多数windows下的编译软件带的库中都没有sqlite3.h库文件,此时你需要进行链接操作生成可执行文件。

具体怎么链接,每个编译软件不同,这里以CLion为例,进行演示。如果你的软件是DevC++,链接操作可以参考这篇博客Windows下链接。

操作步骤:

  • 1.下载好的sqlite3.h文件放在你准备链接的数据库文件同一目录下
  • 2.打开CLion,新建项目,工作目录选择你刚刚存放的位置
  • 3.编写CMake文件,代码在下面,复制粘贴即可,自动保存
  • 4.在main.c文件里写测试代码,编译运行

CMake代码:

cmake_minimum_required(VERSION 3.25)
project(db_work C)

set(CMAKE_C_STANDARD 11)
add_compile_options(-l sqlite3)
add_executable(db_work main.c sqlite3.c)

现在看不懂也没关系,后面会有一篇博客专门介绍makefile的,到时详细解释。

三.C语言实现sqlite操作

1.提前看

首先我们通过命令窗口,直到数据库文件原来就存在的信息,确保后面增加的信息是通过C语言操作实现的。

如果你不知道具体怎么操作,可以看上一篇博客:sqlite基础

我的当前数据库信息:

TvrR.jpg

我们现在演示的数据库里面有两个表COMPANY、student,其中COMPANY是一个空表,还没有插入信息;student表中仅有一条Alice的信息。

2.回调函数

在进行C语言实现sqlite操作之前,我们首先得理解一个概念,回调函数。回调函数是一种常见的编程技术,用于在异步程序中处理结果或事件。当执行某个操作时,通常需要等待该操作完成后才能继续执行下一步。在这种情况下,可以将回调函数传递给该操作,以便在操作完成时自动调用该函数。

是不是你还一头雾水,我们先了解程序执行两种方式,同步执行和异步执行。同步执行没什么好说的,即程序从上到下一行一行的顺序执行,但是如果某个进程有许多线程,又必须等某一线程执行,主线程才能继续进行时,如果是同步方式就要一直等待这个需要线程执行完,很容易时间长造成阻塞。这里我们就用了异步执行的方式,异步方式是指在程序运行过程中,某个操作需要花费一定的时间才能完成,而在等待这个操作完成之前,程序会继续执行后面的代码。当这个操作完成后,程序会自动调用相应的回调函数来处理结果。

现在应该明白回调函数的作用了吧,再继续理解,它既然是处理某个线程或操作的处理结果,怎么处理,是不是要定义一个函数来对结果进行处理,所以回调函数是一种在编程中常见的技术,它允许您将一个函数作为参数传递给另一个函数,以便在需要时执行该函数。

他的存在形式是什么呢,其实回调函数严格来说就是一个普通函数,就是处理某个操作结果的函数,它自己可以作为一个参数被操作函数调用而已。举个例子好理解:

#include <stdio.h>

// 回调函数类型定义
typedef void (*Callback)(int);

// 执行计算任务的函数
void calculate(int a, int b, Callback callback) {
    int result = a + b;
    // 调用回调函数,将结果传递给它
    callback(result);
}

// 回调函数的实现
void printResult(int result) {
    printf("The result is: %d\n", result);
}

int main() {
    // 调用 calculate 函数并传入回调函数
    calculate(1, 2, printResult);
    return 0;
}

这里我们又一个calculate函数,假设进程程序特别长,在进行calculate操作之后还有其他操作,就可以使用回调函数的编程技术,即本例中把回调函数printResult作为一个参数可以通过calculate引入,这样不需要等他计算结果出来主线程就可以进行后面的操作,等calculate函数把结果计算出来自己调用printResult来打印输出。

有的人说,我为什么要通过函数指针导入,在一个函数内部本身就可以调用另一个函数嘛,这样确实可以,但这样就变成了同步执行方式,它必须等a+b计算结果出来后才会执行printResult函数,如果a+b计算结果没出来,程序就一直卡在这里。

3.函数指针

知道回调函数之后,你就知道回调函数可以作为参数导入,那直接整个函数作为参数导入吗,它其实是一个函数指针来代替引入。

函数指针是什么,顾名思义,就是一个指向函数的指针,只不过他和平时指针的定义方式不同而已。例如void (*Callback)(int)这段代码的意思就是定义了一个回调函数类型 Callback,它表示一个以整型参数为输入、无返回值的函数指针类型。(左边返回值,右边输入)

那么typedef void (*Callback)(int) 这行代码的作用,其实是将 void (*Callback)(int) 取一个别名 Callback,使其可以被当成一个新的数据类型来使用。这样,在程序中可以直接声明 Callback 类型的变量,而不需要再写一长串复杂的函数指针声明。

比如上面例子中写成Callback callback,而不是写成void (*Callback)(int) callback

4.C语言创建表

源代码:

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

//回调函数
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
    int i;
    for(i=0; i<argc; i++){
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

int main(int argc, char* argv[])
{
    sqlite3 *db;
    char *zErrMsg = 0;
    int  rc;
    char *sql;

    /*打开数据库*/
    rc = sqlite3_open("D:\\softwore work\\db work\\text.db", &db);
    if( rc ){
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        exit(0);
    }else{
        fprintf(stdout, "Opened database successfully\n");
    }

    /* 创建表 */
    sql = "CREATE TABLE friend("  \
         "id INT PRIMARY KEY     NOT NULL," \
         "name           TEXT    NOT NULL," \
         "age            INT     NOT NULL," \
         "address        CHAR(50)," \
         "salary         REAL );";

    /* Execute SQL statement */
    rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);      //执行上面的sql语句
    if( rc != SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);           //释放内存函数,释放zErrMsg对应的内存空间
    }else{
        fprintf(stdout, "Table created successfully\n");
    }
    sqlite3_close(db);
    return 0;
}

这里面你理解上面知识点就好理解了,补充两点:

  • 反斜杠 “” 字符在许多编程语言中,包括 C 和其派生语言如 C++ 中用于指示一个语句延续到下一行。这被称为行继续字符。每行末尾的反斜杠用于连接(合并)多行字符串以形成单个字符串。这样可以通过将长行分成更小的块来使代码更易于阅读。如果没有反斜杠,则 SQL 语句会被视为多个独立的字符串,在执行代码时会导致语法错误。

  • 回调函数:本例的回调函数,通常用于 SQLite 数据库操作中的查询操作。

    它的参数包括:

    1. void *NotUsed:这是一个不使用的指针,通常可以忽略。
    2. int argc:这是一个整数,表示查询结果集的列数。
    3. char **argv:这是一个字符数组指针,它包含每个查询结果的值。每个元素都是一个字符串,存储了对应列的值。
    4. char **azColName:这是一个字符数组指针,它包含每个查询结果的列名。每个元素都是一个字符串,存储了对应列的名称。

    在这个回调函数中,它遍历了所有的查询结果,并打印输出了每个结果的列名和对应的值。最后返回0表示操作成功完成。这个回调函数常用于 SQLite 的查询操作中,在执行 select 语句时,SQLite 将结果逐行传递给该回调函数处理。(进行其他操作时,程序执行会很快,一般不会使用到回调函数)

5.演示结果

jpg

利用命令端口,可以看到在此基础上,我们成功建立一个friend的表。

四.其他操作

是不是理解上面的知识了,理解上面的知识后你应该就知道怎么使用C语言实现sqlite的其他操做了。

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;

   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      exit(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }

   /* Create SQL statement */
   sql = "INSERT INTO friend "  \
         "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
         "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
         "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
         "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

   /* Execute SQL statement */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
   if( rc != SQLITE_OK ){
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   }else{
      fprintf(stdout, "Records created successfully\n");
   }
   sqlite3_close(db);
   return 0;
}

例如本例修改后就完成了INSERT语句的操作。

五.Python sqlite3 模块 API

  1. connect(database[, timeout, isolation_level, detect_types, factory, cached_statements])

    打开数据库连接,并返回一个连接对象。其中:

    • database:要连接的数据库文件名。
    • timeout:超时时间,默认为 5.0 秒。
    • isolation_level:事务隔离级别,默认为 None
    • detect_types:是否自动检测数据类型,默认为 0(不检测)。
    • factory:用于创建游标对象的类。默认为 None,表示使用内置的游标类。
    • cached_statements:是否缓存 SQL 语句,默认为 100
  2. Cursor()

    创建一个游标对象,用于执行 SQL 命令并管理结果集。

  3. execute(sql[, parameters])

    执行 SQL 命令,并将参数传递给 SQL 命令中的占位符。其中:

    • sql:要执行的 SQL 命令。
    • parameters:可选参数,用于替换 SQL 命令中的占位符。
  4. fetchone()

    获取查询结果集中的下一行数据。

  5. fetchmany([size])

    获取查询结果集中的多行数据,最多返回 size 行。如果未指定 size,则默认为 Cursor.arraysize

  6. fetchall()

    获取查询结果集中的所有行数据。

  7. commit()

    提交当前事务。

  8. rollback()

    回滚当前事务。

  9. close()

    关闭游标对象和数据库连接。

在python中链接数据库并实现创建表的操作:

import sqlite3

conn = sqlite3.connect('D:\\softwore work\\db work\\text.db')
print ("数据库打开成功")
c = conn.cursor()
c.execute('''CREATE TABLE classmate
       (ID INT PRIMARY KEY     NOT NULL,
       NAME           TEXT    NOT NULL,
       AGE            INT     NOT NULL,
       ADDRESS        CHAR(50),
       SALARY         REAL);''')
print ("数据表创建成功")
conn.commit()
conn.close()

六.情况说明

懂了之后,其实操作并不难,python链接相对来说比C语言简单。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/478073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在自己的Maven工程上搭建Mybatis框架?

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 目录 前言 一. 什么是Mybatis框架&#xff1f;1.1 框架是什么&#xff1f;1.2 什么是MyBatis &#xff1f;1…

3.11 C结构体及结构体数组

结构体的意义 问题&#xff1a;学籍管理需要每个学生的下列数据&#xff1a;学号、姓名、性别、年龄、分数&#xff0c;请用C语言程序存储并处理一组学生的学籍。 思考&#xff1a;如果有多个学生&#xff0c;该怎么定义 已学数据类型无法解决。 结构体概述 正式&#xff1a;…

【Sping学习详解】

重新学习Spring很久了&#xff0c;也看了不少的视频&#xff0c;但是没有系统总结&#xff0c;容易忘记&#xff0c;网上寻找相关博客&#xff0c;也没有找到按照路线总结的&#xff0c;只能说不顺我心&#xff0c;所以自己总结一下&#xff01;&#xff01;&#xff01; 从下…

vulnhub靶机dpwwn1

准备工作 下载连接&#xff1a;https://download.vulnhub.com/dpwwn/dpwwn-01.zip 网络环境&#xff1a;DHCP、NAT 下载完后解压&#xff0c;然后用VMware打开dpwwn-01.vmx文件即可导入虚拟机 信息收集 主机发现 端口发现 继续查看端口服务信息 打开网站发现只有Apache默认…

【Spring篇】IOC/DI注解开发

&#x1f353;系列专栏:Spring系列专栏 &#x1f349;个人主页:个人主页 目录 一、IOC/DI注解开发 1.注解开发定义bean 2.纯注解开发模式 1.思路分析 2.实现步骤 3.注解开发bean作用范围与生命周期管理 1.环境准备 2.Bean的作用范围 3.Bean的生命周期 4.注解开发依赖…

行为识别 Activity Recognition

行为识别 行为检测是一个广泛的研究领域&#xff0c;其应用包括安防监控、健康医疗、娱乐等。 课程大纲 导论 图卷积在行为识别中的应用&#xff1a;论文研读&#xff0c;代码解读&#xff0c;实验 Topdown关键点检测中的hrnet&#xff1a;论文研读&#xff0c;代码解读&a…

ETL工具 - Kettle 流程、应用算子介绍

一、Kettle 流程和应用算子 上篇文章对Kettle 转换算子进行了介绍&#xff0c;本篇文章继续对Kettle 的流程和应用算子进行讲解。 下面是上篇文章的地址&#xff1a; ETL工具 - Kettle 转换算子介绍 流程算子主要用来控制数据流程和数据流向&#xff1a; 应用算子则是Kettle给…

ESP32 ESP-Rainmaker 本地点灯控制Demo测试

基于ESP-Rainmaker 本地点灯控制Demo测试 &#x1f33f;ESP-Rainmaker项目地址&#xff1a;https://github.com/espressif/esp-rainmaker/tree/master ✨这个项目早些时候就已经开始测试了&#xff0c;最后卡在了手机APP连接esp32设备端一直无法连接上&#xff0c;也一直没有找…

性能:Intel Xeon(Ice Lake) Platinum 8369B阿里云CPU处理器

阿里云服务器CPU处理器Intel Xeon(Ice Lake) Platinum 8369B&#xff0c;基频2.7 GHz&#xff0c;全核睿频3.5 GHz&#xff0c;计算性能稳定。目前阿里云第七代云服务器ECS计算型c7、ECS通用型g7、内存型r7等规格均采用该款CPU。 Intel Xeon(Ice Lake) Platinum 8369B Intel …

Linux第五章

文章目录 前言一、MySQL5.7版本在CentOS系统安装二、Tomcat安装部署1.安装JDK环境2. 解压并安装Tomcat 三、Nginx安装部署四、RabbitMQ安装部署五、Redis安装部署六、ElasticSearch安装部署七、集群化环境前置准备八、Zookeeper集群安装部署九、Kafka集群安装部署十、大数据集群…

操作系统的进程调度

进程调度概述 一、操作系统的调度时机 1、什么时候进行进程调度&#xff1f; 主动放弃&#xff08;进程正常终止、运行过程中发生异常而终止、进程主动请求阻塞&#xff09; 被动放弃&#xff08;分给进程的时间片用完、有更紧急的事需要处理、有更高优先级的进程进入就绪队列…

CentOS7 安装MySQL8

CentOS7 安装MySQL8 安装 VMware 以及 CentOS更新系统添加 MySQL Yum 存储库安装 MySQL 8启动 MySQL检查 MySQL 状态查看临时密码用临时密码登录修改密码 安装 VMware 以及 CentOS 由于本博主之前写过&#xff0c;在这给出链接&#xff0c;不再赘述了 https://blog.csdn.net/w…

2023.4.30 第五十一次周报

目录 前言 文献阅读 背景 对现有技术的分析 主要思路和贡献 相关性分析和归一化处理 相关性分析 归一化处理 TCN 基于 TCN-LSTM 的 PM 浓度预测模型 敏感性分析 论文思路 求半方差 训练模型 -1 训练模型-2 总结 前言 This week I studied an article that cons…

R语言 | 进阶字符串的处理

目录 一、语句的分割 二、修改字符串的大小写 三、unique()函数的使用 四、字符串的连接 4.1 使用paste()函数常见的失败案例1 4.2 使用paste()函数常见的失败案例2 4.3 字符串的成功连接与collapse参数 4.4 再谈paste()函数 4.5 扑克牌向量有趣的应用 五、字符串数据的…

vue前端开发100问(持续更新)

1.export default的作用是 export主要用于对外输出本模块变量的接口&#xff0c;一个文件就可以被理解为一个模块。export就是导出。 import就是在一个模块中加载另一个含有export接口的模块&#xff0c; import就是导入。 2.什么样的内容需要放在export default里面&#xf…

mybatis使用(简单易上手)

mybatis使用 一、mybatis介绍1、mybatis是什么2、mybatis支持的数据库3、~~mybatis插件机制~~ 二、springboot集成mybatis1、引入依赖2、配置mybatis 三、使用mybatis1、注解方式使用mybatis2、XML文件方式 一、mybatis介绍 1、mybatis是什么 MyBatis是一个开源的Java持久层框…

第十七章 预制件prefab(下)

本章节我们来讲解如何编辑预制体文件。这里介绍三种打开编辑预制件的方式。第一就是通过预制件的实例游戏对象的Inspector检视面板上面的预制件“打开”按钮。 第二就是在Project工程面板中选中预制件文件&#xff08;Cube.prefab&#xff09;&#xff0c;然后在Inspector检视面…

山东专升本计算机第八章-多媒体技术基础

多媒体技术基础 多媒体技术 考点 7 图形/图像处理软件 图形/图像文件格式 • BMP • windows系统下的标准位图格式 • 未经压缩 • JPEG&#xff08;联合图像专家组&#xff09; • 有损压缩格式&#xff0c;色数量高达24位&#xff0c;广泛应用于Internet上的主页或图片…

excel实战小测第四

【项目背景】 本项目为某招聘网站部分招聘信息&#xff0c;要求对“数据分析师”岗位进行招聘需求分析&#xff0c;通过对城市、行业、学历要求、薪资待遇等不同方向进行相关性分析&#xff0c;加深对数据分析行业的了解。 结合企业真实招聘信息&#xff0c;可以帮助有意转向数…