如何使用RPostgreSQL参数(插入数据)

时间:2013-11-25 19:10:08

标签: sql r postgresql rpostgresql

我正在尝试使用RPostgreSQL将数据插入到预先存在的PostgreSQL表中,我无法弄清楚SQL参数的语法(预处理语句)。

E.g。假设我想做以下

insert into mytable (a,b,c) values ($1,$2,$3)

如何指定参数?如果您只是将参数放在dbSendQuery

中,...似乎无法理解

我发现dbWriteTable可以用来转储整个表,但是不允许你指定列(因此对默认值没有好处等)。无论如何,一旦我获得了数据,我就需要知道其他查询(所以我认为这不是特定的插入特定的)!

当然,我只是遗漏了一些明显的东西......

3 个答案:

答案 0 :(得分:6)

我一直在寻找相同的东西,出于同样的原因,这就是安全性。

显然dplyr包具有您感兴趣的容量。它几乎没有记录,但它就在那里。向下滚动到" Postgresql"在这个小插图中:http://cran.r-project.org/web/packages/dplyr/vignettes/databases.html

总而言之,dplyr提供了函数sql()和escape(),它们可以组合起来生成参数化查询。 DBI包中的SQL()函数似乎以完全相同的方式工作。

> sql(paste0('SELECT * FROM blaah WHERE id = ', escape('random "\'stuff')))
<SQL> SELECT * FROM blaah WHERE id = 'random "''stuff'

它返回类的对象&#34; sql&#34;和&#34;字符&#34;,所以你可以将它传递给tbl()或者也可能传递给dbSendQuery()。

escape()函数也正确处理向量,我发现它最有用:

> sql(paste0('SELECT * FROM blaah WHERE id in ', escape(1:5)))
<SQL> SELECT * FROM blaah WHERE id in (1, 2, 3, 4, 5)

同样自然也适用于变量:

> tmp <- c("asd", 2, date())
> sql(paste0('SELECT * FROM blaah WHERE id in ', escape(tmp)))
<SQL> SELECT * FROM blaah WHERE id in ('asd', '2', 'Tue Nov 18 15:19:08 2014')

我现在把查询放在一起更安全。

答案 1 :(得分:3)

截至最新RPostgreSQL,它应该有效:

db_connection <- dbConnect(dbDriver("PostgreSQL"), dbname = database_name,
                   host = "localhost", port = database_port, password=database_user_password,
                   user = database_user)
qry = "insert into mytable (a,b,c) values ($1,$2,$3)"
dbSendQuery(db_connection, qry, c(1, "some string", "some string with | ' "))

答案 2 :(得分:2)

这是一个使用DBIRPostgres软件包的版本,并且一次插入多行,因为这些年以后仍然很难从文档中找出。

x <- data.frame(
  a = c(1:10),
  b = letters[1:10],
  c = letters[11:20]
)

# insert your own connection info
con <- DBI::dbConnect(
  RPostgres::Postgres(),
  dbname = '', 
  host = '', 
  port = 5432, 
  user = '',
  password = ''
)

RPostgres::dbSendQuery(
  con, 
  "INSERT INTO mytable (a,b,c) VALUES ($1,$2,$3);",
  list(
    x$a,
    x$b,
    x$c
  )
)

dbBind()软件包中DBI的帮助是唯一说明如何格式化参数的地方:

DBI当前未指定占位符格式;在里面 将来,可能会支持统一的占位符语法。咨询 支持格式的后端文档...。已知示例为:

    RMySQL和RSQLite中的
  • ?(按出现顺序进行位置匹配)
  • RPostgres和RSQLite中的
  • $1(按索引进行位置匹配)
  • 在RSQLite中
  • :name$name(命名匹配)