C 产生错误的sqlite日志查询
我正在用C编写一个使用sqlite3的应用程序。我希望所有的查询和错误都被被动地记录到stderr进行调试 假设我有此代码(省略错误处理): 输出:C 产生错误的sqlite日志查询,c,sqlite,C,Sqlite,我正在用C编写一个使用sqlite3的应用程序。我希望所有的查询和错误都被被动地记录到stderr进行调试 假设我有此代码(省略错误处理): 输出: SELECT * FROM users (1) no such table: users_nonexistant 我怎样才能让它输出这个 SELECT * FROM users SELECT * FROM users_nonexisant (1) no such table: users_nonexistant 阅读相关文档以了解导致此问题的原
SELECT * FROM users
(1) no such table: users_nonexistant
我怎样才能让它输出这个
SELECT * FROM users
SELECT * FROM users_nonexisant
(1) no such table: users_nonexistant
阅读相关文档以了解导致此问题的原因 SQLITE_配置_日志 SQLITE_CONFIG_LOG选项用于配置SQLITE全局错误日志。(SQLITE_CONFIG_LOG选项有两个参数:一个指向调用签名为void()(void,int,const char*)的函数的指针,另一个指向void的指针。如果函数指针不为NULL,则sqlite3_LOG()将调用它来处理每个日志事件。如果函数指针为NULL,则sqlite3_LOG()将接口变为no-op。无论何时调用SQLITE_CONFIG_LOG函数,作为SQLITE_CONFIG_LOG第二个参数的void指针将作为第一个参数传递给应用程序定义的记录器函数。记录器函数的第二个参数是第一个参数到相应sqlite3_LOG()的副本调用并指定为结果代码或扩展结果代码。传递给记录器的第三个参数是通过sqlite3_snprintf()格式化后的日志消息。SQLite日志记录接口不可重入;应用程序提供的记录器函数不得调用任何SQLite接口。在多线程应用程序中,应用程序定义的记录器函数必须是线程安全的 这意味着您可以传递一个指向要执行的
char*
sql语句的
//...
int main(void)
{
char** pStatement=NULL;
sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, pStatement);
sqlite3 *db = NULL;
sqlite3_open_v2("main.db3", &db, SQLITE_OPEN_READWRITE, NULL);
sqlite3_trace_v2(db, SQLITE_TRACE_STMT, tracer, NULL);
const char *statement="SELECT * FROM users";
pStatement=(char**)&statement;
sqlite3_exec(db,statement , NULL, NULL, NULL);
const char *faultyStatement="SELECT * FROM users_nonexistant";
pStatement=(char**)&faultyStatement;
sqlite3_exec(db, faultyStatement, NULL, NULL, NULL);
}
static void errorLogCallback(void * pStatement, int iErrCode, const char *zMsg
{
fprintf(stderr, "%s\n(%d) %s\n",*(char**)pStatement, iErrCode, zMsg);
}
//...
免责声明:我还没有测试代码!仅对实际运行的语句调用语句跟踪程序 在编译SQL语句之前,没有内置的机制来记录它们。
如果您不能修改
sqlite3\u exec
调用,您必须更改SQLite的源代码并在那里添加日志调用。谢谢您的回答。这肯定会打印出正确的信息,但我不想为每个sqlite3\u exec
语句编写额外的代码。我添加了一条注释,//此代码无法更改代码>使这一点更加明显。sqlite3_exec
本身已经是prepare
、step
和finalize
的包装器,您可以编写一个包装器函数,还可以为当前语句设置指针是的,是的,我知道我可以为所有sqlite3调用编写一个包装器。但这是我无法做到的准确地更改所有100多个呼叫站点,并发送一封公司范围内的电子邮件,告诉所有人使用我的新API。我感谢您的帮助,但听起来我想要的是不可能的。感谢您提供的信息。我怀疑是这样的,但我希望不是这样。修补源代码是一种选择,但可能不值得,从维护角度来看。我将继续生活我所拥有的。
//...
int main(void)
{
char** pStatement=NULL;
sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, pStatement);
sqlite3 *db = NULL;
sqlite3_open_v2("main.db3", &db, SQLITE_OPEN_READWRITE, NULL);
sqlite3_trace_v2(db, SQLITE_TRACE_STMT, tracer, NULL);
const char *statement="SELECT * FROM users";
pStatement=(char**)&statement;
sqlite3_exec(db,statement , NULL, NULL, NULL);
const char *faultyStatement="SELECT * FROM users_nonexistant";
pStatement=(char**)&faultyStatement;
sqlite3_exec(db, faultyStatement, NULL, NULL, NULL);
}
static void errorLogCallback(void * pStatement, int iErrCode, const char *zMsg
{
fprintf(stderr, "%s\n(%d) %s\n",*(char**)pStatement, iErrCode, zMsg);
}
//...