【问题标题】:How do I substitute values from the R session into SQL bind variable placeholders?如何将 R 会话中的值替换为 SQL 绑定变量占位符?
【发布时间】: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)

【问题讨论】:

    标签: sql r oracle-sqldeveloper dbplyr bind-variables


    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2020-06-03
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 2017-10-31
      相关资源
      最近更新 更多