如何在 dplyr 中使用参数化 SQL?

Posted

技术标签:

【中文标题】如何在 dplyr 中使用参数化 SQL?【英文标题】:How to use parameterized SQL with dplyr? 【发布时间】:2018-01-29 22:51:27 【问题描述】:

我正在尝试在 SQL Server 上使用 dplyr 执行 SQL 查询:

tbl(con, sql(sqlQuery))

查询是使用sprintf("SELECT ... WHERE a = '%s') 动态生成的。这是一种不好的做法,因为它可能被滥用于 SQL 注入,但我在 dplyr 中找不到任何文档或参数化查询的工作示例。能做到吗,怎么做?

连接 (con) 正在使用 DBI、odbc 库和 SQL Server Native Client 11.0 ODBC 驱动程序:

con <- DBI::dbConnect(odbc::odbc(),
                      Driver = "SQL Server Native Client 11.0",

【问题讨论】:

有一些文档here。 我认为这不适用于 tbl 函数。在列出的选项中,似乎只有 dbGetQuery 可以与 tbl 一起使用,但 dbGetQuery 不支持参数。 (tbl 不适用于一系列函数调用,例如 dbSendQuery/dbBind/dbFetch/dbClearResults)。 sqlInterpolate 可能有效,但我希望使用底层 SQL 驱动程序语法的东西。 sqlInterpolatetbl 一起使用:sqlQuery &lt;- sqlInterpolate(con, "select count(*) from mytable where var = ?value", value = 10) ; tbl(con, sql(sqlQuery))。我不确定我是否理解您的期望,您能否提供更多详细信息? 我正在寻找使用底层驱动程序的参数语法的东西,例如 SQL Server 的“@ParameterName”,以方便重用现有查询。但是我用 sqlInterpolate 测试了你的例子,如果它是唯一的选择,它可以工作,谢谢 现在我明白了,但我不知道有什么好的解决方案。您可以在查询周围添加gsub("@", "?", .),但这不是很干净。 【参考方案1】:

根据您需要参数的用途,根据您的示例,它看起来可能是 WHERE 语句,您可以在 R 中定义参数,然后将其用于您的 dplyr 动词。

my_param <- "FILTER_VALUE" #create param
my_table <- tbl(con, "TABLE_NAME") #create ref tibble
my_table <- my_table %>% filter( a == my_param ) # filter by param
my_table <- my_table %>% collect() # execute query

您在 R 中分配的任何内容都可以在 filtermutate 中引用。

【讨论】:

以上是关于如何在 dplyr 中使用参数化 SQL?的主要内容,如果未能解决你的问题,请参考以下文章

参数化查询如何帮助防止 SQL 注入?

参数化查询如何帮助防止 SQL 注入?

在带有 PDO 的 PHP 中,如何检查最终的 SQL 参数化查询? [复制]

在带有 PDO 的 PHP 中,如何检查最终的 SQL 参数化查询? [复制]

SQL 查询参数化如何工作?

AWS Athena - 如何参数化 SQL 查询