sqlite3資料庫Linux 系統移植和使用

来源:https://www.cnblogs.com/hylife/archive/2023/02/28/17164211.html
-Advertisement-
Play Games

sqlite3資料庫是一個小型的資料庫,當數據量不大,要求不是特別高的時候,是個不錯的選擇。 在Linux上移植和使用也非常的方便。 本示例是在硬體全志r528 .linux5.4 上驗證的。 移植操作: 1、源碼下載 去官網進行下載源碼SQLite Download Page,根據自己的選取選擇不 ...


sqlite3資料庫是一個小型的資料庫,當數據量不大,要求不是特別高的時候,是個不錯的選擇。

在Linux上移植和使用也非常的方便。

本示例是在硬體全志r528 .linux5.4 上驗證的。

移植操作:

   1、源碼下載

      去官網進行下載源碼SQLite Download Page,根據自己的選取選擇不同的版本。我發現我系統的menuconfig 上就帶sqlite3的資料庫,所以沒有在

官網上下載,直接勾選上。編譯出來的。

     

 

 

       

    2、交叉編譯

  進入sqlite-autoconf-3230100後執行以下指令生成Makefile文件:

 

./configure CC=arm-hisiv400-linux-gcc--host=arm-hisiv400-linux--prefix=/home/rong//share/lishuangliang/sqlite/install

 

其中CC指定嵌入式平臺為arm-hisiv400-linux-gcc即海思的Hi3536;host項指定主機;prefix項指定安裝目錄;

需要註意的是每一項配置的等號兩邊不能有空格。接著運行make進行編譯,待編譯完成後運行make install進行安裝,

至此源碼編譯安裝完成。(未驗證)
      編譯出來有用的文件有libsqlite3.so libsqlite3.so.0動態庫。sqlite3 可執行文件。

    3、配置部署編譯出來的庫和執行文件

    將libsqlite3.so libsqlite3.so.0動態庫拷貝到Linux系統的  /usr/lib/ 目錄下,

        將sqlite3 拷貝到Linux系統的  /usr/bin/ 目錄下麵。

應用編譯

    將 libsqlite3.so libsqlite3.so.0 放在要編譯的應用程式一個目錄或其他目錄下都可以主要是編譯器要能找到。

    sqlite3.h放在放在要編譯的應用程式一個目錄

  配置交叉編譯 必須 加上 -lsqlite3  -L加上庫目錄 -I 加上頭文件目錄

  如下是一個簡單的Makefile 

  

# 方便起見一般都會先定義編譯器鏈接器
CC = arm-openwrt-linux-gcc 
LD = arm-openwrt-linux-gcc
FLAGS = -lsqlite3 -L /home/kerson/app/test_app/sqlit3  -I /home/kerson/app/test_app/sqlit3

# 正則表達式表示目錄下所有.c文件,相當於:SRCS = main.c a.c b.c
SRCS = $(wildcard *.c)

# OBJS表示SRCS中把列表中的.c全部替換為.o,相當於:OBJS = main.o a.o b.o
OBJS = $(patsubst %c, %o, $(SRCS))

# 可執行文件的名字
TARGET = test_sqlite

# .PHONE偽目標,具體含義百度一下一大堆介紹
.PHONY:all clean

# 要生成的目標文件
all: $(TARGET)

# 第一行依賴關係:冒號後面為依賴的文件,相當於Hello: main.o a.o b.o
# 第二行規則:$@表示目標文件,$^表示所有依賴文件,$<表示第一個依賴文件
$(TARGET): $(OBJS)
    $(LD) $(FLAGS) -o $@ $^

# 上一句目標文件依賴一大堆.o文件,這句表示所有.o都由相應名字的.c文件自動生成
%.o:%.c
    $(CC) $(FLAGS) -c $^

# make clean刪除所有.o和目標文件
clean:
    rm -f $(OBJS) $(TARGET)

 

 

 

 

下麵分享實驗代碼

主要是拼接SQL語句。之後用exec函數執行SQL語句。

主要的是查詢表格內容時,註意回調函數是每查找到一條記錄就執行一次回調函數。

 

my_sqlite3.c


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

#include "sqlite3.h"
#include "my_sqlite3.h"




/*
* @brief 打開/創建資料庫
* @param 無
* @return 失敗返回NULL/成功返回資料庫db
*/

sqlite3 * sqlite3_open_database(char * db_name)
{
    int ret = 0;
    sqlite3* db;

    if(db_name == NULL || strlen(db_name) == 0){
        return NULL;
    }
    
    ret = sqlite3_open(db_name ,&db);
    if(ret != SQLITE_OK){
        printf("Open db error =:%s",sqlite3_errmsg(db));
        return NULL;
    }
    
    return db;
}


/*
* @brief 創建一個表
* @param db,
    table_name:表名字
    data_buf:列項目
* @return 失敗返回-1/成功返回0
*/

int sqlite3_create_table(sqlite3 *db, char * table_name,char *data_buf)
{
    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1;
    if(table_name == NULL ||strlen(table_name) ==0){
        printf("input argc error\n");
        return -1;
    }

    sprintf(sql_str,"CREATE TABLE IF NOT EXISTS %s %s",table_name,data_buf);
    ret = sqlite3_exec(db,sql_str,0,0,&err_msg);
    if(ret != SQLITE_OK)
    {
        printf("Creat table %s error : %s", table_name,err_msg);
        sqlite3_free(err_msg);
    }else{
        ret = 0;
    }

    return ret;
}




/*
* @brief 刪除一個表
* @param db,
    table_name:表名字
* @return 失敗返回-1/成功返回0
*/
int sqlite3_delete_table(sqlite3 *db, char * table_name)
{
    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1;
    if(table_name == NULL ||strlen(table_name) ==0){
        printf("input argc error\n");
        return -1;
    }

    sprintf(sql_str,"DROP TABLE %s",table_name);
    sqlite3_busy_timeout(db, 1000);
    ret = sqlite3_exec(db,sql_str,0,0,&err_msg);
    if(ret != SQLITE_OK)
    {
        printf("Delete table %s error : %s", table_name,err_msg);
        sqlite3_free(err_msg);
    }else{
        ret = 0;
    }
    return ret;

    
}


/*
* @brief 插入一條數據
* @param db,
    table_name:表名字
* @return 失敗返回-1/成功返回0
*/
int sqlite3_insert_single(sqlite3 *db,char *table_name,  char *data_buf)
{

    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1;
    if(table_name == NULL ||strlen(table_name) ==0){
        printf("input argc error\n");
        return -1;
    }

    sprintf(sql_str,"INSERT INTO %s values %s",table_name,data_buf);
    sqlite3_busy_timeout(db, 1000);
    ret = sqlite3_exec(db,sql_str,0,0,&err_msg);
    if(ret != SQLITE_OK)
    {
        printf("insert table %s error : %s", table_name,err_msg);
        sqlite3_free(err_msg);
    }else{
        ret = 0;
    }
    return ret;
}



/*
* @brief 插入多條數據(利用顯示事物機制,效率高)
* @param db,
    table_name:表名字
    data_buf 多條插入的內容
* @return 失敗返回-1/成功返回0
*/

int sqlite3_insert_multi(sqlite3 *db,char *table_name,  char **data_buf ,int len)
{

    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1 ,i =0;
    sqlite3_stmt * stmt;
    
    if(table_name == NULL ||strlen(table_name) ==0){
        printf("input argc error\n");
        return -1;
    }
    sprintf(sql_str,"INSERT INO %s values ?");

    sqlite3_exec(db,"BEGIN",0,0,0);
    ret = sqlite3_prepare(db,sql_str,strlen(sql_str),&stmt,0);
    if(ret != SQLITE_OK)
        return -1;
    
    while(data_buf[i] !=NULL && i < len){
        sqlite3_bind_text(stmt,1,data_buf[i],strlen(data_buf[i]),NULL);
        ret = sqlite3_step(stmt);
        if((ret != SQLITE_OK) && (ret != SQLITE_DONE)){
            break;
        }
        sqlite3_reset(stmt);
        i++;
    }
    sqlite3_finalize(stmt);
    if(i < len){
        sqlite3_exec(db,"ROLLBACK",0,0,0);
        return -1;
    }
    if(i == len){
        sqlite3_exec(db,"COMMIT",0,0,0);
        ret =0;
    }    


    return ret;
}



/*
* @brief 查詢回調函數
* @param 

 data:由sqlite3_exec傳遞的初始化參數
 argc:表頭的列數
 col:表頭的名字數組指針
 argv:表頭的數據數組指針

* @return 失返回0
*/
int exec_handle(void *data, int argc, char **argv,char ** colname)
{
    /*查詢到一條結果將data+1*/    
    int i = *(int *)(data);
    *(int *)(data) = i+1;

    /*列印*/
    for(i =0;i<argc;i++){
        printf("NUM =%d %s\t%s\n",*(int *)(data),colname[i],argv[i]);
    }

    return 0;
}




/*
* @brief 查詢表格內容  sql語句:SELECT 列名稱 FROM 表名稱 WHERE 列 運算符 值
列名稱為 * 代表所有的列
* @param db,
    table_name:表名字
* @return 失敗返回-1/成功返回0 查詢成功,無查詢結果,返回1 查詢成功,有查詢結果
*/
int sqlite3_select_exec(sqlite3 *db,char *table_name, char *col_name, char *where_cond)
{
    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1;
    int data =0;
    if(table_name == NULL ||strlen(table_name) ==0){
        printf("input argc error\n");
        return -1;
    }

    sprintf(sql_str,"select %s from %s ",col_name,table_name);
    
    if(where_cond != NULL){
        strcat(sql_str," where ");
        strcat(sql_str,where_cond);
    }
    sqlite3_busy_timeout(db, 1000);
    ret = sqlite3_exec(db,sql_str,exec_handle,&data,&err_msg);
    if(ret != SQLITE_OK)
    {
        printf("select table %s error : %s", table_name,err_msg);
        sqlite3_free(err_msg);
    }else{

        if(data == 0){
            return 0; /*查詢成功,無查詢結果*/
        }else{
            return 1; /*查詢成功,有查詢結果*/
        }    
        
    }

}


/*
* @brief 查詢資料庫中的表格  sql語句:select name from sqlite_maseter where type ='table' order by name
列名稱為 * 代表所有的列
* @param db,
* @return 
*/
int sqlite3_get_tablename(sqlite3 *db)
{
    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1;
    char ** dbresult;
    int i,j,nrow,ncolumn,index =0;

    sprintf(sql_str,"select name from sqlite_master where type ='table' order by name ");
    
    sqlite3_busy_timeout(db, 1000);
    ret = sqlite3_get_table(db,sql_str,&dbresult,&nrow,&ncolumn,&err_msg);
    if(ret == SQLITE_OK)
    {
        for(i=0;i <= nrow; i++)
            /*for(j=0;j< ncolumn;j++)*/
        {
            printf("%s \n",dbresult[index]);
            index++;
        }
    }
    else{

        printf(" get table error\n ");
    }

}




/*
* @brief 更新 sql語句:UPDATAE 表名 SET 新值 WHERE 列 運算符 值
* @param db,
    table_name:表名字
* @return 失敗返回-1/成功返回0 查詢成功,無查詢結果,返回1 查詢成功,有查詢結果
*/
int sqlite3_update_single(sqlite3 *db,char *table_name, char *new_val, char *where_cond)
{
    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1;

    if(table_name == NULL ||strlen(table_name) ==0){
        printf("input argc error\n");
        return -1;
    }

    sprintf(sql_str,"UPDATE %s SET %s",table_name,new_val);
    if(where_cond != NULL){
        strcat(sql_str," where ");
        strcat(sql_str,where_cond);
    }    
    sqlite3_busy_timeout(db, 1000);
    ret = sqlite3_exec(db,sql_str,0,0,&err_msg);
    if(ret != SQLITE_OK)
    {
        printf("UPDATE table %s error : %s", table_name,err_msg);
        sqlite3_free(err_msg);
        ret =-1;
    }else{

        ret = 0;    
    }
    return ret;

}


