交叉編譯sqlite3:
#./configure CC=aarch64-linux-gnu-gcc
#make
加-host=arm-linux會生成靜態庫和動態庫,不加只生成靜態庫。
動態庫拷貝到執行環境,還需要:
# ldconfig #使動態庫在系統中更新生效
將庫拷貝到代碼執行環境:
====================================================
以下是轉載:
linux下C語言編程操作數據庫(sqlite3)
置頂 zouleideboke 2017-06-23 17:25:15 16699 收藏 32
展開
前言:C語言中通過調用 sqlite 的函數接口來實現對數據庫的管理(創建數據庫、創建表格、插入數據、查詢、數據、刪除數據等),掌握sqlite數據庫的語法,以及sqlite提供的函數接口,那麼在linux下C語言編程操作數據庫就變得簡單了。
Centos系統一般默認是沒有安裝sqlite3數據庫的,所以我們要到其官網下載,我下載的版本是 sqlite-3.6.16.tar.gz
[zoulei@CentOS sqlite]$ wget http://www.sqlite.org/sqlite-3.6.16.tar.gz
進入下載目錄,解壓文件sqlite-3.6.16.tar.gz解壓後生成sqlite-3.6.16目錄. cd 進入sqlite-3.6.16
[zoulei@CentOS sqlite]$ tar -xzvf sqlite-3.6.16.tar.gz
[zoulei@CentOS sqlite]$ cd sqlite-3.6.16
[zoulei@CentOS sqlite-3.6.16]$
執行配置腳本,生成相關文件之後使用make命令編譯
[zoulei@CentOS sqlite-3.6.16]$ ./configure
[zoulei@CentOS sqlite-3.6.16]$ make
[zoulei@CentOS sqlite-3.6.16]$ sudo make install
安裝完成之後會在sqlite-3.6.16目錄下生成sqlite3等文件
在linux下sqlite3具體怎麼操作,可以參考這篇博客:點擊打開鏈接
看代碼:sqlite.c
/*********************************************************************************
* Copyright: (C) 2017 zoulei
* All rights reserved.
*
* Filename: insert.c
* Description: This file i
*
* Version: 1.0.0(2017年06月22日)
* Author: zoulei <[email protected]>
* ChangeLog: 1, Release initial version on "2017年06月22日 19時31分12秒"
*
********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
#define _DEBUG_
int main(int argc, char**argv)
{
sqlite3 *db=NULL;
int len;
int i=0;
int nrow=0;
int ncolumn = 0;
char *zErrMsg =NULL;
char **azResult=NULL; //二維數組存放結果
/* 打開數據庫 */
len = sqlite3_open("user",&db);
if( len )
{
/* fprintf函數格式化輸出錯誤信息到指定的stderr文件流中 */
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));//sqlite3_errmsg(db)用以獲得數據庫打開錯誤碼的英文描述。
sqlite3_close(db);
exit(1);
}
else printf("You have opened a sqlite3 database named user successfully!\n");
/* 創建表 */
char *sql = " CREATE TABLE SensorData(\
ID INTEDER PRIMARY KEY,\
SensorID INTEGER,\
siteNum INTEGER,\
Time VARCHAR(12),\
SensorParameter REAL\
);" ;
sqlite3_exec(db,sql,NULL,NULL,&zErrMsg);
#ifdef _DEBUG_
printf("%s\n",zErrMsg);
sqlite3_free(zErrMsg);
#endif
/*插入數據 */
char*sql1 ="INSERT INTO 'SensorData'VALUES(NULL,1,2,201430506201,13.5);";
sqlite3_exec(db,sql1,NULL,NULL,&zErrMsg);
char*sql2 ="INSERT INTO 'SensorData'VALUES(NULL,3,4,201530506302,14.5);";
sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg);
char*sql3 ="INSERT INTO 'SensorData'VALUES(NULL,5,6,201630506413,18.6);";
sqlite3_exec(db,sql3,NULL,NULL,&zErrMsg);
/* 查詢數據 */
sql="select *from SensorData";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
printf("nrow=%d ncolumn=%d\n",nrow,ncolumn);
printf("the result 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 , NULL , NULL , &zErrMsg );
#ifdef _DEBUG_
printf("zErrMsg = %s \n", zErrMsg);
sqlite3_free(zErrMsg);
#endif
/* 查詢刪除後的數據 */
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
printf( "row:%d column=%d\n " , nrow , ncolumn );
printf( "After deleting , the result is : \n" );
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
{
printf( "azResult[%d] = %s\n", i , azResult[i] );
}
sqlite3_free_table(azResult);
#ifdef _DEBUG_
printf("zErrMsg = %s \n", zErrMsg);
sqlite3_free(zErrMsg);
#endif
sqlite3_close(db);
return 0;
}
代碼分析:
其實操作數據庫無非就是如何調用sqlite3提供的API,以及如何使用相應的語句操作sqlite3數據庫進行增,刪,改,查等。那麼下面我們着重分析
一下sqlite3提供的函數接口。
1.打開數據庫函數接口
原型:int sqlite3_open(const char * filename, sqlite3 **ppDb);
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
用這個函數開始數據庫操作。需要傳入兩個參數,一是數據庫文件名,比如:我的虛擬機~/sqlite/路徑下的user文件,文件名不需要一定存在,如果此文件不存在,sqlite會自動建立它。如果它存在,就嘗試把它當數據庫文件來打開。二是sqlite3**,即前面提到的關鍵數據結構。這個結構底層細節如何,不需要管它。函數返回值表示操作是否正確,如果是SQLITE_OK則表示操作正常。相關的返回值sqlite定義了一些宏。具體這些宏的含義可以參考sqlite3.h 文件。
2.關閉數據庫函數接口
原型:int sqlite3_close(sqlite3**ppDb);
ppDb爲我們使用sqlite3_open()函數打開的數據庫鏈接(對應我寫的程序中的db變量)。
3.執行sql語句函數接口
原型:int sqlite3_exec(sqlite3*,const char*sql,sqlite_callback,void*data,char**errmsg);
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be executed */
sqlite_callback, /* Callback function */
void *, /* 1st argument to callback function */
char **errmsg /* Error msg written here */
);
這就是執行一條sql 語句的函數,
第1個參數不再說了,是前面open函數得到的指針。說了是關鍵數據結構。
第2個參數const char*sql是一條sql 語句,以\0結尾。
第3個參數sqlite3_callback 是回調,當這條語句執行之後,sqlite3會去調用你提供的這個函數。通常設爲NULL。
第4個參數void*是你所提供的指針,你可以傳遞任何一個指針參數到這裏,這個參數最終會傳到回調函數裏面,如果不需要傳遞指針給回調函數,可以填NULL。
第5個參數char** errmsg 是錯誤信息。注意是指針的指針。sqlite3裏面有很多固定的錯誤信息。執行sqlite3_exec 之後,執行失敗時可以查閱這個指針(直接 printf("zErrMsg = %s \n", zErrMsg)得到一串字符串信息,這串信息告訴你錯在什麼地方。sqlite3_exec函數通過修改你傳入的指針的指針,把你提供的指針指向錯誤提示信息,這樣sqlite3_exec函數外面就可以通過這個char*得到具體錯誤提示。
************************************************************************************************************************
說明:通常,sqlite3_callback 和它後面的void*這兩個位置都可以填NULL。填NULL表示你不需要回調。比如你做insert 操作,做delete操作,就沒有必要使用回調。而當你做select 時,就要使用回調,因爲sqlite3 把數據查出來,得通過回調告訴你查出了什麼數據。雖然回調顯得代碼整齊,但有時候你還是想要非回調的select 查詢。這可以通過sqlite3_get_table 函數做到。
原型:sqlite3_get_table(sqlite3*db,const char*zsql,char***pazResult,int*nrow,int*ncolumn,char**zErrmsg);
int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
int *pnRow, /* Number of result rows written here */
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
void sqlite3_free_table(char **result);
第1個參數不再多說,看前面的例子。
第2個參數是sql 語句,跟sqlite3_exec 裏的sql 是一樣的。是一個很普通的以\0結尾的char*字符串。
第3個參數是查詢結果,它依然一維數組(不要以爲是二維數組,更不要以爲是三維數組)。它內存佈局是:字段名稱,後面是緊接着是每個字段值。
第4個參數是查詢出多少條記錄(即查出多少行,不包括字段名那行)。
第5個參數是多少個字段(多少列)。
第6個參數是錯誤信息,跟前面一樣,這裏不多說了。
pazResult返回的字符串數量實際上是(*pnRow+1)*(*pnColumn),因爲前(*pnColumn)個是字段名。
注意:如果提供 了errmsg,用來創建錯誤消息的內存是在堆上分佈的。 故在調用後,應該檢查一下是否爲null值,如果有錯誤發生,使用sqlite3_free()釋放errmsg佔用的內存。
*************************************************************************************************************************************************************************
編譯運行:
[zoulei@CentOS sqlite]$ gcc sqlite.c -o sqlite -l sqlite3
[zoulei@CentOS sqlite]$ ./sqlite
You have opened a sqlite3 database named user successfully!
table SensorData already exists
nrow=3 ncolumn=5
the result is:
azResult[0]=ID
azResult[1]=SensorID
azResult[2]=siteNum
azResult[3]=Time
azResult[4]=SensorParameter
azResult[5]=(null)
azResult[6]=1
azResult[7]=2
azResult[8]=201430506201
azResult[9]=13.5
azResult[10]=(null)
azResult[11]=3
azResult[12]=4
azResult[13]=201530506302
azResult[14]=14.5
azResult[15]=(null)
azResult[16]=5
azResult[17]=6
azResult[18]=201630506413
azResult[19]=18.6
zErrMsg = (null)
row:2 column=5
After deleting , the result is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = siteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = (null)
azResult[6] = 3
azResult[7] = 4
azResult[8] = 201530506302
azResult[9] = 14.5
azResult[10] = (null)
azResult[11] = 5
azResult[12] = 6
azResult[13] = 201630506413
azResult[14] = 18.6
zErrMsg = (null)
從程序輸出結果就可以看出,在刪除數據前,我們有三條記錄,刪除數據後我們發現,數據庫內記錄少了。從而實現了我們的刪除數據目的。
****************************************************************************************************************************************************************************************
注意:這裏我們可以看到,azResult 的前面 5 個數據正好是我們的表 SensorData 的列屬性,之後纔是我們要查詢的數據。所以我們
的程序中才有 i<( nrow + 1 ) * ncolumn 的判斷條件:
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s/n", i , azResult[i] );
輸出中有 zErrMsg = (null) 這樣的字句,這是 zErrMsg 保留的錯誤信息,正如你所看到的,zErrMsg 爲空,表明在執行過程中沒有錯誤信息。
***************************************************************************************************************************************************************************
遇到的問題:
[zoulei@CentOS sqlite]$ gcc sqlite.c -o sqlite
/tmp/cccHlOCK.o: In function `main':
opensqlite.c:(.text+0x21): undefined reference to `sqlite3_open'
opensqlite.c:(.text+0x38): undefined reference to `sqlite3_errmsg'
opensqlite.c:(.text+0x5f): undefined reference to `sqlite3_close'
opensqlite.c:(.text+0x83): undefined reference to `sqlite3_close'
collect2: ld 返回 1
問題解決:
出現上述問題是因爲沒有找到庫文件的問題。
由於用到了用戶自己的庫文件,所以應該指明所用到的庫,我們可以這樣編譯:
[zoulei@CentOS sqlite]$ gcc sqlite.c -o sqlite -l sqlite3
通過find命令找出sqlite3依賴的庫:
[zoulei@CentOS sqlite-3.6.16]$ find -name "libsqlite3.so"
./.libs/libsqlite3.so
[zoulei@CentOS sqlite-3.6.16]$ cd ./.libs
[zoulei@CentOS .libs]$ ls
所以用 -l sqlite3 選項就可以了(由於編譯生成的庫文件是 libsqlite3.so.0.8.6 等,去掉前面的lib和後面的版本標誌,就剩下 sqlite3 了所以是 -l sqlite3 )
————————————————
版權聲明:本文爲CSDN博主「zouleideboke」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zouleideboke/article/details/73649886