更简单的方法来从文件中评估字符串?

更简单的方法来从文件中评估字符串?

问题描述:

我想将一个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'变量包装在转义引号中,整个事情看起来有点混乱。

有没有更简单的方法?

一般情况下,你不应该使用字符串插值来建立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) 

您可以改用ERB模板 - 从文件中读取它们并插入变量(将<%= something%>标记转换为实际值)。

Here's the official doc,这是相当完整和直接。

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

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

这只作品。

你可以使用参数化查询吗?

我不知道如何在ruby中这样做,但基本上它涉及用SQL识别的命令用除了语句之外发送的参数替换的SQL语句标记。

此链接可能帮助:http://sqlite-ruby.rubyforge.org/sqlite3/faq.html#538670816