數據庫簡介
常用的數據庫
大型數據庫:Oracle
中型數據庫:Server 是微軟開發的數據庫產品,主要支持 windows 平臺。
小型數據庫:mySQL 是一個小型關系型數據庫管理系統,開放源碼 。(嵌入式不需要存儲太多數據。)
SQLite 基礎
SQLite 的源代碼是 C,其源代碼完全開放,是一個輕量級的嵌入式數據庫。
特性:
1、零配置一無需安裝和管理配置;
2、儲存在單一磁盤文件中的一個完整的數據庫;
3、數據庫文件可以在不同字節順序的機器間自由共享;
4、支持數據庫大小至2TB;
5、嵌入式足夠小,全部源碼大致3萬行 c 代碼,250KB;
6、比目前流行的大多數數據庫對數據的操作要快;
創建 SQLite 數據庫:
-----------------兩種方式都會用得到,重點是代碼創建--------------------
手工創建:
使用 sqlite3 工具,通過手工輸入 SQL 命令行完成數據庫創建。
代碼創建:
在代碼中常常動態創建數據庫 —— 在程序運行過程中,當需要進行數據庫操作時,應用程序會首先嘗試打開數據庫,如果數據庫并不存在,則程序將自動建立數據庫,然后再打開數據庫。
Linux 虛擬機中 sqlite3 的安裝
在線安裝方式
1) 確保虛擬機能聯網
2)
● sudo apt-get update
● sudo apt-get install sqlite3
● sudo apt-get install libsqlite3-dev
● sudo apt-get install sqlitebrowser
安裝軟件及開發環境
—>sqlite3 數據庫軟件
—>sqlite3 數據庫開發支持庫
—>sqlite3 數據庫操作軟件
3) 安裝成功后,終端輸入以下指令,判斷是否安裝成功:
sqlite3 my.db
出現下列語句,表示安裝成功,版本不一樣無所謂,只要出現“sqlite>”即可,輸入“.quit”退出數據庫:
基礎 SQL語句 的使用
兩種命令格式:
sqlite3 系統命令
—— 以“.”開頭;
SQL 命令
—— 以“;”結尾。
API 接口
(👆 跳轉至 SQLite 官網)常用接口見 “sqlite3 編程”。
sqlite3 的使用:
1、創建一個數據庫(數據庫為空時,找不到圖標);
2、在新建的數據庫中,創建一張表,并設置主鍵;(表格創建成功后,數據庫的圖標顯現)
3、向新建的表中插入數據;
4、查詢表格中的數據;
5、打開圖形化數據庫;
6、刪除表中一行;
7、刪除整張表;
8、刪除數據庫;
sqlite3 編程
(👆 跳轉至 SQLite 官網)
sqlite3_open
#include<sqlite3.h>
int sqlite3_open(char *path, sqlite3 **db);功能:打開 sqlite 數據庫(或新建數據庫)
參數:path: 數據庫文件路徑 db: 指向數據庫句柄的指針 - 該二級指針指向一級指針,最終會存儲打開的數據庫的首地址
返回值:成功返回0,失敗返回錯誤碼(非零值) 使用: sqlite3 *db;if(sqlite3_open("stu.db", &db) != 0)fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));// sqlite3 自帶的打印錯誤信息 值傳遞: 獲取到值
地址傳遞: 修改值
sqlite3_close
#include<sqlite3.h>
int sqlite3_close(sqlite3 *db);功能:關閉 sqlite 數據庫
參數:db
返回值:成功返回0,失敗返回錯誤碼
sqlite3_errmsg
#include<sqlite3.h>
const char *sqlite3_errmsg(sqlite3 *db);
功能: 打印錯誤信息
參數:db
返回值:返回錯誤信息
使用(e.g.): fprintf(stderr, "sqlite3_open failed: %s\n", sqlite3_errmsg(db));
sqlite3_exec
原型:int sqlite3_exec(sqlite3 *db, /* An open database */const char *sql, /* SQL to be evaluated */int (*callback)(void*, int, char**, char**), /* Callback function */void *arg, /* 1st argument to callback */char **errmsg /* Error msg written here */);功能:執行sql語句;
參數:sqlite3 *db: 指定要操作的數據庫句柄指針;char *sql: 指定要執行的sql語句;int (*callback)(void*, int, char**, char**):回調函數; 該函數指針可以指向返回值是int類型,參數列表是(void*, int, char**, char**)的函數void *arg: 傳遞給回調函數的第一個參數; - 類似線程函數傳參,需強轉 - 不傳參可以填 NULLchar **errmsg: 該二級指針指向的一級指針會存儲錯誤信息的首地址,錯誤信息存儲在靜態存儲區;(定義一個一級指針即可)
返回值:成功:返回 SQLITE_OK,即 0;失敗:返回 error_code,即非 0
// sqlite3.c#include <stdio.h>
#include <sqlite3.h>int num;
char buf[128] = {};
typedef struct{int id;char name[32];float score;
} STU; int main(int argc, char const *argv[])
{sqlite3 *db = NULL;if (sqlite3_open("/home/hq/MyFolders/sqlite3/testdb.db", &db)){fprintf(stderr, "Sqlite3_open failed: %s\n", sqlite3_errmsg(db));return -1;}char *errmsg = NULL;if (sqlite3_exec(db, "CREATE TABLE stu(id int primary key, name char, score float);",NULL, NULL, &errmsg)){fprintf(stderr, "Failed to create a table named \"stu\": %s\n", errmsg);return -1;}if (sqlite3_exec(db, "INSERT INTO stu VALUES(2023052201, \"Frank\", 95);", NULL, NULL, &errmsg)){fprintf(stderr, "Failed to insert: %s\n", errmsg);return -1;}printf("Please input a number:\n");scanf("%d", &num);STU stu;for (int i = 0; i < num; i++){scanf("%d %s %f", &stu.id, stu.name, &stu.score);sprintf(buf, "INSERT INTO stu VALUES(%d, \"%s\", %f);", stu.id, stu.name, stu.score);if (sqlite3_exec(db, buf, NULL, NULL, &errmsg)){fprintf(stderr, "Failed to insert: %s\n", errmsg);return -1;}}sqlite3_close(db);return 0;
}
運行結果如下:
sqlite3_exec 的 回調函數 callback
int callback(void *arg, int columns, char **column_text, char **column_name);功能:sqlite3_exec 每找到一條滿足條件的記錄,就會執行一次回調函數。
參數:void *arg: sqlite3_exec 的第四個參數傳入;int columns: 查詢結果的列數;char **column_text:該二級指針指向一個指針數組,數組中的元素都是 char*類型 的指針,指針指向查詢結果的內容;char **column_name:該二級指針指向一個指針數組,數組中的元素都是 char*類型 的指針,指針指向查詢結果的列名;
返回值:成功時候必須返回0,該返回值會返回給 sqlite3_exec 函數,如果沒有返回0,則 sqlite3_exec 會認為回調函數運行失敗,從而導致 sqlite3_exec 運行失敗。
// sqlite3.c#include <stdio.h>
#include <sqlite3.h>int num;
char buf[128] = {};
typedef struct{int id;char name[32];float score;
} STU; int select_cback(void *arg, int columns, char **column_text, char **column_name){printf("columns: %d\n", columns);printf("column_name: ");for (int i = 0; i < columns; i++)printf("%-12s", column_name[i]); putchar(10);printf("column_text: ");for (int i = 0; i < columns; i++)printf("%-12s", column_text[i]);putchar(10);return 0;
}int main(int argc, char const *argv[])
{sqlite3 *db = NULL;if (sqlite3_open("/home/hq/MyFolders/sqlite3/testdb.db", &db)){fprintf(stderr, "Sqlite3_open failed: %s\n", sqlite3_errmsg(db));return -1;}char *errmsg = NULL;if (sqlite3_exec(db, "CREATE TABLE stu(id int primary key, name char, score float);",NULL, NULL, &errmsg)){fprintf(stderr, "Failed to create a table named \"stu\": %s\n", errmsg);}if (sqlite3_exec(db, "INSERT INTO stu VALUES(2023052201, \"Frank\", 95);", NULL, NULL, &errmsg)){fprintf(stderr, "Failed to insert: %s\n", errmsg);return -1;}printf("Please input a number:\n");scanf("%d", &num);STU stu;for (int i = 0; i < num; i++){scanf("%d %s %f", &stu.id, stu.name, &stu.score);sprintf(buf, "INSERT INTO stu VALUES(%d, \"%s\", %f);", stu.id, stu.name, stu.score);if (sqlite3_exec(db, buf, NULL, NULL, &errmsg)){fprintf(stderr, "Failed to insert: %s\n", errmsg);return -1;}}if (sqlite3_exec(db, "SELECT * FROM stu;", select_cback, NULL, &errmsg)){fprintf(stderr, "Select failed: %s\n", errmsg);return -1;}printf("------------------------\n");if (sqlite3_exec(db, "SELECT name FROM stu WHERE score = 92;", select_cback, NULL, &errmsg)){fprintf(stderr, "Select failed: %s\n", errmsg);return -1;}sqlite3_close(db);return 0;
}
運行結果如下:
sqlite3_get_table(不回調查詢)
int sqlite3_get_table(sqlite3 *db, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg);功能:執行SQL操作
參數: db: 數據庫句柄 sql: SQL語句resultp: 用來指向sql執行結果的指針 (該參數為三級指針,指向二級指針,所以需定義二級指針變量) nrow: 該一級指針指向的內存空間中存儲結果的行數,(一級指針指向變量地址),包括表頭ncolumn: 該一級指針指向的內存空間中存儲結果的列數 errmsg: 該二級指針指向的一級指針會存儲錯誤信息首地址
返回值:成功返回SQLITE_OK,失敗返回錯誤碼
// sqlite3.c#include <stdio.h>
#include <sqlite3.h>int num;
char buf[128] = {};
typedef struct{int id;char name[32];float score;
} STU; int main(int argc, char const *argv[])
{sqlite3 *db = NULL;if (sqlite3_open("/home/hq/MyFolders/sqlite3/testdb.db", &db)){fprintf(stderr, "Sqlite3_open failed: %s\n", sqlite3_errmsg(db));return -1;}char *errmsg = NULL;if (sqlite3_exec(db, "CREATE TABLE stu(id int primary key, name char, score float);",NULL, NULL, &errmsg)){fprintf(stderr, "Failed to create a table named \"stu\": %s\n", errmsg);}if (sqlite3_exec(db, "INSERT INTO stu VALUES(2023052201, \"Frank\", 95);", NULL, NULL, &errmsg)){fprintf(stderr, "Failed to insert: %s\n", errmsg);return -1;}printf("Please input a number:\n");scanf("%d", &num);STU stu;for (int i = 0; i < num; i++){scanf("%d %s %f", &stu.id, stu.name, &stu.score);sprintf(buf, "INSERT INTO stu VALUES(%d, \"%s\", %f);", stu.id, stu.name, stu.score);if (sqlite3_exec(db, buf, NULL, NULL, &errmsg)){fprintf(stderr, "Failed to insert: %s\n", errmsg);return -1;}}char **resultp;int nrow, ncolumn;if (sqlite3_get_table(db, "SELECT * FROM stu;", &resultp, &nrow, &ncolumn, &errmsg)){fprintf(stderr, "Failed to select: %s\n", errmsg);return -1;}printf("--------------------\n");for (int i = 0; i <= nrow; i++){ // 要包含表頭for (int j = 0; j < ncolumn; j++)printf("%-12s", resultp[i*ncolumn+j]);putchar(10);}sqlite3_close(db);return 0;
}
運行結果如下: