【问题标题】:How to safely pass parameters to ActiveRecord#select() when using PostgreSQL使用 PostgreSQL 时如何安全地将参数传递给 ActiveRecord#select()
【发布时间】:2013-07-03 16:02:03
【问题描述】:

我有一个方法,它接受一个列名并在我的模型上定义一个范围。该范围利用 PostgreSQL 窗口函数(如 rank() 和 row_number()),向结果数据集添加一个附加列。例如,User.ranked_on_score 应该添加一个别名为 score_rankingrank() 列。

目前,我通过简单的字符串插值(伪代码)实现了它:

window_alias = "#{attr}_rankings"
result_alias = "#{attr}_ranking"

select("users.*, #{window_alias}.#{result_alias}")
.join("JOIN (SELECT id, rank() OVER (ORDER BY #{attr} ASC) as #{result_alias} ...")

考虑到范围应该预先定义为宏并且不接受用户输入,这种方法应该是安全的;不过,我不喜欢它。

我知道sanitize_sql 方法,但它不适用于我的情况。它将参数用单引号括起来,这在 WHERE 子句中很好,但如果在 SELECT 子句中使用会引发语法错误(PG 要求标识符用双引号括起来)。

是否有任何内置的标识符清理方法?还是我应该就这样离开它?

【问题讨论】:

    标签: ruby-on-rails postgresql


    【解决方案1】:

    你试过quote_column_name吗?由于某种原因它没有记录,但应该做你需要的。

    window_alias = quote_column_name("#{attr}_rankings")
    result_alias = quote_column_name("#{attr}_ranking")
    

    在底层,它相当于在使用 PostgreSQL 时调用PGconn.quote_ident

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 2021-10-15
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多