2009-12-23 62 views
0

我想將一個mySQL查詢存儲在一個文件中。我計劃不得不用我的程序中的變量來替換它的一部分。更簡單的方法來從文件中評估字符串?

我在紅寶石中使用了'eval'方法,它起作用,但感覺有點笨拙。

使用irb我做了以下。

>> val = 7 
=> 7 
>> myQuery = "select * from t where t.val = \#{val}" #escaped hash simulates reading it from file 
=> "select * from t where t.val = \#{val}" 
>> myQuery = eval "\"#{myQuery}\"" 
=> "select * from t where t.val = 7" 

正如你可以看到它的工作原理!但爲了使它工作,我不得不將'myQuery'變量包裝在轉義引號中,整個事情看起來有點混亂。

有沒有更簡單的方法?

回答

1

一般情況下,你不應該使用字符串插值來建立SQL查詢。這樣做會使您打開SQL injection攻擊,其中有人提供具有結束引號字符的輸入,然後是另一個查詢。舉例來說,使用例如:

>> val = '7; DROP TABLE users;' 
=> "7; DROP TABLE users;" 
>> myQuery = "select * from t where t.val = \#{val}" 
=> "select * from t where t.val = \#{val}" 
>> eval "\"#{myQuery}\"" 
=> "select * from t where t.val = 7; DROP TABLE users;" 

即使沒有惡意輸入,你可以簡單地執行意外,你是不打算代碼,舉例來說如果有人列入其輸入引號。

除非絕對必要,避免使用eval也是一個好主意;它使得如果你的程序中有一個bug,有人可以通過將它傳遞給eval來執行任意代碼,並且由於你的一些源代碼將從常規源代碼樹以外的地方加載,所以它使得代碼不易維護。

那麼,你是如何做到這一點呢?數據庫API通常包括一個prepare命令,該命令可以準備執行一條SQL語句。在該語句中,您可以包含?字符,它們表示可以在該語句中替換的參數。然後,您可以在語句上調用execute,爲這些參數傳入值,並且它們將被安全地執行,無法讓某人執行任意一段SQL。

下面是它在你的例子中的工作原理。這假設你正在使用this MySQL/Ruby module;如果您使用的是不同的界面,它可能會有類似的界面,儘管它可能不完全相同。

>> val = 7 
>> db = Mysql.new(hostname, username, password, databasename) 
>> query = db.prepare("select * from t where t.val = ?") 
>> query.execute(val) 
0

您可以改用ERB模板 - 從文件中讀取它們並插入變量(將<%= something%>標記轉換爲實際值)。

Here's the official doc,這是相當完整和直接。

0

如果你的程序事先要使用的變量都知道可以用printf像語法的字符串替換

"123 %s 456" % 23 # => "123 23 456" 

這隻作品。

相關問題