2014-08-29 95 views
0

我正在使用SQLite的C API,修改數據庫的唯一方法似乎是將SQL語句作爲字符串。例如,文檔顯示它只是通過exec函數調用傳遞一個命令行字符串到發動機的代碼示例:以編程方式修改SQLite數據庫而不使用SQL

rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg); 

我不想成爲構建字符串並將它們傳遞給一個解釋,而不是最起碼是因爲安全問題,也是因爲我不想圍繞拼湊的字符串和轉義序列在一起。

是否有SQLite函數允許我直接操作數據庫而不用創建SQL字符串?

+1

你總是要創建一個字符串來描述操作,但您可以使用「編譯」語句(當正確使用時)消除任何「SQL注入」的可能性並且便於指定可變參數。 – 2014-08-29 02:26:47

+0

好吧,*不要*「圍繞拼湊字符串和轉義序列在一起」 - 這是佔位符/準備語句的用途。問題解決了。 – user2864740 2014-08-29 02:27:27

+0

有*可能*是一種創建/調用SQLite使用的內部「程序/ DSL」的方法,但僅用於研究/學習/趣味目的,*不*用於避免此「問題」;描述這些操作是不實際的。使用DSL /樹到SQL(帶佔位符/綁定)庫/轉換可能更實際一些。我不確定C是什麼,但是其他語言中有很多例子,並且我創建了類似的高級SQL生成器。 – user2864740 2014-08-29 02:31:26

回答

0

SQLite專門設計爲SQL數據庫,這意味着您使用SQL作爲語言與數據庫進行交互,並讓數據庫關心任何內部結構,優化等。SQL被定義爲獨立於下層而不是作爲實現的API。

但也許你的需求根本不需要SQL數據庫。在這種情況下,有幾個簡單的數據庫(如BerkeleyDB)只存儲一個值到一個鍵,並且有幾種編程語言的API。

1

sqlite_exec僅支持單個SQL字符串。 如果你真的想使用它,你可以安全地拼湊字符串和轉義序列sqlite3_mprintf

爲了避免周圍補鞋串胡鬧和轉義序列一起,用準備好的語句和參數綁定:

sqlite3_stmt *stmt; 
const char *sql = "UPDATE MyTable SET Name = ? WHERE ID = ?"; 
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); 
if (rc == SQLITE_OK) { 
    sqlite3_bind_text(stmt, 1, "Tyler Durden", -1, SQLITE_TRANSIENT); 
    sqlite3_bind_int (stmt, 2, 1655700); 
    rc = sqlite3_step(stmt); 
    if (rc != SQLITE_DONE) 
     ; // error 
    sqlite3_finalize(stmt); 
} 
相關問題