Вставка данных в таблицу Oracle - PullRequest
0 голосов
/ 19 октября 2018

Я очень плохо знаком с 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 самостоятельно.Что я делаю неправильно?

Спасибо!

1 Ответ

0 голосов
/ 19 октября 2018

Несколько операторов SQL не поддерживаются в вызовах dbGetQuery, dbSendQuery, dbSendUpdate.Вам нужно перебирать их для каждого оператора.Следовательно, почему обрабатывается только первое утверждение.Чтобы решить эту проблему, расширьте анонимную функцию внутри 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, поддерживая параметризацию с помощью dbSendUpdate, как упомянуто в rForge docs для массовых вставок без необходимости итеративной конкатенации строк.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...