0

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

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

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 要求标识符用双引号括起来)。

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

4

1 回答 1

3

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

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

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

于 2013-07-03T16:15:57.353 回答