10

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

例如,假设我想做以下事情

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

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

我发现dbWriteTable可以用来转储整个表,但不会让你指定列(所以对默认值等没有好处)。无论如何,一旦我在其中获取数据,我就需要知道其他查询的这一点(所以我想这并不是真正插入特定的)!

当然我只是错过了一些明显的东西......

4

3 回答 3

7

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

显然 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'

它返回类“sql”和“character”的对象,因此您可以将其传递给 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')

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

于 2014-11-18T13:23:26.067 回答
5

截至最新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 | ' "))
于 2016-10-17T16:09:40.943 回答
3

这是一个使用DBIandRPostgres包的版本,一次插入多行,因为这么多年过去了,仍然很难从文档中弄清楚。

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 中
  • $1RPostgres 和 RSQLite 中的(按索引进行位置匹配)
  • :name$name(命名匹配)在 RSQLite

?也是 R package 的占位符RJDBC

于 2020-07-01T22:20:08.987 回答