#sql #r #sql-update #rodbc
#sql #r #sql-update #rodbc
Вопрос:
Я читаю в файле .csv и сравниваю два поля, одно в таблице с именем «Col» и одно в файле .csv с именем «newdata». Если они совпадают, я перезаписываю item_price в таблице «COL» значением avg_price в «newdata». Я не получаю ошибок, но в COL ничего не изменилось.
library(RODBC)
db <- "C:/Projects/Online.accdb"
conn <- odbcConnectAccess2007(db)
newData <- read.csv("C:/Projects/duplicates.csv", stringsAsFactors = F)
for(row in 1:nrow(newData)){
query <- paste0(
"UPDATE COL
SET item_price = ",newData$avg_price[row],
"WHERE COL.generic ='",newData$generic[row],"'"
)
sqlQuery(conn, query)
}
close(conn)
Комментарии:
1. Можете ли вы напечатать (запрос) в цикле и похоже ли это на правильный sql, который соответствует вашей базе данных Access с законным предложением where? Если вы выполните один из этих операторов print (query) в базовом Access вручную, изменит ли это ваш COL, как ожидалось?
2. Item_price не отображается: [1] «ОБНОВИТЬ COL n УСТАНОВИТЬ item_price = ГДЕ COL.generic =’8440-20-008-7933′»
3. Я предполагаю, что могу просто запустить запрос в access, чтобы увидеть, где я ошибся, но я думал, что смогу научиться, выполнив в R.
4. что вам дает head (newData)?
5. общая средняя стоимость 1 8440-20-008-7933 6.070 2 8440-20-001-0714 9.735 3 8405-20-003-0729 20.540 4 8315-21-868-7262 9.315 5 8315-21-899-3717 19.190 6 8315-21-899-3721 7.765
Ответ №1:
Из комментариев ниже предложите исправление, которое изменит имена столбцов входного файла, чтобы они соответствовали именам запроса:
library(RODBC)
db <- "C:/Projects/Online.accdb"
conn <- odbcConnectAccess2007(db)
newData <- read.csv("C:/Projects/duplicates.csv", stringsAsFactors = F)
names(newData) <- c("generic","avg_price")
for(row in 1:nrow(newData)){
query <- paste0("UPDATE COL SET item_price = ",newData$avg_price[row]," WHERE COL.generic ='",newData$generic[row],"'")
sqlQuery(conn, query)
}
close(conn)
Комментарии:
1. Сорен, большое спасибо за это. Один вопрос, кажется, что это влияет только на часть таблицы. В таблице более 3,5 миллионов записей. Видите ли вы что-нибудь в коде, что ограничивало бы запрос на обновление?
2. Рад, что это помогло! Посмотрите, что вы получите с помощью «length(unique (newData $ generic))», это даст вам общее максимальное количество обновлений, которые вы передаете в базу данных. Если число, которое вы получаете здесь, составляет, скажем, 100 000, то вы можете ожидать только такого количества обновлений. Если число близко к 3,5 миллионам, то вам может потребоваться более внимательно изучить значения newData $ generic, чтобы увидеть, является ли это общее значение ‘id’ допустимым значением, существующим в вашей базе данных
3. Длина (..) в newData составляет всего 173. Это просто длина файла newData. Он должен принимать каждую запись в newData, находить все записи в COL, которые соответствуют ей (из 3,5 миллионов записей) и заменять item_price в COL значением в avg_price. Но, похоже, обновление прекращается после нескольких сотен совпадений. Вы хотите сказать, что это обновит только 173 записи в COL для каждого совпадения?
4. Сложно сказать, не видя данных с обеих сторон файла .csv и файла Access, но похоже, что ваш цикл работает должным образом, даже если он работает наполовину. То, что он перестает работать, говорит о том, что он каким-то образом не соответствует. Возможно, значение общего идентификатора неверно отформатировано с одной или другой стороны, поэтому оно не находит соответствия (возможно, там есть пробелы или дополнительные знаки препинания?). Если есть 173 уникальных значения CSvid, в вашей базе данных вы можете выполнить «выбрать количество (отличное от общего) из COL» и посмотреть, есть ли там 173 для сопоставления?
5. Хорошо, я проработаю это. Я предполагаю, что мне также не нужно запускать цикл for для каждой записи в БД.