如何将 R 会话中的值替换为 SQL 绑定变量占位符?

Posted

技术标签:

【中文标题】如何将 R 会话中的值替换为 SQL 绑定变量占位符?【英文标题】:How do I substitute values from the R session into SQL bind variable placeholders? 【发布时间】:2019-08-23 16:40:49 【问题描述】:

我想在 R 脚本中重用原始 SQL。然而,SQL 有variable binding 可以让我们参数化查询。

在 dbplyr 中使用 SQL 时,是否有一种快速的方法可以将 R 会话中的值直接替换为绑定变量占位符?

我想它不一定是 dbplyr,但这就是我使用的。

我记得 RMarkdown supports an SQL engine 允许带有 SQL 的块将变量绑定到(全局?)环境中的值。 (在that page中搜索文本“如果需要将R变量的值绑定到SQL查询中”。)基于此,似乎有人已经设置了一种方法来做简单的变量绑定。

例如,下面的代码使“Oracle SQL Developer”程序在我运行时提示我输入:param1 的值。

select 
  * 
from 
  ( select 'test' as x, 'another' as y from dual )
where x = :param1 and y = :param2 

我想在 R 中使用相同的代码并使用一些参数运行它。这不起作用,但如果有一个功能可以做到这一点,我认为它可能会起作用:

# Assume "con" is a DB connection already established to an Oracle db.
tbl( con, 

  args_for_oracle_sql( 

    "select 
      * 
    from 
      ( select 'test' as x, 'another' as y from dual )
    where x = :param1 and y = :param2 ", 

    # Passing the named parameters
    param1 = "test", 

    param2 = "another" 

  ) 
)


# Here's another interface idea that is perhaps similar to 
# what is shown here for SQL: https://bookdown.org/yihui/rmarkdown/language-engines.html#sql

raw_sql <- "
    select 
      * 
    from 
      ( select 'test' as x, 'another' as y from dual )
    where x = :param1 and y = :param2 "

# Set variables that match parameter names in the current environment.
param1 <- "test"
param2 <- "another"

tbl( con, 

  exc_with_args_for_oracle_sql( 

    # Pass raw SQL with the ":param1" markers       
    sql = raw_sql, 

    # Pass the function an environment that contains the values 
    # of the named parameters in the SQL. In this case, the 
    # current environment where I've set these values above. 
    env_with_args = environment()

  ) 
)

顺便说一句,我不确定需要以下哪些库,但这是我加载的:

library(RODBC)
library(RODBCext)
library(RODBCDBI)
library(DBI)
library(dplyr)
library(dbplyr)
library(odbc)

【问题讨论】:

【参考方案1】:

使用 dbplyr 中的 build_sql() 函数(用于字符串)

library(DBI)
library(dbplyr)
library(odbc)
param1 = readline("What is the value of param1 ?")  # base R
param1 = rstudioapi::askForPassword("What is the value of param1 ?") # RStudio
param2 = readline("What is the value of param2 ?")  # 

con = dbConnect('XXX') # Connection
# write your query (dbplyr)
sql_query = build_sql("select 
      * 
    from 
      ( select 'test' as x, 'another' as y from dual )
    where x = ",param1," and y = ", param2, con = con)

df = dbGetQuery(con,sql_query)

【讨论】:

以上是关于如何将 R 会话中的值替换为 SQL 绑定变量占位符?的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis的笔记

mysqlprepared statements中的绑定过程

Mybatis面试题总结

为 EXECUTE IMMEDIATE 解析 PL/SQL 语句中的占位符

mybatis整理

OTL翻译 -- otl_stream流相关绑定变量