簡體   English   中英

sqlite日志查詢產生錯誤

[英]sqlite log queries that produce errors

我正在用C編寫一個使用sqlite3的應用程序。 我想將所有查詢和錯誤被動地記錄到stderr進行調試。

說我有這個代碼(省略錯誤處理):

void main(void)
{
    sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
    sqlite3 *db = NULL;
    sqlite3_open_v2("main.db3", &db, SQLITE_OPEN_READWRITE, NULL);
    sqlite3_trace_v2(db, SQLITE_TRACE_STMT, tracer, NULL);

    // this code cannot change
    sqlite3_exec(db, "SELECT * FROM users", NULL, NULL, NULL);
    sqlite3_exec(db, "SELECT * FROM users_nonexistant", NULL, NULL, NULL);
}

static void errorLogCallback(void *, int iErrCode, const char *zMsg)
{
    fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
}

static int tracer(unsigned, void*, void *p, void*)
{
    sqlite3_stmt *stmt = (sqlite3_stmt*)p;
    char *sql = sqlite3_expanded_sql(stmt);
    fprintf(stderr, "%s\n", sql);
    sqlite3_free(sql);
    return 0;
}

輸出:

SELECT * FROM users
(1) no such table: users_nonexistant

我怎樣才能輸出呢?

SELECT * FROM users
SELECT * FROM users_nonexisant
(1) no such table: users_nonexistant

閱讀sqlite3_config的文檔可以看到有關配置選項的頁面

SQLITE_CONFIG_LOG

SQLITE_CONFIG_LOG選項用於配置SQLite全局錯誤日志。 (SQLITE_CONFIG_LOG選項有兩個參數:一個指向函數的指針,調用簽名為void( )(void ,int,const char *),指向void的指針。如果函數指針不為NULL,則由sqlite3_log調用()處理每個日志記錄事件。如果函數指針為NULL,則sqlite3_log()接口變為無操作。 作為SQLITE_CONFIG_LOG的第二個參數的void指針作為第一個參數傳遞給應用程序定義的記錄器函數無論何時調用該函數 。記錄器函數的第二個參數是相應sqlite3_log()調用的第一個參數的副本,用於結果代碼或擴展結果代碼。傳遞給記錄器的第三個參數是log通過sqlite3_snprintf()格式化后的消息.SQLite日志記錄界面不可重入;應用程序提供的記錄器函數不能調用任何SQLite接口。在多線程應用程序中,應用程序定義的記錄器函數 n必須是線程安全的。

這意味着你可以傳遞一個char** pStatement ,它將指向要執行的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_exec調用,則必須更改SQLite的源代碼並在其中添加日志調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM