2010-01-05 141 views
8

我也有類似的用Perl如下所示的SQL語句:如何在SQL準備語句中轉義單引號和雙引號?

my $sql="abc..TableName '$a','$b' "; 

的$一個是它可以包含任何東西,包括單引號,雙引號,後臺和前臺斜線字符等自由文本

這些字符如何轉義以使SQL語句有效?

謝謝。

+3

'$ a'和'$ b'具有與'sort'功能相關的特殊含義。使用它們通常不是一個好主意。除了代碼示例中的簡短變量名稱。 – daotoad 2010-01-05 03:27:16

+0

除了[perl]標籤,[停止SQL注入PHP的最佳方法] dup(http://stackoverflow.com/q/60174/90527)。唯一的實際區別在於代碼示例。另外,dup [避免SQL注入攻擊的最佳方法是什麼?](http://stackoverflow.com/q/1973/)。 – outis 2012-04-27 22:36:31

回答

21

您可以使用->quote方法(假設你使用DBI):

my $oldValue = $dbh->quote('oldValue'); 
my $newValue = $dbh->quote('newValue'); 
$dbh->do("UPDATE myTable SET myValue=$newValue where myValue=$oldValue"); 

更妙的是,最好的做法是使用綁定值:

my $sth = $dbh->prepare('UPDATE myTable SET myValue=? WHERE myValue=?'); 

$sth->execute('newValue','oldValue'); 

這也應該工作對於存儲過程調用,假設語句一旦擴展字符串就是有效的SQL。這可能是驅動程序/數據庫特定的,所以YMMV。

my $sth = $dbh->prepare("DBName..ProcName ?,? "); 
$sth->execute($a, $b); 
+0

我很抱歉不清楚。我正在調用存儲過程。這個例子應該如下所示:my $ sql =「DBName..ProcName'$ a','$ b'」; – Sam 2010-01-05 01:39:36

+5

使用綁定參數仍然適用於存儲過程調用。 – mopoke 2010-01-05 01:40:25

+0

如果不是很明顯,如果您一直使用綁定參數,並且在執行插入操作之前已經手動轉義了您的值的單引號,那麼列值將以每個單引號的兩個連續單引號結尾。 – RTF 2015-09-21 13:29:27

9

使用準備好的語句。用?替換變量。從DBI手冊頁中挑選一個示例:

$sql = 'SELECT * FROM people WHERE lastname = ?'; 
$sth = $dbh->prepare($sql); 
$sth->execute($user_input_here); 

將用戶輸入內插到您的SQL中需要安全漏洞。

+0

我很抱歉不清楚。我正在調用存儲過程。這個例子應該是這樣的: my $ sql =「DBName..ProcName'$ a','$ b'」; – Sam 2010-01-05 01:38:19

6

如果使用查詢參數佔位符,則不必轉義字符串的內容。

my $sql="DBName..ProcName ?, ?"; 
$sth = $dbh->prepare($sql); 
$sth->execute($a, $b); 

如果DBI使用真正的查詢參數,它將參數值分別從SQL語句發送到RDBMS。這些值永遠不會與SQL語句字符串結合使用,因此這些值從來沒有機會導致SQL注入。

如果DBI通過將變量插入查詢字符串來「模擬」預備語句,那麼DBI應該處理正確的轉義邏輯,因此您不必這樣做。讓專家(編寫和測試DBI的人)擔心如何去做。

3

如果你不想使用 - >報價(出於某種原因,該功能不會對我的版本DBI的運行),那麼試試這個:

$query=~s/\"/\\\"/g; 

我傾向於做同樣的單引號和逗號也只是爲了安全起見。

似乎爲我工作得很好......!