
嘻道奇闻
- 文章199742
- 阅读14625734
SQLite数据库增删改查实战:C语言快速入门指南
(抓耳挠腮)为什么别人用C语言操作数据库行云流水,你连个数据表都建不起来?今天咱们就来撕开SQLite的神秘面纱。说实在的,这玩意儿比MySQL简单多了,不信?看完这篇你就知道。
??基础三问:SQLite是个啥???
-
??为什么说它像随身U盘???
不像MySQL要装服务端,SQLite就是个.db文件。你复制到U盘里带着走,插到哪台电脑都能用,特别适合做本地数据存储。 -
??和MySQL比谁更香???
举个栗子:MySQL是五星酒店后厨,SQLite是你家厨房。做个学生管理系统这种小项目,用MySQL就像用菜刀切水果——没必要。 -
??C语言怎么和它对话???
全靠三个关键函数:sqlite3_open()开门,sqlite3_exec()传话,sqlite3_close()关门。具体咋用?往下看实战代码。
??场景实操:从零建表到增删改查??
先装sqlite3开发库。Linux下sudo apt-get install sqlite3 libsqlite3-dev,Windows去官网下amalgamation压缩包,把sqlite3.h和sqlite3.c拖进项目。
(突然拍大腿)对了!很多新手卡在编译环节。记住要加链接参数:
bash复制gcc demo.c -lsqlite3 -o demo # Linux下这么写
??连接数据库的生死门??
看这段必用代码,出错率高达80%的新手坑都在里面:
c复制#include
#include int main() { sqlite3 *db; // 这是你的数据库手柄 char *err_msg = 0; // 下面这行可能让你怀疑人生 int rc = sqlite3_open("school.db", &db); if(rc != SQLITE_OK) { fprintf(stderr, "打不开数据库:%s\n", sqlite3_errmsg(db)); return 1; } // 建表语句(小心!SQL写错全盘皆输) char *sql = "CREATE TABLE IF NOT EXISTS students(" "id INTEGER PRIMARY KEY," "name TEXT NOT NULL," "score INT);"; rc = sqlite3_exec(db, sql, 0, 0, &err_msg); if(rc != SQLITE_OK ){ fprintf(stderr, "SQL炸了:%s\n", err_msg); sqlite3_free(err_msg); } else { printf("数据表成了!\n"); } sqlite3_close(db); // 不关数据库,文件锁死给你看 return 0; }
(敲黑板)注意第15行的IF NOT EXISTS,这是防止重复建表报错的救命符。还有第28行的关闭操作,忘了这个下次运行程序直接崩溃。
??增删改查四连击??
假设现在要添加学生数据,正确的姿势应该是:
c复制// 接上面连接成功的代码 char *insert_sql = "INSERT INTO students (name, score) " "VALUES ('李雷', 85), ('韩梅梅', 92);"; rc = sqlite3_exec(db, insert_sql, 0, 0, &err_msg);
但等等!这种直接拼接SQL的方式有严重隐患。比如名字里带单引号'O'Neil',直接导致SQL报错。应该用参数绑定:
c复制sqlite3_stmt *stmt; char *sql = "INSERT INTO students (name, score) VALUES (?1, ?2);"; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); // 绑定参数(防SQL注入的关键) sqlite3_bind_text(stmt, 1, "王大力", -1, SQLITE_STATIC); sqlite3_bind_int(stmt, 2, 77); sqlite3_step(stmt); sqlite3_finalize(stmt); // 这个比exec安全多了
??查数据的三大坑??
-
??返回乱码怎么回事???
用sqlite3_column_text()取出的数据要立即复制出来,否则关闭数据库后指针就失效了。 -
??怎么遍历查询结果???
正确姿势:
c复制char *sql = "SELECT * FROM students;"; sqlite3_stmt *stmt; rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0); while((rc = sqlite3_step(stmt)) == SQLITE_ROW) { int id = sqlite3_column_int(stmt, 0); const char *name = (const char*)sqlite3_column_text(stmt, 1); int score = sqlite3_column_int(stmt, 2); printf("学号:%d 姓名:%s 分数:%d\n", id, name, score); } sqlite3_finalize(stmt);
- ??分页查询怎么做???
加LIMIT和OFFSET参数:
c复制"SELECT * FROM students LIMIT 10 OFFSET 20;" // 跳过20条取10条
??致命错误自救指南??
? 数据库被锁住怎么办?
检查是不是有未关闭的数据库连接,或者别的程序正在使用.db文件。
? 提示no such table?
八成是建表语句没执行成功,用sqlite3_exec()建表时记得检查返回值。
? 插入数据总是失败?
看看字段类型对不对,比如往INTEGER字段插字符串肯定报错。
小编观点:别被SQLite的简单外表骗了,事务处理和并发操作才是真门槛。建议新手先用sqlite3命令行工具手动执行SQL,找到感觉再写C代码。记住,每个sqlite3_open()必须对应一个sqlite3_close(),不然等着文件损坏吧。