2011-05-03 150 views
9

我有一些奇怪的感覺,我想向你揭示sqlite3 參數我可以在sqlite3中使用表名參數嗎?

這是我的查詢和故障消息:

#query 
'SELECT id FROM ? WHERE key = ? AND (userid = '0' OR userid = ?) ORDER BY userid DESC LIMIT 1;' 
#error message, fails when calling sqlite3_prepare() 
error: 'near "?": syntax error' 

在我的代碼,它看起來像:

// Query is a helper class, at creation it does an sqlite3_preprare() 
Query q("SELECT id FROM ? WHERE key = ? AND (userid = 0 OR userid = ?) ORDER BY userid DESC LIMIT 1;"); 
// bind arguments 
q.bindString(1, _db_name.c_str()); // class member, the table name 
q.bindString(2, key.c_str()); // function argument (std::string) 
q.bindInt (3, currentID); // function argument (int) 
q.execute(); 

我有,我不能對使用SQLite 參數的感覺表名稱,但我無法在Sqlite3 C API中找到確認。

你知道我的查詢有什麼問題嗎?
我是否必須預先處理我的SQL語句以在之前包括表名準備查詢?

+0

不,你不能用SQLite或其他大多數SQL產品來做到這一點。參數綁定用於綁定參數,而不是替換您喜歡的任何舊查詢位。 – 2011-05-03 13:37:57

+0

嗯,這就是我所懷疑的,但是SQLite API沒有告訴它,你知道我可以在哪裏得到*確認嗎?另外,我不同意參數不能是SQL語句的*變量*之一。 'INSERT','UPDATE','WHERE'是靜態的,來自SQL語言的固定詞法分析器,但表名不是,恕我直言。 – Gui13 2011-05-03 13:40:54

+0

這裏http://www.sqlite.org/c3ref/bind_blob.htm,例如「文字可能被參數替換」。 SQL語法中的文字就像字符串和數字一樣。表名不是文字。 – 2011-05-03 13:44:31

回答

8

Ooookay,應該在SO上看得更徹底。

答案:
- SQLite Parameters - Not allowing tablename as parameter
- Variable table name in sqlite

一切都是針對Python,但我想這同樣適用於C++。

TL;博士

您無法通過表名作爲參數。
如果任何人有SQLite文檔中的鏈接,我已經確認了這一點,我會很樂意接受答案。

+0

sqlite文檔可以在這裏找到:https://www.sqlite.org/cintro.html在第6章。綁定參數和重複使用準備好的語句中,它說'參數不能用於列名或表名。' – 2017-06-09 14:37:39

3

我知道這是超級老了,不過既然你的查詢只是一個字符串,你可以隨時用C追加表名這樣++:

std::string queryString = "SELECT id FROM " + std::string(_db_name); 

或在Objective-C:

[@"SELECT id FROM " stringByAppendingString:_db_name]; 
+0

這是正確的,但它是用於一個嵌入式系統,我不得不限制內存碎片。這樣做會在一行中分配4個字符串,這不會很有效。我通過將DB佈局更改爲更適合的方式解決了問題。 – Gui13 2013-04-25 18:55:58

+0

@ Gui13實際上,如果編譯器沒有優化,那麼這樣的一行代碼最多可以分配2個塊:一個用於存儲'_db_name',另一個用於存儲整個查詢,前面加上'「SELECT ...」 'operator +(const char *,std :: string &&)',或者暫時沒有足夠的額外空間。在將字符附加到另一個字符串之前,不需要將字符'char *'轉換爲字符串,並且在複製初始化時不再需要複製。此外,大多數編譯器使用(或者可以選擇使用)小字符串優化,這在大多數情況下意味着沒有分配。 – bcrist 2014-03-03 00:09:18

+1

更重要的是,附加字符串會將您的代碼暴露給sql注入,如果'_db_name'的值是'「table;從表中刪除;」'我們不能使用表名參數是一種遺憾,但我們必須至少清理該值或驗證這個表是否首先存在。 – ateijelo 2016-06-22 19:53:59

相關問題