/*
* @brief 刪除 sql語句:DELETE FROM 表名稱 WHERE 列 運算符 值
沒有where 為刪除所有。
* @param db,
    table_name:表名字
* @return 失敗返回-1/成功返回0 查詢成功,無查詢結果,返回1 查詢成功,有查詢結果
*/
int sqlite3_delete_single(sqlite3 *db,char *table_name,char *where_cond)
{
    char sql_str[128] ={0};
    char *err_msg = NULL;
    int ret =-1;
    int data =0;
    if(table_name == NULL ||strlen(table_name) ==0){
        printf("input argc error\n");
        return -1;
    }

    sprintf(sql_str,"DELETE FROM %s",table_name);
    if(where_cond != NULL){
        strcat(sql_str," where ");
        strcat(sql_str,where_cond);
    }
    sqlite3_busy_timeout(db, 1000);
    ret = sqlite3_exec(db,sql_str,exec_handle,&data,&err_msg);
    if(ret != SQLITE_OK)
    {
        printf("s table %s error : %s", table_name,err_msg);
        sqlite3_free(err_msg);
        ret =-1;
    }else{

        ret = 0;    
    }
    return ret;

}

 

頭文件

my_sqlite3.h

#ifndef _MY_SQLITE3_H_
#define _MY_SQLITE3_H_ sqlite3 * sqlite3_open_database(char * db_name); int sqlite3_create_table(sqlite3 *db, char * table_name,char *data_buf); int sqlite3_delete_table(sqlite3 *db, char * table_name); int sqlite3_insert_single(sqlite3 *db,char *table_name, char *data_buf); int sqlite3_select_exec(sqlite3 *db,char *table_name, char *col_name, char *where_cond); int exec_handle(void *data, int argc, char **argv,char ** colname); int sqlite3_update_single(sqlite3 *db,char *table_name, char *new_val, char *where_cond); int sqlite3_delete_single(sqlite3 *db,char *table_name,char *where_cond); int sqlite3_get_tablename(sqlite3 *db); #endif

 

 

測試代碼

 

main.c


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

#define DB_NAME  "./test.db" 
#define DB_NAME1  "./data.db" 

#define TABLE_NAME "stu_table"
#define TABLE_NAME1 "場景表"

#define MAX_LEN 512


int main(int argc, char **argv)
{
    sqlite3 *db = NULL;
    char buf[MAX_LEN] ={0};
    char buf1[MAX_LEN] ={0};
    char *errmsg;
    int ret;

    db = sqlite3_open_database(DB_NAME);
    if(db == NULL){
        printf("open db error\n");
        return -1;
    }

    /*創建一個表*/
#if 0
    memset(sql,0,sizeof(sql));
    strcpy(sql,"creat table if not exists %s(name text ,score int);",TABLE_NAME);
    ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
    if(ret !=0)
    {
        printf("sqlite3_exec:%s\n",errmsg);
    }
#endif
    memset(buf,0,sizeof(buf));
    strcpy(buf,"(Name text ,Score int)");
    ret = sqlite3_create_table(db,TABLE_NAME,buf);
    if(ret !=0)
    {
        return -1;
    }
    
    sqlite3_get_tablename(db); /*獲取有多少表格*/


    /*插入表中*/
    memset(buf,0,sizeof(buf));
    strcpy(buf,"('lili',86)");
    ret = sqlite3_insert_single(db,TABLE_NAME,buf);
    if(ret !=0)
    {
        return -1;
    }


    /*插入表中*/
    memset(buf,0,sizeof(buf));
    strcpy(buf,"('wangwu',99)");
    ret = sqlite3_insert_single(db,TABLE_NAME,buf);
    if(ret !=0)
    {
        return -1;
    }

    /*查找*/
    printf("select all:\n");
    sqlite3_select_exec(db,TABLE_NAME,"*",NULL);
    printf("select Score > 90:\n");
    memset(buf,0,sizeof(buf));
    strcpy(buf,"Score > 90");
    sqlite3_select_exec(db,TABLE_NAME,"*",buf);
    
    /*更改*/
    memset(buf,0,sizeof(buf));
    strcpy(buf,"Score = 91");
    memset(buf1,0,sizeof(buf1));
    strcpy(buf1,"Score < 90");
    sqlite3_update_single(db,TABLE_NAME,buf,buf1);


    /*查找*/
    printf("select all:\n");
    sqlite3_select_exec(db,TABLE_NAME,"*",NULL);
    printf("select Score > 90:\n");
    memset(buf,0,sizeof(buf));
    strcpy(buf,"Score > 90");
    sqlite3_select_exec(db,TABLE_NAME,"*",buf);

    /*刪除*/
    memset(buf,0,sizeof(buf));
    strcpy(buf,"Score > 90");
    sqlite3_delete_single(db,TABLE_NAME,buf);

    printf("select all:\n");
    sqlite3_select_exec(db,TABLE_NAME,"*",NULL);



    /*關閉資料庫*/
    sqlite3_close(db);


    db = sqlite3_open_database(DB_NAME1);
    if(db == NULL){
        printf("open db error\n");
        return -1;
    }

    sqlite3_get_tablename(db); /*獲取有多少表格*/


    /*查找*/
    printf("select all:\n");
    sqlite3_select_exec(db,TABLE_NAME1,"*",NULL);

    /*更改*/
    memset(buf,0,sizeof(buf));
    strcpy(buf,"播放亮度 = 255");
    memset(buf1,0,sizeof(buf1));
    strcpy(buf1,"場景ID = 6");
    sqlite3_update_single(db,TABLE_NAME1,buf,buf1);


    /*查找*/
    printf("select all:\n");
    sqlite3_select_exec(db,TABLE_NAME1,"*",NULL);


    /*關閉資料庫*/
    sqlite3_close(db);

 
    return 0;
}

 

 

具體其他更細節的SQL語句,需要什麼功能就百度搜索,拼接執行。

 

參考資料:

(29條消息) sqlite3資料庫移植詳解_dosthing的博客-CSDN博客_移植sqlite3

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 問題產生: 作者最近在搭建Hadoop+Hive集群時,將NameNode、DataNode、Rm全部部署到一臺物理機上,查詢量較大時連接掛掉。 問題定位: 使用JPS命令查看Metastore服務正常運行,hive2--Runjar掛掉。重啟之後,過段時間又會掛掉。 Linux 內核有個機制叫OO ...
  • 下載 官網下載地址:http://nginx.org/en/download.html Mainline version 開發版Stable version 穩定版Legacy versions 歷史版 滑鼠移動到你要選擇的版本超鏈接上點右鍵 複製鏈接地址 下載:wget http://nginx. ...
  • 編寫hello world腳本 #!/bin/bash # 編寫hello world腳本 echo "Hello World!" ##通過位置變數創建 Linux 系統賬戶及密碼 #!/bin/bash # 通過位置變數創建 Linux 系統賬戶及密碼 #$1 是執行腳本的第一個參數,$2 是執行 ...
  • 該引擎繼承於MergeTree,併在數據塊合併演算法中添加了摺疊行的邏輯。CollapsingMergeTree會非同步的刪除(摺疊)這些除了特定列Sign有1和-1的值以外,其餘所有欄位的值都相等的成對的行。沒有成對的行會被保留。因此,該引擎可以顯著的降低存儲量並提高SELECT查詢效率。 簡單來說就 ...
  • 轉載於:(140條消息) 如何管理oralce口令文件和參數文件_oracle 口令文件_夢想家DBA匠人的博客-CSDN博客口令文件審核 Step 1: 使用root賬號將 oracle dba的許可權移除 [root@oracle-db-19c ~]# su - oracle[oracle@ora ...
  • 前言 Redis 提供了 2 個不同形式的持久化方式: RDB(Redis DataBase) AOF(Append Of File) RDB 在指定的時間間隔內將記憶體中的數據集快照寫入磁碟, 也就是行話講的 Snapshot 快照,它恢復時是將快照文件直接讀到記憶體里。 備份是如何執行的 Redis ...
  • 約束 約束是作用於表中欄位上的規則,用於限制存儲在表中的數據,保證資料庫中數據的正確、有效和完整。 一. 常用的約束 約束作用於表中的欄位,可以在創建表或修改表的時候添加約束。 AUTO_INCREMENT 約束關鍵字 自動增長:用於比如每次新添加一行數據,id就+1。 如果自增和主鍵一起使用時,插 ...
  • 連接查詢用於多表關聯查詢,連接方式不同,查詢重點不同。 內連接 作用:查詢多表之間交集部分數據 關鍵詞:inner join 可簡寫為:join,即 inner join = join 圖示: 左外連接 作用:表 A 左連接表 B,以左表 A 為主查詢,關聯查詢表 B,查詢左表 A 所有數據,以及表 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...