【问题标题】:How to use parameters with RPostgreSQL (to insert data)如何在 RPostgreSQL 中使用参数(插入数据)
【发布时间】:2013-11-25 19:10:08
【问题描述】:

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

例如假设我想做以下事情

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

如何指定参数? dbSendQuery 好像不明白,你只是把参数放在... 里。

我发现dbWriteTable 可用于转储整个表,但不允许您指定列(因此不适合默认值等)。无论如何,一旦我在其中获取数据,我就需要知道其他查询的这一点(所以我想这并不是真正插入特定的)!

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

【问题讨论】:

  • [这个答案有帮助][1]?这个问题似乎与那里提出的问题相似。 [1]:stackoverflow.com/questions/2186015/bind-variables-in-r-dbi
  • @JoeLove 我认为(但不是 100% 肯定)这是 RSQLite 特有的。
  • @joran,是的,那是错误的(删除它)。我的意思是相反的:R 是一种统计语言,与通用语言相比,数据库功能较弱而感到不安是错误的。就像你不会期望 c# 中的 glm 一样。如:这不是 R 的错,我使用了错误的工具来完成这项工作。
  • @Corone 是的,我实际上同意一般评估。我认为,R 的大部分数据库功能都是根据数据总是以一种方式传输的想法设计的,从 db 到 R 进行分析。

标签: sql r postgresql rpostgresql


【解决方案1】:

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

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

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

【讨论】:

  • 您也可以使用完全支持参数化查询的新github.com/rstats-db/RPostgres
  • 谢谢@hadley。有关于参数化部分的任何示例吗?前几天写了一个blog post关于大插入的性能,想对包做个对比。
  • 还没有,但我正在为下周的 Rstudio 博客撰写一篇博文。请注意,Postgres 的参数化插入很慢,因此 RPostgres 中的 dbWriteTable 使用不同的策略(LOAD INFILE)
  • 我猜,问题是关于向特定列插入/追加/更新数据。
【解决方案2】:

最新的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 | ' "))

【讨论】:

  • 我无法让类似的事情发挥作用,至少对于 dbGetQuery。能否提供更详细的出处?
【解决方案3】:

这是一个使用 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
  )
)

DBI 包中对dbBind() 的帮助是唯一解释如何格式化参数的地方:

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

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

? 也是 R 包 RJDBC 的占位符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2019-04-05
    • 2016-11-15
    • 2017-07-28
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多