如何在 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 驱动程序语法的东西。sqlInterpolate
与tbl
一起使用:sqlQuery <- 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 中分配的任何内容都可以在 filter
或 mutate
中引用。
【讨论】:
以上是关于如何在 dplyr 中使用参数化 SQL?的主要内容,如果未能解决你的问题,请参考以下文章
在带有 PDO 的 PHP 中,如何检查最终的 SQL 参数化查询? [复制]