Linux下sqlite3基本指令之具體應用
整理一下sqlite3資料庫在檔案中的操作用法(程式碼選自UDP網路聊天室):
建立(資料庫檔案)user.db檔案
函式原型(開啟):
int sqlite3_open(const char* fileName, sqlite3** ppDB);
函式功能:開啟一個數據庫;若該資料庫檔案不存在,則自動建立。開啟或者建立資料庫的命令會被快取,直到這個資料庫真正被呼叫的時候才會被執行。
輸入引數:fileName,待開啟的資料庫檔名稱,包括路徑,以’\0’結尾; 特別說明:SQLite 支援記憶體資料庫,記憶體方式儲存使用檔名“:memory:”
輸出引數:ppDB,返回開啟的資料庫控制代碼;
返回值:執行成功返回SQLITE_OK,否則返回其他值;
int ret;
sqlite3 *ppdb = NULL;
ret = sqlite3_open("user.db", &ppdb);
if (ret != SQLITE_OK)
{
perror("sqlite3_open");
exit(1);
}
函式原型(執行):
int sqlite3_exec(sqlite3* pDB, const char sql, sqlite_callback callback, void*para, char* errMsg);
函式功能:編譯和執行零個或多個SQL 語句,查詢的結果返回給回撥函式callback
ret = sqlite3_exec(ppdb, "create table if not exists save_info(account text primary key, password text, nickname text, moto text, likes integer, vip text, qq_email text, administrator text, shut_up text);", NULL, NULL, NULL);
if (ret != SQLITE_OK)
{
perror("sqlite3_exec_create_table");
exit(1);
}
語法註釋:
[INTO]:一個可選的關鍵字,可以將它用在 INSERT 和目標表之間。
table_name:將要接收資料的表或 table 變數的名稱。
(column_list):要在其中插入資料的一列或多列的列表。必須用圓括號將column_list括起來,並且用逗號進行分隔。
VALUES:引入要插入的資料值的列表。對於column_list(如果已指定)中或者表中的每個列,都必須有一個數據值。必須用圓括號將值列表括起來。如果 VALUES 列表中的值與表中列的順序不相同,或者未包含表中所有列的值,那麼必須使用column_list明確地指定儲存每個傳入值的列。
sprintf(admin, "insert into save_info values('%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%s')", account, password, nickname,
moto, likes, vip, qq_email, administrator, shut_up);//伺服器啟動後自行生成一個管理員帳號
ret = sqlite3_exec(ppdb, admin, NULL, NULL, NULL);
if (ret != SQLITE_OK)
{
perror("sqlite3_exec_insert into");
exit(1);
}
修改資料
Update <表名>
Set <列名>=<表示式>[{, <列名>=<表示式>}] Set 列名 表示式 [{, 列名 表示式 }] [Where <條件>]
sqlite3_get_table函式原型:
int sqlite3_get_table(sqlite3* pDB, const char sql,char *pResult, int rowCount,int * columnCount, char errMsg);
函式功能:執行SQL 語句,通過一維陣列返回結果;一般用於資料記錄查詢
下面是聊天室註冊和登入部分的程式碼:
void server_save_info(sqlite3 *ppdb, Userinfo *recvbuf, Userinfo *sendbuf)//註冊
{
int ret;
char auff[1024];
sprintf(auff, "insert into save_info values('%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%s')", recvbuf->account, recvbuf->password,
recvbuf->nickname, recvbuf->moto, recvbuf->likes, recvbuf->vip, recvbuf->qq_email, recvbuf->administrator, recvbuf->shut_up);
ret = sqlite3_exec(ppdb, auff, NULL, NULL, NULL);
if (ret != SQLITE_OK)
{
perror("sqlite3_exec");
strcpy(sendbuf->buf, "帳號已存在!");
}
else
{
strcpy(sendbuf->buf, "註冊成功!");
}
}
**dbresult[i]是從select出來的資料中尋找,從零開始數,數完第一行的列表名稱後,下一行的資料才是要尋找的值**
void server_login(sqlite3 *ppdb, Userinfo *recvbuf, Userinfo *sendbuf, Node **head, struct sockaddr_in *tmp_addr) //登入
{
bzero(sendbuf, sizeof(*sendbuf));
char **dbresult = NULL;
char *errmsg = NULL;//用來儲存錯誤資訊字串
int nrow;//查詢出多少記錄(總行數)
int ncolumn;//查詢出來的記錄有多少欄位,(總列數)
int ret, i;
char cuff[1024];
sprintf(cuff, "select account, password, nickname, moto, likes, vip , administrator from save_info where account = '%s' and password = '%s'", recvbuf->account, recvbuf->password);
ret = sqlite3_get_table(ppdb, cuff, &dbresult, &nrow, &ncolumn, &errmsg);//執行成功返回SQLITE_OK,否則返回其他值
if (ret != SQLITE_OK)
{
perror("sqlite3_get_table_server_login");
return;
}
if (1 == nrow)
{
Node *tmp = (*head)->next;
while (tmp != (*head))
{
if (!strcmp(tmp->nickname, dbresult[9]))
{
strcpy(sendbuf->buf, "該帳號已在其他地方登入!");
return;
}
tmp = tmp->next;
}
strcpy(sendbuf->buf, "登入成功!");
strcpy(sendbuf->nickname, dbresult[9]);
strcpy(sendbuf->moto, dbresult[10]);
sendbuf->likes = (*dbresult[11]) - 48;
strcpy(sendbuf->vip, dbresult[12]);
strcpy(sendbuf->administrator, dbresult[13]);
Node *p = (Node *)malloc(sizeof(Node));//連結串列用來記錄帳號是否已登入,登入的帳號接入連結串列
if (NULL == p)
{
printf("Malloc Failure !\n");
return;
}
p->client_addr.sin_family = tmp_addr->sin_family;
p->client_addr.sin_port = tmp_addr->sin_port;
p->client_addr.sin_addr.s_addr = tmp_addr->sin_addr.s_addr;
strcpy(p->nickname, dbresult[9]);
p->next = (*head)->next;
(*head)->next = p;//迴圈連結串列; 記憶:head始終在最右邊,新來的結點在最左邊,head->next 始終指向p
}
else
{
strcpy(sendbuf->buf, "帳號或密碼錯誤");
}
}