代码之家  ›  专栏  ›  技术社区  ›  Sam Mason

将RPostgres或RPostgreSQL dbGetQuery()参数传递给IN运算符

  •  1
  • Sam Mason  · 技术社区  · 7 年前

    只是想知道是否有任何方法可以将任意数量的参数传递给 IN 条款via params 属于 dbGetQuery()

    例如,给定

    dbcon <- dbConnect(RPostgres::Postgres())
    # or: dbcon <- dbConnect(RPostgreSQL::PostgreSQL())
    
    dbExecute(dbcon, "CREATE TEMP TABLE foo AS SELECT i FROM generate_series(1, 10) x(i);")
    

    我能做点什么吗

    dbGetQuery(dbcon, "SELECT * FROM foo WHERE i IN (1, 2, 3)")
    

    其中标识符是“值的短列表”,即通常小于10个整数或字符串。我想我可以做些什么:

    ids <- c(1, 2, 3)
    dbGetQuery(dbcon, "SELECT * FROM foo WHERE i IN $1", list(ids))
    

    但我能做的就是:

    ids <- '{1,2,3}'
    dbGetQuery(dbcon, "SELECT * FROM foo WHERE i = ANY($1)", list(ids))
    

    但随后 ids 从一组字符串中提取有点容易出错。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Chrisss    7 年前

    你想用 DBI::sqlInterpolate 用于生成动态查询。这比不安全地将查询粘贴在一起要好。但是它对矢量输入不起作用,所以, dbplyr::translate_sql 如果你能忍受更多的包导入,那就足够了。例子:

    require(DBI)
    require(dbplyr)
    
    con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:")
    month_input <- SQL(!!translate_sql(month.abb))
    # Or if you don't like lazy-eval NSE nonsense
    month_input <- dbplyr:::escape(month.abb)
    print(month_input)
    # <SQL> ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
    
    query <- sqlInterpolate(con, "SELECT * FROM colours WHERE month IN ?months",
      months = month_input)
    print(query)
    # <SQL> SELECT * FROM colours WHERE month IN ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')