Trong phần này, bạn sẽ học cách dùng SQLite trong chương trình C/C++.
Cài đặt
Trước khi dùng SQLite trong C/C++, cần đảm bảo thư viện SQLite đã cài đặt. Xem chương SQLite Installation để hiểu quy trình.
Các API giao diện C/C++ SQLite
Các routine quan trọng sau đủ cho yêu cầu làm việc với SQLite database từ C/C++. Nếu cần ứng dụng phức tạp hơn, xem tài liệu chính thức SQLite.
| STT | API & Mô tả |
|---|---|
| 1 | sqlite3_open(const char *filename, sqlite3 **ppDb)Mở kết nối đến file database SQLite, trả về đối tượng kết nối dùng cho các routine khác. Nếu filename là NULL hoặc ':memory:', tạo database trong RAM chỉ tồn tại trong phiên. Nếu filename không NULL, mở file database theo tên. Nếu file không tồn tại, tạo file mới. |
| 2 | sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)Cách nhanh, dễ để thực thi lệnh SQL từ đối số sql (có thể nhiều lệnh). Tham số 1: đối tượng database mở. sqlite_callback: callback, data là đối số 1, errmsg bắt lỗi. Phân tích và thực thi từng lệnh trong sql cho đến hết chuỗi hoặc gặp lỗi. |
| 3 | sqlite3_close(sqlite3*)Đóng kết nối database đã mở bằng sqlite3_open(). Tất cả prepared statements phải finalized trước khi đóng. Nếu còn query chưa finalized, trả về SQLITE_BUSY với lỗi "Unable to close due to unfinalized statements". |
Kết nối Database
Đoạn code C sau kết nối database hiện có. Nếu không tồn tại, sẽ tạo mới và trả về đối tượng database.
Ví dụ
#include <stdio.h>
#include <sqlite3.h>
int main(int argc, char* argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("test.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return 0;
} else {
fprintf(stderr, "Opened database successfully\n");
}
sqlite3_close(db);
return 0;
}
Kết quả
$gcc test.c -l sqlite3 $./a.out Opened database successfully
Tạo bảng (Create Table)
Đoạn code tạo bảng COMPANY trong database đã tạo.
Ví dụ
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
int i;
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
rc = sqlite3_open("test.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return 0;
} else {
fprintf(stdout, "Opened database successfully\n");
}
sql = "CREATE TABLE COMPANY("
"ID INT PRIMARY KEY NOT NULL,"
"NAME TEXT NOT NULL,"
"AGE INT NOT NULL,"
"ADDRESS CHAR(50),"
"SALARY REAL );";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Table created successfully\n");
}
sqlite3_close(db);
return 0;
}
Kết quả (Kiểm tra file database)
-rwxr-xr-x. 1 root root 9567 May 8 02:31 a.out -rw-r--r--. 1 root root 1207 May 8 02:31 test.c -rw-r--r--. 1 root root 3072 May 8 02:31 test.db
Thao tác Insert
Tạo bản ghi trong bảng COMPANY.
Ví dụ
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
int i;
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
rc = sqlite3_open("test.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return 0;
} else {
fprintf(stderr, "Opened database successfully\n");
}
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
"VALUES (1, 'Paul', 32, 'California', 20000.00 ); "
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 ); "
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
"VALUES (4, 'Mark', 25, 'Rich-Mond', 65000.00 );";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Records created successfully\n");
}
sqlite3_close(db);
return 0;
}
Kết quả
Opened database successfully Records created successfully
Thao tác SELECT
Xem chi tiết callback function dùng trong các ví dụ. Callback cung cấp cách lấy kết quả từ SELECT. Khai báo:
typedef int (*sqlite3_callback)(
void*, /* Data từ đối số 4 của sqlite3_exec() */
int, /* Số cột trong hàng */
char**, /* Mảng chuỗi đại diện các trường trong hàng */
char** /* Mảng chuỗi đại diện tên cột */
);
Nếu callback cung cấp cho sqlite_exec() làm đối số 3, SQLite gọi callback cho mỗi bản ghi xử lý trong mỗi SELECT trong đối số SQL.
Code fetch và hiển thị bản ghi từ bảng COMPANY:
Ví dụ
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
static int callback(void *data, int argc, char **argv, char **azColName) {
int i;
fprintf(stderr, "%s: ", (const char*)data);
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[]) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
rc = sqlite3_open("test.db", &db);
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return 0;
} else {
fprintf(stderr, "Opened database successfully\n");
}
sql = "SELECT * from COMPANY";
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
Kết quả
Opened database successfully Callback function called: ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 20000.0 Callback function called: ID = 2 NAME = Allen AGE = 25 ADDRESS = Texas SALARY = 15000.0 Callback function called: ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 Callback function called: ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully