Вставить в MySQL из R - PullRequest
       14

Вставить в MySQL из R

0 голосов
/ 15 февраля 2019

Я использую пакет DBI для вставки данных в MySQL.Вот код:

ch <- DBI::dbConnect(MySQL())
dbSendQuery(ch, 'set character set "utf8"')
dbSendQuery(ch, 'SET NAMES utf8')
for (i in 1:nrow(test)) {
  query <- paste0("INSERT INTO trade_data VALUES('0', '", test[i, 1], "', '",
                  test[i, 2], "', ", test[i, 3], "')")
  dbSendQuery(ch, query)
}

Проблема в столбце 3td, который является числовым, но имеет значения NA.Когда цикл попадает в строку со значением NA, он возвращает ошибку:

Ошибка в .local (conn, Statement, ...): не удалось выполнить инструкцию: неизвестный столбец 'NA' в'список полей'

Я пытался изменить NA на NaN, "NULL" и некоторые другие типы, но ничего не работает.Если я изменяю NA на 0, это работает.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Рассмотрим отраслевой стандарт параметризации программирования для любого прикладного уровня, например R, на котором работает SQL.Благодаря такому подходу вы избегаете необходимости интерполяции строк или использования грязных кавычек.Стандарт DBI R имеет несколько способов, одним из которых является sqlInterpolate:

# PREPARED STATEMENT (NO DATA) QMARKS REQUIRED BUT NAMES CAN CHANGE
sql <- "INSERT INTO trade_data (Col1, Col2, Col3, col4) 
        VALUES (?param1, ?param2, ?param3, ?param4)"

ch <- DBI::dbConnect(MySQL())
dbSendQuery(ch, 'set character set "utf8"')
dbSendQuery(ch, 'SET NAMES utf8')

for (i in 1:nrow(test)) {
  # BIND PARAMS
  query <- sqlInterpolate(conn, sql, param1 = "0", param2 = test[i, 1], 
                          param3 = test[i, 2], param4 = test[i, 3])
  # EXECUTE QUERY
  dbSendQuery(ch, query)
}
0 голосов
/ 16 февраля 2019

Я правильно понял.Мне пришлось изменить "" на "NULL" и NA на NULL, а затем использовать оператор ifelse при вставке.Как это:

ch <- DBI::dbConnect(MySQL())
dbSendQuery(ch, 'set character set "utf8"')
dbSendQuery(ch, 'SET NAMES utf8')
test[test == ""] <- "NULL"
test[is.na(test)] <- "NULL"
for (i in 1:nrow(test)) {
  query <- paste0("INSERT INTO trade_data VALUES('0', '", test[i, 1], "', ",
                  ifelse(test[i, 2] == "NULL", test[i, 2], paste0("'", test[i, 2], "'")), ", ", 
                  ifelse(test[i, 3] == "NULL", test[i, 3], paste0("'", test[i, 3], "'")), ", ",
                  # test[i, 3],", ", 
                  test[i, 4], ", ",
                  test[i, 5], ", ",
                  test[i, 6], ", ", test[i, 7] , ", ",
                  test[i, 8], ", ", test[i, 9] , ", ",
                  test[i, 10], ", ", test[i, 11] , ", '",
                  test[i, 12], "')")
  dbSendQuery(ch, query)
}
DBI::dbDisconnect(ch)
0 голосов
/ 15 февраля 2019

Если вам удобно сменить NA на 0, то лучше всего сделать следующее:

test[is.na(test)] <- 0

Это заменит все NA в data.frame testс 0. Вы можете сделать то же самое и изменить строку «NULL», если хотите.

test[is.na(test)] <- 'NULL'

Если вы хотите заменить только столбец, вы можете сделатьследующее:

test$col3[is.na(test$col3)] <- 0

...