Linux環(huán)境下SQLite簡(jiǎn)單實(shí)現(xiàn)(附示例說(shuō)明)
SQLite 數(shù)據(jù)庫(kù)常用操作指令總結(jié)
SQLite 是輕量級(jí)嵌入式數(shù)據(jù)庫(kù),無(wú)需服務(wù)端,操作指令簡(jiǎn)潔直觀。以下按數(shù)據(jù)庫(kù)管理、表操作、數(shù)據(jù)增刪改查(CRUD)、進(jìn)階操作四大類(lèi),整理最常用的核心指令,并附示例說(shuō)明。
一、數(shù)據(jù)庫(kù)基礎(chǔ)管理
SQLite 數(shù)據(jù)庫(kù)以單個(gè)文件存儲(chǔ)(如 test.db),以下指令用于數(shù)據(jù)庫(kù)的創(chuàng)建、連接與狀態(tài)查看。
操作目的 | 指令格式 | 示例與說(shuō)明 |
連接/創(chuàng)建數(shù)據(jù)庫(kù) |
|
|
查看當(dāng)前連接的數(shù)據(jù)庫(kù) |
| 執(zhí)行后顯示當(dāng)前連接的數(shù)據(jù)庫(kù)文件路徑(如 |
退出 SQLite 命令行 |
| 輸入 |
二、數(shù)據(jù)表核心操作
數(shù)據(jù)表是存儲(chǔ)數(shù)據(jù)的載體,需先定義表結(jié)構(gòu)(字段名、數(shù)據(jù)類(lèi)型、約束),再進(jìn)行后續(xù)操作。
1. 創(chuàng)建表(CREATE TABLE)
格式:
CREATE TABLE [IF NOT EXISTS] 表名 (
字段1 數(shù)據(jù)類(lèi)型 [約束],
字段2 數(shù)據(jù)類(lèi)型 [約束],
...
[主鍵約束/外鍵約束]
);關(guān)鍵說(shuō)明:
IF NOT EXISTS:可選,避免表已存在時(shí)報(bào)錯(cuò)。- SQLite 常用數(shù)據(jù)類(lèi)型:
INTEGER(整數(shù))、TEXT(字符串)、REAL(浮點(diǎn)數(shù))、BLOB(二進(jìn)制,如圖片)、NUMERIC(自動(dòng)適配數(shù)值類(lèi)型)。 - 常見(jiàn)約束:
PRIMARY KEY(主鍵,唯一且非空)、NOT NULL(字段不可為空)、UNIQUE(字段值唯一)、DEFAULT [值](默認(rèn)值)。
示例:創(chuàng)建 user 表(存儲(chǔ)用戶(hù)信息)
CREATE TABLE IF NOT EXISTS user (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- 主鍵,自動(dòng)遞增(AUTOINCREMENT 僅 INTEGER 可用)
name TEXT NOT NULL, -- 用戶(hù)名,非空
age INTEGER DEFAULT 18, -- 年齡,默認(rèn)18
email TEXT UNIQUE, -- 郵箱,唯一(避免重復(fù)注冊(cè))
create_time TEXT DEFAULT (datetime('now', 'localtime')) -- 注冊(cè)時(shí)間,默認(rèn)當(dāng)前本地時(shí)間
);2. 查看表相關(guān)信息
操作目的 | 指令格式 | 示例與說(shuō)明 |
查看所有表名 |
| 執(zhí)行后顯示當(dāng)前數(shù)據(jù)庫(kù)中所有表(如 |
查看表結(jié)構(gòu)(字段詳情) |
|
|
3. 修改表結(jié)構(gòu)(ALTER TABLE)
SQLite 對(duì) ALTER TABLE 支持有限,僅支持重命名表和添加字段,不支持刪除/修改已有字段(需間接實(shí)現(xiàn),如建新表遷移數(shù)據(jù))。
操作目的 | 指令格式 | 示例與說(shuō)明 |
重命名表 |
|
|
給表添加新字段 |
|
|
4. 刪除表(DROP TABLE)
格式:
DROP TABLE [IF EXISTS] 表名;
示例:
DROP TABLE IF EXISTS users; -- 若 `users` 表存在則刪除,避免報(bào)錯(cuò)
三、數(shù)據(jù)增刪改查(CRUD)
數(shù)據(jù)表創(chuàng)建后,核心操作是對(duì)數(shù)據(jù)的新增、刪除、修改和查詢(xún)。
1. 新增數(shù)據(jù)(INSERT)
向表中插入一條或多條記錄。
格式1:指定字段插入(推薦,字段順序可自定義)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);
格式2:不指定字段(需按表結(jié)構(gòu)字段順序插入所有值)
INSERT INTO 表名 VALUES (值1, 值2, ...); -- 主鍵若為 AUTOINCREMENT,可傳 NULL 自動(dòng)生成
格式3:批量插入
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1-1, 值1-2, ...), (值2-1, 值2-2, ...), ...;
示例:向 user 表插入數(shù)據(jù)
-- 1. 指定字段插入(忽略 id,自動(dòng)遞增;忽略 create_time,用默認(rèn)時(shí)間)
INSERT INTO user (name, age, email) VALUES ('張三', 25, 'zhangsan@test.com');
-- 2. 批量插入
INSERT INTO user (name, age, email) VALUES
('李四', 30, 'lisi@test.com'),
('王五', 22, 'wangwu@test.com');注意:字符串值需用 '單引號(hào)' 包裹,數(shù)值類(lèi)型直接寫(xiě)(如 25 無(wú)需引號(hào))。
2. 查詢(xún)數(shù)據(jù)(SELECT)
SQLite 最核心的操作,用于從表中篩選、排序、限制數(shù)據(jù),語(yǔ)法靈活。
基礎(chǔ)格式(查詢(xún)所有字段/指定字段)
-- 查詢(xún)指定字段 SELECT 字段1, 字段2, ... FROM 表名; -- 查詢(xún)所有字段(* 表示所有) SELECT * FROM 表名;
帶條件查詢(xún)(WHERE)
篩選符合條件的記錄,支持 =、!=、>、<、>=、<=、LIKE(模糊匹配)、IN(范圍匹配)等條件。
SELECT * FROM user WHERE age > 23; -- 查詢(xún)年齡大于23的用戶(hù) SELECT name, email FROM user WHERE email LIKE '%test.com'; -- 模糊匹配郵箱以 test.com 結(jié)尾的用戶(hù) SELECT * FROM user WHERE age IN (22, 25, 30); -- 查詢(xún)年齡為22、25、30的用戶(hù)
排序(ORDER BY)
按指定字段升序(ASC,默認(rèn))或降序(DESC)排列結(jié)果。
SELECT * FROM user ORDER BY age DESC; -- 按年齡降序排列(從大到小) SELECT name, age FROM user ORDER BY age ASC, name DESC; -- 先按年齡升序,再按姓名降序
限制結(jié)果數(shù)量(LIMIT)
只返回前 N 條記錄,常用于分頁(yè)(搭配 OFFSET 實(shí)現(xiàn)分頁(yè),OFFSET M 表示跳過(guò)前 M 條)。
SELECT * FROM user LIMIT 2; -- 返回前2條記錄 SELECT * FROM user ORDER BY age DESC LIMIT 2 OFFSET 1; -- 跳過(guò)第1條,返回接下來(lái)的2條(即第2、3條)
去重(DISTINCT)
去除結(jié)果中重復(fù)的記錄(基于指定字段)。
SELECT DISTINCT age FROM user; -- 查詢(xún)所有不重復(fù)的年齡
統(tǒng)計(jì)(COUNT/SUM/AVG 等聚合函數(shù))
COUNT(*):統(tǒng)計(jì)記錄總數(shù);COUNT(字段):統(tǒng)計(jì)該字段非空值的數(shù)量。SUM(字段):計(jì)算字段值總和;AVG(字段):計(jì)算字段值平均值。
<code>SELECT COUNT(*) AS user_count FROM user; -- 統(tǒng)計(jì)用戶(hù)總數(shù),結(jié)果列名用 AS 改為 user_count SELECT AVG(age) AS avg_age FROM user; -- 計(jì)算用戶(hù)平均年齡 SELECT SUM(age) FROM user WHERE age > 25; -- 計(jì)算年齡大于25的用戶(hù)年齡總和</code>
3. 修改數(shù)據(jù)(UPDATE)
更新表中符合條件的記錄,必須加 WHERE 條件,否則會(huì)修改所有記錄!
格式:
UPDATE 表名 SET 字段1=新值1, 字段2=新值2, ... [WHERE 條件];
示例:
-- 將張三的年齡改為26(指定 WHERE 條件,僅修改張三) UPDATE user SET age=26 WHERE name='張三'; -- 將所有年齡小于20的用戶(hù),默認(rèn)年齡改為19(批量修改,需謹(jǐn)慎) UPDATE user SET age=19 WHERE age < 20;
4. 刪除數(shù)據(jù)(DELETE)
刪除表中符合條件的記錄,必須加 WHERE 條件,否則會(huì)刪除所有記錄!
格式:
DELETE FROM 表名 [WHERE 條件];
示例:
-- 刪除郵箱為 wangwu@test.com 的用戶(hù) DELETE FROM user WHERE email='wangwu@test.com'; -- 刪除年齡大于35的用戶(hù) DELETE FROM user WHERE age > 35;
四、進(jìn)階操作
1. 事務(wù)管理(BEGIN/COMMIT/ROLLBACK)
SQLite 支持事務(wù),確保一組操作要么全部成功,要么全部失?。ū苊鈹?shù)據(jù)不一致)。
BEGIN TRANSACTION;或BEGIN;:開(kāi)始事務(wù)。COMMIT;:提交事務(wù)(所有操作生效,持久化到數(shù)據(jù)庫(kù))。ROLLBACK;:回滾事務(wù)(取消事務(wù)內(nèi)所有未提交的操作)。
示例:批量插入數(shù)據(jù),出錯(cuò)則回滾
BEGIN;
INSERT INTO user (name, email) VALUES ('趙六', 'zhaoliu@test.com');
INSERT INTO user (name, email) VALUES ('孫七', 'sunqi@test.com'); -- 若此句報(bào)錯(cuò)(如郵箱重復(fù))
COMMIT; -- 報(bào)錯(cuò)則執(zhí)行 ROLLBACK,兩句插入都不生效2. 索引(CREATE INDEX)
索引用于加速查詢(xún)(尤其表數(shù)據(jù)量大時(shí)),但會(huì)增加插入/修改/刪除的耗時(shí)(需維護(hù)索引)。
格式:
CREATE [UNIQUE] INDEX [IF NOT EXISTS] 索引名 ON 表名 (字段1, 字段2, ...);
示例:
-- 給 user 表的 email 字段創(chuàng)建唯一索引(避免重復(fù),同時(shí)加速郵箱查詢(xún)) CREATE UNIQUE INDEX IF NOT EXISTS idx_user_email ON user (email); -- 給 age 字段創(chuàng)建普通索引(加速年齡相關(guān)查詢(xún)) CREATE INDEX IF NOT EXISTS idx_user_age ON user (age);
刪除索引:
DROP INDEX IF EXISTS 索引名; -- 如 DROP INDEX idx_user_age;
五、常用輔助指令(命令行特有)
SQLite 命令行中,以 . 開(kāi)頭的指令用于輔助操作,非 SQL 標(biāo)準(zhǔn)語(yǔ)法:
.help:查看所有 SQLite 命令行指令幫助。.mode column:以表格形式顯示查詢(xún)結(jié)果(更易讀)。.header on:顯示查詢(xún)結(jié)果的字段名(配合.mode column使用)。.read [SQL文件路徑]:執(zhí)行外部 SQL 文件(如.read init.sql,執(zhí)行init.sql中的所有指令)。
六、關(guān)鍵注意事項(xiàng)
- SQL 指令大小寫(xiě)不敏感:
SELECT和select效果一致,但建議關(guān)鍵字(如SELECT、INSERT)大寫(xiě),表名/字段名小寫(xiě),提高可讀性。 - 字符串用單引號(hào):SQLite 中字符串必須用
'單引號(hào)'包裹,雙引號(hào)可能報(bào)錯(cuò)(不同數(shù)據(jù)庫(kù)兼容問(wèn)題)。 - 主鍵自動(dòng)遞增:僅
INTEGER類(lèi)型的主鍵可加AUTOINCREMENT,插入時(shí)傳NULL即可自動(dòng)生成唯一ID。 - 避免誤操作:
UPDATE和DELETE必須加WHERE條件,否則會(huì)修改/刪除全表數(shù)據(jù)(無(wú)回收站,無(wú)法恢復(fù))。
SQLite3 C語(yǔ)言實(shí)現(xiàn)增刪改查知識(shí)點(diǎn)小結(jié)
SQLite3 是輕量級(jí)嵌入式數(shù)據(jù)庫(kù),無(wú)需獨(dú)立服務(wù),通過(guò) C 語(yǔ)言 API 可直接操作。以下總結(jié)核心知識(shí)點(diǎn)、常用 API 及簡(jiǎn)化版增刪改查案例,避免復(fù)雜判斷,聚焦基礎(chǔ)功能實(shí)現(xiàn)。
一、核心知識(shí)點(diǎn)與常用 API
1. 編譯與鏈接
- 依賴(lài):需包含 SQLite3 頭文件
sqlite3.h,鏈接時(shí)添加 SQLite3 庫(kù)(如 Linux 下-lsqlite3,Windows 下鏈接sqlite3.lib)。 - 編譯命令示例(Linux):
gcc main.c -o sqlite_demo -lsqlite3
2. 核心 API 說(shuō)明
API 函數(shù)原型 | 功能說(shuō)明 | 關(guān)鍵參數(shù)/返回值 |
| 打開(kāi)/創(chuàng)建數(shù)據(jù)庫(kù) | - |
| 執(zhí)行 SQL 語(yǔ)句(增、刪、改、查均可用,查需配合回調(diào)) | - |
| 關(guān)閉數(shù)據(jù)庫(kù) | - 需確保所有 SQL 操作完成后調(diào)用 |
| 釋放錯(cuò)誤信息內(nèi)存 | - 必須釋放 |
回調(diào)函數(shù)原型: | 查詢(xún)時(shí)每行數(shù)據(jù)的處理函數(shù)(自動(dòng)被 | - |
二、簡(jiǎn)化版增刪改查案例
以下案例實(shí)現(xiàn)一個(gè) student 表(包含 id 主鍵、name 姓名、age 年齡)的完整操作,代碼無(wú)復(fù)雜判斷,僅保留核心邏輯。
步驟 1:完整代碼實(shí)現(xiàn)
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
// 1. 查詢(xún)回調(diào)函數(shù):打印每行查詢(xún)結(jié)果
int query_callback(void *arg, int col_num, char **col_val, char **col_name) {
// 打印列名(僅第一行數(shù)據(jù)時(shí)打印一次)
static int is_first_row = 1;
if (is_first_row) {
for (int i = 0; i < col_num; i++) {
printf("%-10s", col_name[i]); // 左對(duì)齊,占10字符
}
printf("\n");
is_first_row = 0;
}
// 打印當(dāng)前行數(shù)據(jù)
for (int i = 0; i < col_num; i++) {
// 若值為NULL,顯示"NULL",否則顯示值
printf("%-10s", col_val[i] ? col_val[i] : "NULL");
}
printf("\n");
return 0; // 繼續(xù)遍歷下一行
}
int main() {
sqlite3 *db = NULL; // 數(shù)據(jù)庫(kù)句柄
char *err_msg = NULL; // 錯(cuò)誤信息
int ret; // API返回值
// 2. 打開(kāi)/創(chuàng)建數(shù)據(jù)庫(kù)(若不存在則自動(dòng)創(chuàng)建)
ret = sqlite3_open("student.db", &db);
if (ret != SQLITE_OK) {
printf("打開(kāi)數(shù)據(jù)庫(kù)失?。?s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
printf("打開(kāi)數(shù)據(jù)庫(kù)成功!\n");
// 3. 創(chuàng)建表(若表不存在則創(chuàng)建)
const char *create_sql = "CREATE TABLE IF NOT EXISTS student ("
"id INT PRIMARY KEY," // 主鍵(唯一標(biāo)識(shí))
"name TEXT," // 姓名
"age INT);"; // 年齡
ret = sqlite3_exec(db, create_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("創(chuàng)建表失?。?s\n", err_msg);
sqlite3_free(err_msg); // 釋放錯(cuò)誤信息
sqlite3_close(db);
return 1;
}
printf("創(chuàng)建表成功(或表已存在)!\n");
// 4. 插入數(shù)據(jù)(增)
const char *insert_sql = "INSERT INTO student (id, name, age) "
"VALUES (1, 'Zhang San', 20), " // 插入2條數(shù)據(jù)
"(2, 'Li Si', 21);";
ret = sqlite3_exec(db, insert_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("插入數(shù)據(jù)失敗(可能主鍵重復(fù)):%s\n", err_msg);
sqlite3_free(err_msg);
} else {
printf("插入數(shù)據(jù)成功!\n");
}
// 5. 查詢(xún)數(shù)據(jù)(查):調(diào)用回調(diào)函數(shù)處理結(jié)果
printf("\n===== 查詢(xún)所有學(xué)生數(shù)據(jù) =====");
const char *query_sql = "SELECT * FROM student;";
ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("查詢(xún)數(shù)據(jù)失?。?s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
// 6. 更新數(shù)據(jù)(改):修改Li Si的年齡為22
const char *update_sql = "UPDATE student SET age = 22 WHERE name = 'Li Si';";
ret = sqlite3_exec(db, update_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("\n更新數(shù)據(jù)失?。?s\n", err_msg);
sqlite3_free(err_msg);
} else {
printf("\n更新數(shù)據(jù)成功(Li Si年齡改為22)!\n");
}
// 7. 再次查詢(xún),驗(yàn)證更新結(jié)果
printf("\n===== 更新后的數(shù)據(jù) =====");
ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("查詢(xún)數(shù)據(jù)失?。?s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
// 8. 刪除數(shù)據(jù)(刪):刪除id=1的學(xué)生
const char *delete_sql = "DELETE FROM student WHERE id = 1;";
ret = sqlite3_exec(db, delete_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("\n刪除數(shù)據(jù)失?。?s\n", err_msg);
sqlite3_free(err_msg);
} else {
printf("\n刪除數(shù)據(jù)成功(刪除id=1的學(xué)生)!\n");
}
// 9. 第三次查詢(xún),驗(yàn)證刪除結(jié)果
printf("\n===== 刪除后的數(shù)據(jù) =====");
ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("查詢(xún)數(shù)據(jù)失?。?s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
// 10. 關(guān)閉數(shù)據(jù)庫(kù)
sqlite3_close(db);
printf("\n關(guān)閉數(shù)據(jù)庫(kù)成功!\n");
return 0;
}步驟 2:代碼說(shuō)明與運(yùn)行結(jié)果
關(guān)鍵邏輯解釋
- 回調(diào)函數(shù):
query_callback僅用于查詢(xún),自動(dòng)接收每行數(shù)據(jù),先打印列名,再打印每行值。 - 錯(cuò)誤處理:每次調(diào)用
sqlite3_exec后檢查返回值,若失敗則打印err_msg并釋放內(nèi)存(避免泄漏)。 - 冪等操作:
CREATE TABLE IF NOT EXISTS確保表不存在時(shí)才創(chuàng)建,避免重復(fù)創(chuàng)建錯(cuò)誤;插入數(shù)據(jù)若主鍵重復(fù)(如再次運(yùn)行程序),會(huì)提示失敗但不崩潰。
預(yù)期運(yùn)行結(jié)果
打開(kāi)數(shù)據(jù)庫(kù)成功! 創(chuàng)建表成功(或表已存在)! 插入數(shù)據(jù)成功! ===== 查詢(xún)所有學(xué)生數(shù)據(jù) ===== id name age 1 Zhang San 20 2 Li Si 21 更新數(shù)據(jù)成功(Li Si年齡改為22)! ===== 更新后的數(shù)據(jù) ===== id name age 1 Zhang San 20 2 Li Si 22 刪除數(shù)據(jù)成功(刪除id=1的學(xué)生)! ===== 刪除后的數(shù)據(jù) ===== id name age 2 Li Si 22 關(guān)閉數(shù)據(jù)庫(kù)成功!
三、重點(diǎn)注意事項(xiàng)
- 內(nèi)存釋放:
sqlite3_exec輸出的err_msg必須用sqlite3_free釋放,否則會(huì)導(dǎo)致內(nèi)存泄漏。 - 數(shù)據(jù)庫(kù)關(guān)閉:所有操作完成后必須調(diào)用
sqlite3_close,若有未提交的事務(wù),會(huì)自動(dòng)回滾。 - 主鍵唯一性:插入數(shù)據(jù)時(shí)需確保主鍵(如
id)不重復(fù),否則插入失?。ò咐幸烟幚碓撎崾荆?。 - 數(shù)據(jù)類(lèi)型:SQLite3 是弱類(lèi)型數(shù)據(jù)庫(kù),定義的
INT/TEXT僅為提示,實(shí)際可存儲(chǔ)任意類(lèi)型,但建議按定義使用。
總結(jié)
到此這篇關(guān)于Linux環(huán)境下SQLite簡(jiǎn)單實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Linux下SQLite實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQLite3 在嵌入式C環(huán)境中存儲(chǔ)音頻/視頻文件的最優(yōu)方案
本文探討了SQLite3在嵌入式C環(huán)境中存儲(chǔ)音視頻文件的優(yōu)化方案,推薦采用文件路徑存儲(chǔ)結(jié)合元數(shù)據(jù)管理,兼顧效率與資源限制,小文件可使用BLOB存儲(chǔ),輔以壓縮和故障安全機(jī)制,適合資源受限的嵌入式系統(tǒng),對(duì)SQLite3存儲(chǔ)文件相關(guān)知識(shí)感興趣的朋友一起看看吧2025-06-06
SQLite3中的日期時(shí)間函數(shù)使用小結(jié)
這篇文章主要介紹了SQLite3中的日期時(shí)間函數(shù)使用小結(jié),同時(shí)介紹了一些SQLite數(shù)據(jù)庫(kù)的基本知識(shí),需要的朋友可以參考下2014-05-05
Linux系統(tǒng)上sqlite3的使用操作實(shí)例
本文介紹了Linux下sqlite3的安裝、基本操作指令、SQL語(yǔ)句使用、C/C++?API調(diào)用及QT集成方法,涵蓋數(shù)據(jù)庫(kù)創(chuàng)建、表結(jié)構(gòu)定義、數(shù)據(jù)增刪改查、API執(zhí)行與回調(diào)機(jī)制等內(nèi)容,對(duì)linux?sqlite3使用感興趣的朋友一起看看吧2025-06-06
SQLite3中自增主鍵相關(guān)知識(shí)總結(jié)
這篇文章主要介紹了SQLite3中自增主鍵相關(guān)知識(shí)總結(jié),清零的方法、INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用等,需要的朋友可以參考下2014-05-05

