如何使用R和Rpostgres使用参数化查询,以接受变量中包含的值作为psql的输入

时间:2019-06-24 00:18:58

标签: r postgresql rpostgresql

我想使用R将变量中包含的值作为输入传递给PostgreSQL查询。

目前,我以它为例:
https://db.rstudio.com/best-practices/run-queries-safely/

Using a parameterised query with DBI requires three steps.

You create a query containing a ? placeholder and send it to the database with dbSendQuery():

airport <- dbSendQuery(con, "SELECT * FROM airports WHERE faa = ?")
Use dbBind() to execute the query with specific values, then dbFetch() to get the results:

dbBind(airport, list("GPT"))
dbFetch(airport)
##   faa            name      lat       lon alt tz dst
## 1 GPT Gulfport-Biloxi 30.40728 -89.07011  28 -6   A
Once you’re done using the parameterised query, clean it up by calling dbClearResult()

dbClearResult(airport)

这是我当前的设置。


install.packages("RPostgres")
#https://github.com/r-dbi/RPostgres
require(RPostgres)
require(DBI)
require(tidyr)
# RPostgreSQL::PostgreSQL()

# make connection
con <- dbConnect(RPostgres::Postgres(), dbname = 'test', 
                      host = 'mydbtest.com',
                      port = 1234, # or any other port specified by your DBA
                      user = 'test',
                      password = 'test')

rs = dbGetQuery(con, "select count(*),state from sales where created > ? and created < ? group by state")

我想做什么: 将两个日期作为输入传递给查询。

我收到错误:

> rs = dbGetQuery(prod_con, "select count(*),state from sales where created > ? and created < ? group by state")
Error in result_create(conn@ptr, statement) : 
  Failed to prepare query: ERROR:  syntax error at or near "and"
LINE 1: ...count(*),state from sales where created > ? and create...

问题1 我如何解决此错误,并且是由什么原因引起的?我正在使用?如示例中给出的占位符。

问题2 如何将多个值传递给两个? 像这样

  

dbBind(con,list(“ 2019-06-21”,“ 2019-06-22”))吗?

参考文献:
how to pass value stored in r variable to a column in where clause of postgresql query in R

RPostgreSQL - Passing Parameter in R to a Query in RPostgreSQL

2 个答案:

答案 0 :(得分:1)

最好使用bind-> send-> fetch完成参数化查询。

因此,在?中使用dbGetQuery表达式的地方,将在

中完成
rs = dbSendQuery(con, "select count(*), state 
                       from sales 
                       where created > ? and created < ? group by state")

然后,将您的参数绑定到查询dbBindQuery(rs, list(blah, blah)) 最后,您dbFetchQuery(rs)

所以您的相框看起来像;

rs <- dbSendQuery(...) 

dbBindQuery(rs, ...)

dbFetchQuery(rs)

dbClearResult(rs)

所有这些都可以在Rstudio网站上找到(您已经在使用)Here。您已经注意到。

因此,对

问题1:您将dbBindQuery中的参数绑定到从dbSendQuery而非dbGetQuery返回的对象上。

问题2:我对此不太确定,但是您的参数在列表中传递。在线上有许多示例,显示了如何通过参数化来加快查询速度。 Here is one such example

答案 1 :(得分:0)

问题1的答案

它不起作用的两个原因。 您收到的语法错误是由于RPostgresql中的known issue引起的。您可以通过将?替换为$来解决。

并且在固定语法之后,必须绑定参数。请参考此答案中示例的固定版本。

问题2的答案

您可以在查询中传递多个参数,方法是将连续整数附加到$符号中。即:SELECT * FROM table where integercolumn > $1 and stringcolumn = $2

请记住在之后绑定那些参数!

相关示例的固定版本

install.packages("RPostgres")
require(RPostgres)
require(DBI)
require(tidyr)
# RPostgreSQL::PostgreSQL()

# MAKE CONNECTION
con <- dbConnect(RPostgres::Postgres(),
    dbname = 'test', 
    host = 'mydbtest.com',
    port = 1234, # or any other port specified by your DBA
    user = 'test',
    password = 'test')

# SEND QUERY
rs = dbSendQuery(con, "SELECT count(*), state FROM sales WHERE created > $1 and created < $2 GROUP BY state")

# BIND PARAMETERS
dbBind(rs, list(date1, date2)) # where date1 and date2 are your defined variables or raw date values

# FETCH FROM DB USING QUERY
rows <- dbFetch(rs)

# CLEAR RESULT
dbClearResult(rs)

请注意,绑定参数$1对应于date1

这是我的第一个堆栈溢出答案,因此如果这对您有帮助,则投票将对我有很大帮助! -杰克