参数绑定和IN运算符

时间:2014-12-02 07:51:32

标签: sql ruby sqlite parameterbinding

我相信它不可能,但以防万一:

如何绑定IN运算符的右(列)参数?

SELECT foo FROM bar WHERE baz IN ('cow', 'chicken');

遗憾的是,这不起作用:

list = ['cow', 'chicken']
db.execute('SELECT foo FROM bar WHERE baz IN ?', list) 

参数绑定不仅比值的直接插值更漂亮,而且更安全:使用它的一个主要原因是阻止臭名昭着的Bobby Tables。但是,您是否因为IN参数的手动转义而陷入困境?

list = ['cow', 'chicken']
sqllist = list.map { |el| "'#{SQLite3::Database.quote(el)}'" }.join(',')
db.execute('SELECT foo FROM bar WHERE baz IN (#{sqllist})')

(示例是带有sqlite3 gem的Ruby,但问题实际上适用于为您执行参数绑定的所有语言/库。)

1 个答案:

答案 0 :(得分:3)

传递给db.execute的SQL只是一个字符串,占位符的数量只需要与您提供的值的数量相匹配。因此,您可以基于list.length构建占位符,并使用字符串插值将其删除:

placeholders = Array.new(list.length, '?').join(',')
db.execute("SELECT foo FROM bar WHERE baz IN (#{placeholders})", list)

这非常安全,因为您确切知道进入placeholders的内容。