C++ SQLite的使用總結


SQLite3簡介

  SQLite3只是一個輕型的嵌入式數據庫引擎,占用資源非常低,處理速度比Mysql還快,專門用於移動設備上進行適量的數據存取,它只是一個文件,不需要服務器進程。

  SQL語句是SQL操作的指令,我們用C/C++訪問數據庫時,需要用char*即C字符串來保存SQL語句,然后調用相應sqlite3庫的函數,傳入C字符串,來執行SQL指令。

  常用術語表(table)、字段(column,列,屬性)、記錄(row,record)。

轉載:https://www.cnblogs.com/KillerAery/p/9114124.html

  

SQL(structured query language)語句 

  特點:不區分大小寫,每條語句后加";"結尾。

  關鍵字:select、insert、update、delete、from、creat、where、desc、order、by、group、table、alter、view、index等,數據庫中不能使用關鍵字命名表和字段。

  數據定義語句(DDL:Data Definition Language)

  新建表 ⟹ create:create table 表名 (字段名1 字段類型1,字段名2 字段類型2,。。。); create table if not exists 表名 (字段名1 字段類型1,字段名2 字段類型2,。。。);

CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL); 

  刪除表 ⟹ drop:dorp table 表名;drop table if exists 表名;

DROP TABLE IF EXISTS t_person; 

  數據操作語句(DML:Data Manipulation language)

  添加表中的數據 ⟹ insert:insert into 表名 (字段1,字段2,。。。) values (字段1的值,字段2的值);字符串內容用單引號。

INSERT INTO t_person (name, age) VALUES ('大明', 22); 

  修改表中的數據 ⟹ update:update 表名 set 字段1 = 字段1的值,字段2 = 字段2的值,。。。;

UPDATE t_person SET name = '小明', age = 10; // 把表中name字段的值全部改成小明,age字段的值全部改成10。  

UPDATE t_person SET age = 12 WHERE name = '小明'; // 把表中name字段值是小明的age值改為12。  

  刪除表中的數據 ⟹ delete:delete from 表名;delete from 表名 where 字段 = 字段值。

DELETE FROM t_person; // 刪除表中的所有記錄。 

DELETE FROM t_person WHERE age = 25; // 刪除表中字段age等於25的這條記錄。 

DELETE FROM t_person WHERE age > 12 AND age < 15; // 刪除表中年齡大於12且小於15的記錄。 

  數據查詢語句(DQL:Data Query Language)

  select:select 字段1, 字段2, 。。。 from 表名;select 字段1, 字段2, 。。。 from 表名 where 字段 = 某值;select * from 表名;(查詢所有的字段)

  表別名:select 字段1 別名, 字段2 別名,。。。from 表名 別名;select 字段1 別名, 字段2 as 別名,。。。from 表名 as 別名;select 別名.字段1,別名.字段2,。。。from 表名 別名;

SELECT name, age FROM t_person WHERE age < 80; 

SELECT * FROM t_person WHERE age < 80; 

SELECT name, age nianling FROM t_person ren WHERE ren.age > 80 AND nianling < 90; 

  計算記錄條數:select count(字段或者*) from 表名;

SELECT count(name) FROM t_person ren WHERE ren.age > 80; 

SELECT count(*) FROM t_person ren WHERE ren.age > 80; 

  where:where 字段 = 某值;where 字段 is 某值;where 字段 != 某值;where 字段 is not 某值;where 字段 > 某值;where 字段1 = 某值1 and 字段2 < 某值2;where 字段1 = 某值1 or 字段2 > 某值2;

  order by:select * from 表名 order by 字段(默認升序);select * from 表名 order by 字段 desc(降序);select * from 表名 order by 字段 asc(升序);select * from 表名 order by 字段1 asc(先按字段1升序),字段2 desc(再按字段2降序);

SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC; // 先按年齡降序,再按名字升序。  

  limit:select * from 表名 limit 數值1,數值2;分頁查詢,數值1表示跳過前面多少條,數值2表示取出之后多少條。select * from 表名 limit 數值2;(跳過前面0條,相當於select * from 表名 limit 0,數值2,表示最前面多少條數據)

SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC LIMIT 3, 5; // 先篩選,后排序,再分頁。 

  like:模糊查詢,select 字段1, 字段2, 。。。 from 表名 where 字段 like %某值%;

