2013-11-27 40 views
1

我真的很感謝你對我最後一個問題的幫助。這是相關的,但我不想隱藏這個問題在其他..我有一個問題,使用「DATE_ADD(NOW(),INTERVAL $ interval)」在佔位符內。在我使用佔位符之前,這條線工作得很好,而不是空白。mysql placeholder not for DATE_ADD(perl)

$store = qq(INSERT INTO main (creator_name,relationship,time) VALUES(?,?,?)); 

    my $sth = $dbh->prepare($store); 
    $sth->execute($data{creatorname},$data{relationship}, "DATE_ADD(NOW(), INTERVAL $interval)"); 

是否有另一種方法添加DATE_NOW,因此它是synatically正確的?我試圖重新添加回來像

 $store = qq(INSERT INTO main (creator_name,relationship,time) VALUES(?,?, DATE_ADD(NOW(), INTERVAL $interval))); 

它錯誤地說,語法是錯誤的。至少在執行頂部的代碼時,只會將值留空。有了這個嘗試,它甚至不會嘗試。

+0

什麼是$間隔? – woolstar

+0

很難在不知道更多關於設置的情況下測試修補程序,但乍看之下,它看起來像是混合了SQL語法和佔位符值。象'DATE_ADD'或'NOW'這樣的標記是SQL表達式,而不是變量。每個'''佔位符都是一個標量變量的替代品。例如,'DATE_ADD(NOW(),INTERVAL $ interval)'可以變成'DATE_ADD(NOW(),INTERVAL?)',''interval'傳遞給'execute'。過去,我在MySQL日期函數上很生疏,但是你需要[在那個時間間隔上指定單位](http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions的.html#function_date添加)? – rutter

+1

@rutter,'DATE_ADD(NOW(),INTERVAL?)'不會工作,因爲語法是'DATE_ADD(NOW(),INTERVAL {expr} {unit})''。你可以做'DATE_ADD(NOW(),INTERVAL?WEEK)'而不是'DATE_ADD(NOW(),INTERVAL?)'或'DATE_ADD(NOW(),INTERVAL??)' – ikegami

回答

0

您期待以下列印ABC

$x = 'uc "abc"'; 
print $x; 

不,這沒有任何意義。 SQL中同樣的東西。

字符串DATE_ADD(NOW(), INTERVAL ...)肯定不是time字段的有效值。


它出錯了說的語法是錯誤的。

我很確定這個消息比那個更具體。您也沒有提供$interval的值,沒有它我們無法知道導致語法錯誤的原因。

+0

錯誤是「你有錯誤在你的SQL語法中;檢查對應於你的MySQL服務器版本的手冊,選擇在''附近使用的正確語法。變量$ interval包含「1 WEEK」或「1 MONTH」形式的內容。 –

+0

這不會是一個語法錯誤,但我明天會檢查是否有權訪問MySQL。同時,爲我們獲取實際的錯誤信息。 – ikegami

0

改變你的QQ(),以QQ {}爲清楚起見,這應該是修復:

$store = qq{ 
    INSERT INTO main (creator_name,relationship,time) 
    VALUES(?, ?, DATE_ADD(NOW(), INTERVAL ? SECOND)) 
}; 

my $sth = $dbh->prepare($store); 
$sth->execute($data{creatorname},$data{relationship},$interval); 

你需要更改單詞「第二」到合適的單位,$間隔需求是一個整數。

使用準備好的語句的榮譽,但爲什麼這不起作用的方式,你嘗試它是非常重要的:佔位符?不是簡單的地方,任何文本將被替換到您的查詢。這就是爲什麼我們對使用預準備語句作爲防止SQL注入的一種方法的重要性做出如此重大的決定。佔位符是「什麼是查詢」和「數據是什麼」之間的一個硬性劃分,它們分開發送到服務器,而不是一起消耗。

因此...

my $sth = $dbh->prepare(qq{SELECT * FROM user WHERE username = ? AND password = ?}); 
$sth->execute("hacker", "' OR 1 = 1; --"); 

...不能被曲解成爲可怕的......

SELECT * FROM user WHERE username = 'hacker' AND password = '' OR 1 = 1; --' 

...在一份聲明中完成時,它會如果您用原始字符串連接構造你的查詢,因爲服務器永遠不會在兩者之間產生混淆。

佔位符恰好替換一個標量字面值,其中「DATE_ADD(NOW(),INTERVAL $ interval)」不是。 (是的,這是Perl中的標量字符串,但它包含表達式,而不是字面值)。