我已经多次遇到这个问题,以至于没有尝试编写自己的解决方法。就个人而言,我在使用 Microsoft SQL Server 时遇到了同样的问题,但我认为同样的解决方案也适用于 SQLite。我正在与:
- 数据库:托管在 Azure 中的 Microsoft SQL Server
- R:3.5.0
- DBI:1.0.0
- 数据库:1.1.6
- 操作系统:Ubuntu 18.04
方法:
为了效率,我想避免遍历行。我发现了这一点,mapply
并且paste0
可以以更面向列的方式进行组合。
我承认这有点“hacky”,但它对我自己来说效果很好。使用风险自负;我仅将其用于小型项目,而不是企业解决方案。无论如何,效率应该不是那么大的问题,因为无论如何插入都有1000 行的限制。
替换“sqlAppendTable”:
db_sql_append_table <- function(p_df, p_tbl) {
# p_df: data.frame that contains the data to append/insert into the table
# the names must be the same as those in the database
# p_tbl: the name of the database table to insert/append into
num_rows <- nrow(p_df)
num_cols <- ncol(p_df)
requires_quotes <- sapply(p_df, class) %in% c("character", "factor", "Date")
commas <- rep(", ", num_rows)
quotes <- rep("'", num_rows)
str_columns <- ' ('
column_names <- names(p_df)
for(i in 1:num_cols) {
if(i < num_cols) {
str_columns <- paste0(str_columns, column_names[i], ", ")
} else {
str_columns <- paste0(str_columns, column_names[i], ") ")
}
}
str_query <- paste0("INSERT INTO ", p_tbl, str_columns, "\nVALUES\n")
str_values <- rep("(", num_rows)
for(i in 1:num_cols) {
# not the last column; follow up with a comma
if(i < num_cols) {
if(requires_quotes[i]) {
str_values <- mapply(paste0, str_values, quotes, p_df[[column_names[i]]], quotes, commas)
} else {
str_values <- mapply(paste0, str_values, p_df[[column_names[i]]], commas)
}
# this is the last column; follow up with closing parenthesis
} else {
if(requires_quotes[i]) {
str_values <- mapply(paste0, str_values, quotes, p_df[[column_names[i]]], quotes, ")")
} else {
str_values <- mapply(paste0, str_values, p_df[[column_names[i]]], ")")
}
}
}
# build out the query; collapse values with comma & newline; end with semicolon;
str_values <- paste0(str_values, collapse=",\n")
str_query <- paste0(str_query, str_values)
str_query <- paste0(str_query, ";")
return(str_query)
}
调用函数:
我想让它尽可能地与原始sqlAppendTable
功能相似。此函数仅构造查询。
您仍然必须将此函数包装在dbExecute()
对数据库的实际插入/追加行的调用中。
dbExecute(conn=conn, statement = db_sql_append_table(my_dataframe, "table_name"))
编辑
- 添加了“日期”作为该函数需要引用的类型之一。谢谢你的评论!