現在SQL參數化是一個熱門話題,而且對於a good reason,但它是否真正做了除了正常逃脫之外的任何事情?SQL參數化:這是如何在幕後工作的?
我能想象一個參數引擎只要確保數據將其插入到查詢字符串之前體面逃過一劫,但事實是否真的它所做的一切?在連接中做不同的事情會更有意義,例如,像這樣:
> Sent data. Formatting: length + space + payload
< Received data
-----
> 69 SELECT * FROM `users` WHERE `username` LIKE ? AND `creation_date` > ?
< Ok. Send parameter 1.
> 4 joe%
< Ok. Send parameter 2.
> 1 0
< Ok. Query result: [...]
這樣只會消除SQL注入的問題,所以你不會有避免他們通過逃逸。我能想到的參數是如何發揮作用的唯一辦法了,是逃避參數:
// $params would usually be an argument, not in the code like this
$params = ['joe%', 0];
// Escape the values
foreach ($params as $key=>$value)
$params[$key] = mysql_real_escape_string($value);
// Foreach questionmark in the $query_string (another argument of the function),
// replace it with the escaped value.
$n = 0;
while ($pos = strpos($query_string, "?") !== false && $n < count($params)) {
// If it's numeric, don't use quotes around it.
$param = is_numeric($params[$n]) ? $params[$n] : "'" . $params[$n] . "'";
// Update the query string with the replaced question mark
$query_string = substr($query_string, 0, $pos) //or $pos-1? It's pseudocode...
. $param
. substr($query_string, $pos + 1);
$n++;
如果是後者的話,我不會切換我的網站的參數,只是還沒有。它沒有任何優勢,我可以看到,這只是另一個強大的與弱的變量分類討論。強大的輸入可能會在編譯時遇到更多錯誤,但它並沒有真正做出任何可能,否則很難做到這一點 - 與此參數化相同。 (請糾正我,如果我錯了!)
更新:
- 我知道這將取決於SQL服務器上(以及客戶端上,但我相信客戶端使用的最佳可能的技術),但大多數情況下我都考慮過MySQL。儘管如此,關於其他數據庫的答案也是受歡迎的。
- 就我所理解的答案而言,參數化確實不僅僅是簡單地轉義數據。它實際上是以參數化的方式發送到服務器的,所以變量是分開的,而不是作爲單個查詢字符串。
- 這也使服務器能夠存儲和重複使用不同參數的查詢,從而提供更好的性能。
難道我得到的一切?有一件事我仍然很好奇,是MySQL是否具有這些功能,以及查詢重用是否自動完成(或者如果不是,那麼可以如何完成)。
此外,請有人閱讀此更新時發表評論。我不知道它是否碰到了問題或其他...
謝謝!
+1優秀的論點 - 也指出了巨大的性能優勢(至少在SQL Server環境中)。 – 2012-08-11 21:13:02
感謝您提供更新,希望再次upvote ...如果沒有其他帖子/更新,今晚可能會接受這個答案。 – Luc 2012-08-13 14:36:42