首页 > 解决方案 > 将数据插入 Oracle 表

问题描述

我对 R 很陌生,所以请原谅任何明显或幼稚的错误。我需要将 R 中的多行数据插入到 Oracle 数据库表中。

制作数据框(我在脚本前面已经建立了 RJDBC 连接):

df <- data.frame("field_1" = 1:2, "field_2" = c("f","k"), "field_3"= c("j","t"))

此代码运行没有错误,但只将第一行插入到表中:

insert <- sprintf("insert into temp_r_test_u_suck values (%s')", 
                  apply(df, 1, function(i) gsub(" ", "", paste("'", i, collapse="',"), fixed = TRUE)))
dbSendUpdate(con, insert)

此代码运行:

insert <- sprintf("into temp_r_test_u_suck values (%s')", 
                  apply(df, 1, function(i) gsub(" ", "", paste("'", i, collapse="',"), fixed = TRUE)))
insert_all <- c("insert all", insert, "select * from dual")
dbSendUpdate(con, insert_all)

但是给了我这个错误:

Error in .local(conn, statement, ...) : 
  execute JDBC update query failed in dbSendUpdate (ORA-00905: missing keyword

这两个查询都在 Oracle 中独立工作。我究竟做错了什么?

谢谢!

标签: rdatabaseoracle

解决方案


dbGetQuery, dbSendQuery,dbSendUpdate调用中不支持多条 SQL 语句。您需要为每个语句遍历它们。因此,为什么只处理第一个语句。要解决此问题,请将内部的匿名函数扩展apply为调用dbSendUpdate

apply(df, 1, function(i) {
      # BUILD SQL STATEMENT
      insert <- sprintf("insert into temp_r_test_u_suck values (%s')", 
                        paste0("'", i, collapse="',"))

      # RUN QUERY
      dbSendUpdate(con, insert)
})

但是,RJDBC 通过支持参数化来扩展 DBI 标准,dbSendUpdaterForge 文档中所述,用于批量插入,无需迭代连接字符串。

dbSendUpdate(conn, statement, ...)

此函数类似于 dbSendQuery,但适用于 DBML 语句,因此不返回结果集。它比 dbSendQuery 更有效。此外,从 RJDBC 0.2-9 开始,它在准备好的语句中支持向量,从而允许批量插入。

# ALL CHARACTER DATAFRAME
df <- data.frame(field_1=as.character(1:2), field_2=c("f","k"), field_3=c("j","t"), 
                 stringsAsFactors=FALSE)

# PREPARED STATEMENT
sql <- "insert into temp_r_test_u_suck values (?, ?, ?)"

# RUN QUERY
dbSendUpdate(con, sql, df$field_1, df$field_2, df$field_3)

推荐阅读