更简单的方法来从文件中评估字符串?
我想将一个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)
如果你的程序事先要使用的变量都知道可以用printf像语法的字符串替换
"123 %s 456" % 23 # => "123 23 456"
这只作品。
你可以使用参数化查询吗?
我不知道如何在ruby中这样做,但基本上它涉及用SQL识别的命令用除了语句之外发送的参数替换的SQL语句标记。
此链接可能帮助:http://sqlite-ruby.rubyforge.org/sqlite3/faq.html#538670816