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

