如何将 sqlite 列中的数据与 C++ 中的 const char 进行比较
How to compare data in a sqlite column to a const char in c++
我正在尝试将所有列数据与 const char 进行比较,以查看列中的名称是否与连接到游戏服务器的玩家名称匹配。下面的 spaghetticode 中的比较无法正常工作,即使玩家名称已存在于 sqlite 数据库中,也会生成新行。进行这种比较的正确方法是什么?预先感谢您的帮助。
这是有问题的部分的片段:
if(enable_sqlite_db) {
sqlite3_stmt *stmt;
sqlite3 *db;
char *zErrMsg = 0;
int rc;
const char *sql;
bool name_match = false;
const char* player_database_names;
char *p_name = ci->name;
char *p_ip = ci->ip;
rc = sqlite3_open("playerinfo.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
if(sql_console_msgs) fprintf(stdout, "Opened database successfully\n");
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
defformatstring(sqlstrprep)("SELECT NAME FROM PLAYERINFO");
rc = sqlite3_prepare_v2(db, sqlstrprep, -1, &stmt, NULL);
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
int id = sqlite3_column_int(stmt, SQLITE_ROW);
int columns = sqlite3_column_count(stmt);
if(sql_console_msgs) out(ECHO_CONSOLE, "-- id: %d row: %d columns: %d", id, SQLITE_ROW, columns);
player_database_names = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
}
if(player_database_names == p_name) name_match = true;
else if(player_database_names != p_name) name_match = false;
}
完整代码如下:
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;
}
bool sql_console_msgs = true;
void QServ::savestats(clientinfo *ci)
{
if(enable_sqlite_db) {
sqlite3_stmt *stmt;
sqlite3 *db;
char *zErrMsg = 0;
int rc;
const char *sql;
bool name_match = false;
const char* player_database_names;
char *p_name = ci->name;
char *p_ip = ci->ip;
rc = sqlite3_open("playerinfo.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
if(sql_console_msgs) fprintf(stdout, "Opened database successfully\n");
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
defformatstring(sqlstrprep)("SELECT NAME FROM PLAYERINFO");
//defformatstring(sqlstrprep)("SELECT group_concat(NAME) FROM PLAYERINFO");
rc = sqlite3_prepare_v2(db, sqlstrprep, -1, &stmt, NULL);
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
//sometimes returns incorrectly - keeps creating undesired new rows firstguy, secondguy, firstguy
int id = sqlite3_column_int(stmt, SQLITE_ROW);
int columns = sqlite3_column_count(stmt);
if(sql_console_msgs) out(ECHO_CONSOLE, "-- id: %d row: %d columns: %d", id, SQLITE_ROW, columns);
player_database_names = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
//if (std::to_string(player_database_names).find(p_name) != std::string::npos) name_match = true;
//else name_match = false;
if(sql_console_msgs) out(ECHO_CONSOLE, "-- player db names: %s", player_database_names);
}
//if(!strcmp(player_database_names, p_name)) name_match = true;
//else if(strcmp(player_database_names, p_name)) name_match = false;
if(player_database_names == p_name) name_match = true;
else if(player_database_names != p_name) name_match = false;
}
sql = "CREATE TABLE IF NOT EXISTS PLAYERINFO(" \
"NAME TEXT NOT NULL," \
"FRAGS INT NOT NULL," \
"DEATHS INT NOT NULL," \
"FLAGS INT NOT NULL," \
"PASSES INT NOT NULL," \
"IP TEXT NOT NULL," \
"ACCURACY DECIMAL(4, 2) NOT NULL," \
"KPD DECIMAL(4, 2) NOT NULL);";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQLITE3 ERROR @ CREATE TABLE IF NOT EXISTS: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
if(sql_console_msgs) {
if(!name_match) fprintf(stdout, "-- No previous record found under that name\n");
else fprintf(stdout, "-- Found name already, updating record instead\n");
}
}
char sqlINSERT[500];
char sqlUPDATE[1000];
int p_frags = ci->state.frags;
int p_deaths = ci->state.deaths;
int p_flags = ci->state.flags;
int p_passes = ci->state.passes;
int p_acc = (ci->state.damage*100)/max(ci->state.shotdamage, 1);
int p_kpd = (ci->state.frags)/max(ci->state.deaths, 1);
//name is different
if(!name_match) {
snprintf(sqlINSERT, 500, "INSERT INTO PLAYERINFO( NAME,FRAGS,DEATHS,FLAGS,PASSES,IP,ACCURACY,KPD ) VALUES (\"%s\", %d, %d, %d, %d, \"%s\", %d, %d)",p_name,p_frags,p_deaths,p_flags,p_passes,p_ip,p_acc,p_kpd);
//sqlEscape(sqlINSERT);
rc = sqlite3_exec(db, sqlINSERT, callback, 0, &zErrMsg);
}
//client name matches db record, update db if new info is > than db info
else if(name_match) {
snprintf(sqlUPDATE, 10000,
"UPDATE PLAYERINFO SET FRAGS = %d+(SELECT FRAGS FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET DEATHS = %d+(SELECT DEATHS FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET FLAGS = %d+(SELECT FLAGS FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET PASSES = %d+(SELECT PASSES FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET ACCURACY = %d+(SELECT ACCURACY FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET KPD = %d+(SELECT KPD FROM PLAYERINFO) WHERE NAME = \"%s\";",
ci->state.frags, ci->name, ci->state.deaths, ci->name, ci->state.flags, ci->name, ci->state.passes, ci->name, p_acc, ci->name, p_kpd, ci->name);
//sqlEscape(sqlUPDATE);
rc = sqlite3_exec(db, sqlUPDATE, callback, 0, &zErrMsg);
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQLITE3 ERROR @ INSERT & UPDATE: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
if(sql_console_msgs) fprintf(stdout, "Playerinfo modified\n");
}
sqlite3_close(db);
}
}
void QServ::getstats(clientinfo *ci)
{
if(enable_sqlite_db) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
rc = sqlite3_open("playerinfo.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
sqlite3_stmt *stmt;
defformatstring(sqlstrprep)("SELECT NAME,FRAGS,ACCURACY,KPD FROM PLAYERINFO WHERE NAME == \"%s\";", ci->name);
rc = sqlite3_prepare_v2(db, sqlstrprep, -1, &stmt, NULL);
bool necho = false;
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
const char* name = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const char* allfrags = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
const char* avgacc = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
const char* avgkpd = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
if(!necho) {
if(avgacc == NULL) out(ECHO_SERV, "Name: \f0%s\f7, Total Frags: \f3%s\f7, Average KPD: \f6%s", name, allfrags, avgkpd);
else if(avgkpd == NULL) out(ECHO_SERV, "Name: \f0%s\f7, Total Frags: \f3%s\f7, Average Accuracy: \f2%s%%", name, allfrags, avgacc);
else out(ECHO_SERV, "Name: \f0%s\f7, Total Frags: \f3%s\f7, Average Accuracy: \f2%s%%\f7, Average KPD: \f6%s", name,allfrags,avgacc,avgkpd);
necho = true;
}
}
}
sqlite3_close(db);
}
}
void QServ::getnames(clientinfo *ci) {
if(enable_sqlite_db) {
sqlite3_stmt *stmt3;
sqlite3 *db;
int rc;
rc = sqlite3_open("playerinfo.db", &db);
defformatstring(sqlstrprep3)("SELECT group_concat(NAME, \", \") FROM PLAYERINFO WHERE IP == \"%s\";", ci->ip);
rc = sqlite3_prepare_v2(db, sqlstrprep3, -1, &stmt3, NULL);
while ((rc = sqlite3_step(stmt3)) == SQLITE_ROW) {
std::string names(reinterpret_cast<const char*>(sqlite3_column_text(stmt3, 0)));
defformatstring(nmsg)("Names from IP \f2%s\f7: %s", ci->ip, names.c_str());
out(ECHO_SERV, nmsg);
}
sqlite3_close(db);
}
}
void QServ::disconnectclient(clientinfo *ci)
{
if(enable_sqlite_db) savestats(ci);
}
我总是对没有人愿意提供最小工作示例这一事实感到好笑。最后,我自己创建了一个来展示如何做这件事:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "sqlite3.h"
int main(void)
{
int rc;
sqlite3 *db;
rc = sqlite3_open("playerinfo.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(EXIT_FAILURE);
}
else {
fprintf(stdout, "Opened database successfully\n");
}
char *zErrMsg = NULL;
rc = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS PlayerInfo (id INTEGER PRIMARY KEY, name TEXT);"
"REPLACE INTO PlayerInfo(id, name) VALUES (1,'John'),(2,'Paul'),(3,'George'),(4,'Ringo'),(5,'Pete'),(6,'Stuart');",
NULL, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
exit(EXIT_FAILURE);
}
const char *search_name = "Ringo";
bool name_match = false;
sqlite3_stmt *stmt;
char *zSql = "SELECT name FROM PlayerInfo";
sqlite3_prepare_v2(db, zSql, -1, &stmt, NULL);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* player_database_names = sqlite3_column_text(stmt, 0);
if (strcmp(player_database_names, search_name) == 0) {
name_match = true;
break;
}
}
sqlite3_finalize(stmt);
printf("Search name: %s - Result: %s\n", search_name, name_match ? "true" : "false");
sqlite3_close(db);
return EXIT_SUCCESS;
}
原始代码有很多非常奇怪的东西。分明就是一堆东西无缘无故粘在一起的样子。
我以前从未使用过 SQLite,但它确实做得很好。所以想法是
- 打开数据库(
sqlite3_open()
)并检查是否成功。
- 根据需要创建并填充数据库(
sqlite3_exec()
没有回调函数)。
- 使用
sqlite3_prepare_v2()
、sqlite3_step()
和 sqlite3_finalize()
查询数据库行。
- 在循环中搜索是否找到名称。
- 关闭数据库 (
sqlite3_close()
)。
如评论中所述,这不是一个好主意。如果要查看是否存在,请查询是否存在:
sqlite3_stmt *stmt;
char *zSql = "SELECT EXISTS(SELECT 1 FROM PlayerInfo WHERE name=?)";
sqlite3_prepare_v2(db, zSql, -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, search_name, -1, SQLITE_STATIC);
sqlite3_step(stmt);
name_match = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
在这种特定情况下,参数化查询可能有点矫枉过正,但谁知道 search_name
来自哪里...
警告:没有努力进行适当的错误处理。
我正在尝试将所有列数据与 const char 进行比较,以查看列中的名称是否与连接到游戏服务器的玩家名称匹配。下面的 spaghetticode 中的比较无法正常工作,即使玩家名称已存在于 sqlite 数据库中,也会生成新行。进行这种比较的正确方法是什么?预先感谢您的帮助。
这是有问题的部分的片段:
if(enable_sqlite_db) {
sqlite3_stmt *stmt;
sqlite3 *db;
char *zErrMsg = 0;
int rc;
const char *sql;
bool name_match = false;
const char* player_database_names;
char *p_name = ci->name;
char *p_ip = ci->ip;
rc = sqlite3_open("playerinfo.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
if(sql_console_msgs) fprintf(stdout, "Opened database successfully\n");
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
defformatstring(sqlstrprep)("SELECT NAME FROM PLAYERINFO");
rc = sqlite3_prepare_v2(db, sqlstrprep, -1, &stmt, NULL);
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
int id = sqlite3_column_int(stmt, SQLITE_ROW);
int columns = sqlite3_column_count(stmt);
if(sql_console_msgs) out(ECHO_CONSOLE, "-- id: %d row: %d columns: %d", id, SQLITE_ROW, columns);
player_database_names = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
}
if(player_database_names == p_name) name_match = true;
else if(player_database_names != p_name) name_match = false;
}
完整代码如下:
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;
}
bool sql_console_msgs = true;
void QServ::savestats(clientinfo *ci)
{
if(enable_sqlite_db) {
sqlite3_stmt *stmt;
sqlite3 *db;
char *zErrMsg = 0;
int rc;
const char *sql;
bool name_match = false;
const char* player_database_names;
char *p_name = ci->name;
char *p_ip = ci->ip;
rc = sqlite3_open("playerinfo.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
if(sql_console_msgs) fprintf(stdout, "Opened database successfully\n");
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
defformatstring(sqlstrprep)("SELECT NAME FROM PLAYERINFO");
//defformatstring(sqlstrprep)("SELECT group_concat(NAME) FROM PLAYERINFO");
rc = sqlite3_prepare_v2(db, sqlstrprep, -1, &stmt, NULL);
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
//sometimes returns incorrectly - keeps creating undesired new rows firstguy, secondguy, firstguy
int id = sqlite3_column_int(stmt, SQLITE_ROW);
int columns = sqlite3_column_count(stmt);
if(sql_console_msgs) out(ECHO_CONSOLE, "-- id: %d row: %d columns: %d", id, SQLITE_ROW, columns);
player_database_names = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
//if (std::to_string(player_database_names).find(p_name) != std::string::npos) name_match = true;
//else name_match = false;
if(sql_console_msgs) out(ECHO_CONSOLE, "-- player db names: %s", player_database_names);
}
//if(!strcmp(player_database_names, p_name)) name_match = true;
//else if(strcmp(player_database_names, p_name)) name_match = false;
if(player_database_names == p_name) name_match = true;
else if(player_database_names != p_name) name_match = false;
}
sql = "CREATE TABLE IF NOT EXISTS PLAYERINFO(" \
"NAME TEXT NOT NULL," \
"FRAGS INT NOT NULL," \
"DEATHS INT NOT NULL," \
"FLAGS INT NOT NULL," \
"PASSES INT NOT NULL," \
"IP TEXT NOT NULL," \
"ACCURACY DECIMAL(4, 2) NOT NULL," \
"KPD DECIMAL(4, 2) NOT NULL);";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQLITE3 ERROR @ CREATE TABLE IF NOT EXISTS: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
if(sql_console_msgs) {
if(!name_match) fprintf(stdout, "-- No previous record found under that name\n");
else fprintf(stdout, "-- Found name already, updating record instead\n");
}
}
char sqlINSERT[500];
char sqlUPDATE[1000];
int p_frags = ci->state.frags;
int p_deaths = ci->state.deaths;
int p_flags = ci->state.flags;
int p_passes = ci->state.passes;
int p_acc = (ci->state.damage*100)/max(ci->state.shotdamage, 1);
int p_kpd = (ci->state.frags)/max(ci->state.deaths, 1);
//name is different
if(!name_match) {
snprintf(sqlINSERT, 500, "INSERT INTO PLAYERINFO( NAME,FRAGS,DEATHS,FLAGS,PASSES,IP,ACCURACY,KPD ) VALUES (\"%s\", %d, %d, %d, %d, \"%s\", %d, %d)",p_name,p_frags,p_deaths,p_flags,p_passes,p_ip,p_acc,p_kpd);
//sqlEscape(sqlINSERT);
rc = sqlite3_exec(db, sqlINSERT, callback, 0, &zErrMsg);
}
//client name matches db record, update db if new info is > than db info
else if(name_match) {
snprintf(sqlUPDATE, 10000,
"UPDATE PLAYERINFO SET FRAGS = %d+(SELECT FRAGS FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET DEATHS = %d+(SELECT DEATHS FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET FLAGS = %d+(SELECT FLAGS FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET PASSES = %d+(SELECT PASSES FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET ACCURACY = %d+(SELECT ACCURACY FROM PLAYERINFO) WHERE NAME = \"%s\";" \
"UPDATE PLAYERINFO SET KPD = %d+(SELECT KPD FROM PLAYERINFO) WHERE NAME = \"%s\";",
ci->state.frags, ci->name, ci->state.deaths, ci->name, ci->state.flags, ci->name, ci->state.passes, ci->name, p_acc, ci->name, p_kpd, ci->name);
//sqlEscape(sqlUPDATE);
rc = sqlite3_exec(db, sqlUPDATE, callback, 0, &zErrMsg);
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQLITE3 ERROR @ INSERT & UPDATE: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
if(sql_console_msgs) fprintf(stdout, "Playerinfo modified\n");
}
sqlite3_close(db);
}
}
void QServ::getstats(clientinfo *ci)
{
if(enable_sqlite_db) {
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
rc = sqlite3_open("playerinfo.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
sqlite3_stmt *stmt;
defformatstring(sqlstrprep)("SELECT NAME,FRAGS,ACCURACY,KPD FROM PLAYERINFO WHERE NAME == \"%s\";", ci->name);
rc = sqlite3_prepare_v2(db, sqlstrprep, -1, &stmt, NULL);
bool necho = false;
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
const char* name = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const char* allfrags = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
const char* avgacc = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
const char* avgkpd = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
if(!necho) {
if(avgacc == NULL) out(ECHO_SERV, "Name: \f0%s\f7, Total Frags: \f3%s\f7, Average KPD: \f6%s", name, allfrags, avgkpd);
else if(avgkpd == NULL) out(ECHO_SERV, "Name: \f0%s\f7, Total Frags: \f3%s\f7, Average Accuracy: \f2%s%%", name, allfrags, avgacc);
else out(ECHO_SERV, "Name: \f0%s\f7, Total Frags: \f3%s\f7, Average Accuracy: \f2%s%%\f7, Average KPD: \f6%s", name,allfrags,avgacc,avgkpd);
necho = true;
}
}
}
sqlite3_close(db);
}
}
void QServ::getnames(clientinfo *ci) {
if(enable_sqlite_db) {
sqlite3_stmt *stmt3;
sqlite3 *db;
int rc;
rc = sqlite3_open("playerinfo.db", &db);
defformatstring(sqlstrprep3)("SELECT group_concat(NAME, \", \") FROM PLAYERINFO WHERE IP == \"%s\";", ci->ip);
rc = sqlite3_prepare_v2(db, sqlstrprep3, -1, &stmt3, NULL);
while ((rc = sqlite3_step(stmt3)) == SQLITE_ROW) {
std::string names(reinterpret_cast<const char*>(sqlite3_column_text(stmt3, 0)));
defformatstring(nmsg)("Names from IP \f2%s\f7: %s", ci->ip, names.c_str());
out(ECHO_SERV, nmsg);
}
sqlite3_close(db);
}
}
void QServ::disconnectclient(clientinfo *ci)
{
if(enable_sqlite_db) savestats(ci);
}
我总是对没有人愿意提供最小工作示例这一事实感到好笑。最后,我自己创建了一个来展示如何做这件事:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "sqlite3.h"
int main(void)
{
int rc;
sqlite3 *db;
rc = sqlite3_open("playerinfo.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(EXIT_FAILURE);
}
else {
fprintf(stdout, "Opened database successfully\n");
}
char *zErrMsg = NULL;
rc = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS PlayerInfo (id INTEGER PRIMARY KEY, name TEXT);"
"REPLACE INTO PlayerInfo(id, name) VALUES (1,'John'),(2,'Paul'),(3,'George'),(4,'Ringo'),(5,'Pete'),(6,'Stuart');",
NULL, 0, &zErrMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL Database Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
exit(EXIT_FAILURE);
}
const char *search_name = "Ringo";
bool name_match = false;
sqlite3_stmt *stmt;
char *zSql = "SELECT name FROM PlayerInfo";
sqlite3_prepare_v2(db, zSql, -1, &stmt, NULL);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* player_database_names = sqlite3_column_text(stmt, 0);
if (strcmp(player_database_names, search_name) == 0) {
name_match = true;
break;
}
}
sqlite3_finalize(stmt);
printf("Search name: %s - Result: %s\n", search_name, name_match ? "true" : "false");
sqlite3_close(db);
return EXIT_SUCCESS;
}
原始代码有很多非常奇怪的东西。分明就是一堆东西无缘无故粘在一起的样子。
我以前从未使用过 SQLite,但它确实做得很好。所以想法是
- 打开数据库(
sqlite3_open()
)并检查是否成功。 - 根据需要创建并填充数据库(
sqlite3_exec()
没有回调函数)。 - 使用
sqlite3_prepare_v2()
、sqlite3_step()
和sqlite3_finalize()
查询数据库行。 - 在循环中搜索是否找到名称。
- 关闭数据库 (
sqlite3_close()
)。
如评论中所述,这不是一个好主意。如果要查看是否存在,请查询是否存在:
sqlite3_stmt *stmt;
char *zSql = "SELECT EXISTS(SELECT 1 FROM PlayerInfo WHERE name=?)";
sqlite3_prepare_v2(db, zSql, -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, search_name, -1, SQLITE_STATIC);
sqlite3_step(stmt);
name_match = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
在这种特定情况下,参数化查询可能有点矫枉过正,但谁知道 search_name
来自哪里...
警告:没有努力进行适当的错误处理。