SELECT * FROM t_person WHERE name like '%明%'; 

  存儲類型:integer(整型)、real(浮點型)、text(文本字符串)、blob(二進制數據)。

  實際上SQLite是無類型的,建表時聲明的類型是為了方便程序員之間的交流,是一種良好的編程規范。

  字段約束:

  not null:字段的值不能為空。

  unique:字段的值必需唯一。

  default:指定字段的默認值。

  primary key:主鍵,用來唯一的標識某條記錄,相當於記錄的身份證。主鍵可以是一個或多個字段,應由計算機自動生成和管理。主鍵字段默認包含了not null和unique兩個約束。

  autoincrement:當主鍵是integer類型時,應該增加autoincrement約束,能實現主鍵值的自動增長。

CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL UNIQUE, age integer NOT NULL DEFAULT 30); 

  外鍵:利用外鍵約束可以用來建立表與表之間的聯系,一般是一張表的某個字段,引用着另一張表的主鍵的字段。

  創建一個表: 

CREATE TABLE IF NOT EXISTS t_class (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL UNIQUE);

  創建一個帶外鍵的表:t_student表中有一個叫做fk_student_class的外鍵,這個外鍵的作用是讓t_student表中的class_id字段引用t_class表中的id字段。

CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL, class_id integer NOT NULL, CONSTRAINT fk_student_class FOREIGN KEY (class_id) REFERENCES t_class(id)); 

  利用外鍵來查詢多張表中的數據:

SELECT t.name t_name, t.age t_age, tc.name c_name FROM t_student t, t_class tc WHERE t.class_id = tc.id; // 查詢所有學生對應的班級 

SELECT * FROM t_student WHERE class_id = (SELECT id FROM t_class WHERE name = '四班'); // 查詢四班的所有學生

C/C++上使用SQLite3

  配置好C/C++項目環境:導入sqlite3.lib和sqlite3.dll,包含頭文件#include <sqlite3.h>。

 1、下載sqlite3源碼:http://www.sqlite.org/download.html

  主要是sqlite-amalgamation-XXXXXXX.zip、sqlite-dll-win32-x86-XXXXXXX.zip、sqlite-dll-win32-x64-XXXXXXX.zip

動態庫編譯:

  ps:如果沒有特殊要求,可直接使用下載的sqlite-dll-*********.zip內的dll,那如果不放心就自己編譯。

  1、使用vs2010創建win32工程,然后選擇DLL和空項目,正常情況下vc6-vs2015都支持

  2、把sqlite3.c、sqlite3.h、sqlite3ext.h、sqlite3.def拷貝到工程源文件目錄,前3個文件位於第一個zip,后一個文件位於后2個zip,用哪個就看你的目標環境。

  3、然后通過工程的資源管理器把上述4個文件添加到工程中

  4、修改工程配置,在配置屬性-->c/c++-->預處理器-->預處理器定義,加入

  SQLITE_ENABLE_RTREE
  SQLITE_ENABLE_COLUMN_METADATA

  5、修改工程配置,在配置屬性-->鏈接器-->輸入-->模塊定義文件 加入sqlite3.def,然后編譯即可。

靜態庫編譯: 

  1、使用vs2010創建win32工程,然后選擇靜態庫,去掉預編譯頭,正常情況下vc6-vs2015都支持

  2、把sqlite3.c、sqlite3.h、sqlite3ext.h、sqlite3.def拷貝到工程源文件目錄,前3個文件位於第一個zip,后一個文件位於后2個zip,用哪個就看你的目標環境。

  3、然后通過工程的資源管理器把上述4個文件添加到工程中

  4、修改工程配置,在配置屬性-->c/c++-->預處理器-->預處理器定義,加入

  SQLITE_ENABLE_RTREE
  SQLITE_ENABLE_COLUMN_METADATA

  5、修改工程配置,在配置屬性-->鏈接器-->輸入-->模塊定義文件 加入sqlite3.def,然后編譯即可。

 2、打開或者創建數據庫。

 1     sqlite3 *sql = NULL; // 一個打開的數據庫實例
 2     const char * path = "..../test.db";//某個sql文件的路徑
 3 
 4     // 根據文件路徑打開數據庫連接。如果數據庫不存在,則創建。
 5     // 數據庫文件的路徑必須以C字符串傳入。
 6     int result = sqlite3_open_v2(path, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
 7 
 8     if (result == SQLITE_OK) {
 9         std::clog << "打開數據庫連接成功";
10     }
11     else {
12         std::clog << "打開數據庫連接失敗";
13     }

 3、執行不返回數據的SQL語句(增、刪、改)。

 1     const char *sqlSentence = "INSERT INTO t_person(name, age)     VALUES('夏明', 22); ";        //SQL語句
 2     sqlite3_stmt *stmt = NULL;        //stmt語句句柄
 3 
 4     //進行插入前的准備工作——檢查語句合法性
 5     //-1代表系統會自動計算SQL語句的長度
 6     int result = sqlite3_prepare_v2(sql, sqlSentence, -1, &stmt, NULL);
 7 
 8     if (result == SQLITE_OK) {
 9         std::clog<< "添加數據語句OK";
10         //執行該語句
11         sqlite3_step(stmt);
12     }
13     else {
14         std::clog << "添加數據語句有問題";
15     }
16     //清理語句句柄,准備執行下一個語句
17     sqlite3_finalize(stmt);        

 4、執行返回數據的SQL語句(查)

 1     const char *sqlSentence = "SELECT name, age FROM t_person WHERE age < 30;";    //SQL語句
 2     sqlite3_stmt *stmt = NULL;    // stmt語句句柄
 3 
 4     //進行查詢前的准備工作——檢查語句合法性
 5     //-1代表系統會自動計算SQL語句的長度
 6     int result = sqlite3_prepare_v2(sql, sqlSentence, -1, &stmt, NULL);
 7 
 8     if (result == SQLITE_OK) {
 9         std::clog <<  "查詢語句OK";
10             // 每調一次sqlite3_step()函數,stmt語句句柄就會指向下一條記錄
11             while (sqlite3_step(stmt) == SQLITE_ROW) {
12                 // 取出第0列字段的值
13                 const unsigned char *name = sqlite3_column_text(stmt, 0);
14                 // 取出第1列字段的值
15                 int age = sqlite3_column_int(stmt, 1);
16                 //輸出相關查詢的數據
17                 std::clog << "name = " << name <<", age = "<< age;
18             }
19     }
20     else {
21         std::clog << "查詢語句有問題";
22     }
23     //清理語句句柄,准備執行下一個語句
24     sqlite3_finalize(stmt);

 5、關閉數據庫:sqlite3_close_v2(sqlite3* sql)

1      if (sql) {
2         sqlite3_close_v2(sql);
3         sql = nullptr;
4     }

SQLite3 庫函數 總結

  1.打開數據庫

int sqlite3_open_v2(
const char *filename,   // 數據庫的文件路徑
sqlite3 **ppDb,       // 數據庫實例
int flags,          // 標志
const char *zVfs      // 使用該數據庫的虛擬機的名字,這里我們不需要用,直接NULL
);

  flags參數有如下標志:
  SQLITE_OPEN_NOMUTEX: 設置數據庫連接運行在多線程模式(沒有指定單線程模式的情況下)
  SQLITE_OPEN_FULLMUTEX:設置數據庫連接運行在串行模式。
  SQLITE_OPEN_SHAREDCACHE:設置運行在共享緩存模式。
  SQLITE_OPEN_PRIVATECACHE:設置運行在非共享緩存模式。
  SQLITE_OPEN_READWRITE:指定數據庫連接可以讀寫。
  SQLITE_OPEN_CREATE:如果數據庫不存在,則創建。

 2.檢查SQL語句的合法性(查詢前的准備)

 若語句合法即編譯通過,則將語句產生的指令塞進stmt句柄(此時並未執行指令)

int sqlite3_prepare_v2(
    sqlite3 *db,                                    // 數據庫實例
    const char *zSql,                               // 需要檢查的SQL語句
    int nByte,                                      // SQL語句的最大字節長度
    sqlite3_stmt **ppStmt,                          // stmt句柄,用來存儲SQL stmt指令
    const char **pzTail
);

 3.執行stmt句柄(執行存儲在stmt句柄的指令

 如果指令能查詢到下一行數據,就會返回SQLITE_ROW

 如果指令(例如寫入數據)不需要返還數據,就會返還SQLITE_DONE

int sqlite3_step(
  sqlite3_stmt* stmt    //stmt句柄
 ); 

 4.利用stmt句柄獲得第iCol字段的值(字段的下標從0開始)

 //執行完查詢句柄后,stmt就會指向查到的數據

 //然后可以通過stmt獲取相應數據

double sqlite3_column_double(sqlite3_stmt*, int iCol);                  // 浮點數據
int sqlite3_column_int(sqlite3_stmt*, int iCol);                        // 整型數據
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);            // 長整型數據
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);               // 二進制文本數據
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);      // 字符串數據

清理語句句柄(以便重復使用同一個stmt句柄)

int sqlite3_finalize(
  sqlite_stmt* stmt      //stmt句柄
);

關閉數據庫連接

int sqlite3_close_v2(
  sqlite3 * sql,            // 數據庫實例
);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM