R: sqlAppendTable 只适用于数字?

标签 r rsqlite r-dbi

我无法让 R 语言 DBI::sqlAppendTable 函数处理数字以外的任何内容。下面是一些说明问题的代码。我怀疑问题是 sqlAppendTable 没有引用数据。任何修复或解决方法将不胜感激。

num = data.frame(matrix(1:26, ncol=2))
let = data.frame(matrix(letters, ncol=2))

test.sqlAppendTable = function(dfr) {
    #dfr: A data frame.
    conx <- dbConnect(RSQLite::SQLite(), ":memory:")
    on.exit(dbDisconnect(conx))
    dbWriteTable(conx, "temp", dfr[1:5, ])
    temp = dbReadTable(conx, 'temp')
    print(temp)
    sat = sqlAppendTable(conx, 'temp', dfr[6:10, ])
    print(sat)
    rs = dbExecute(conx, sat)
    cat('Result set (rs): ')
    print(rs)
    temp = dbReadTable(conx, 'temp')
    print(temp)
}

test.sqlAppendTable(num) #Runs fine.
test.sqlAppendTable(let) #Generates error:
#Error in rsqlite_send_query(conn@ptr, statement) : no such column: j

最佳答案

我已经多次遇到这个问题,以至于不想尝试编写我自己的解决方法。就我个人而言,我在使用 Microsoft SQL Server 时遇到了同样的问题,但我认为同样的解决方案适用于 SQLite。我正在与:

  • 数据库:Azure 中托管的 Microsoft SQL Server
  • R: 3.5.0
  • DBI:1.0.0
  • ODBC:1.1.6
  • 操作系统:Ubuntu 18.04

  • 方法:
    为了效率,我想避免遍历行。我发现 mapplypaste0可以以更面向列的方式组合。
    我承认这有点“hacky”,但它对我自己来说一直很好。 使用风险自负;我只将它用于小型项目,而不是企业解决方案。 无论如何,效率不应该是一个大问题,因为有一个 1000 row limit无论如何插入。
    替换“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"))
    
    编辑
  • 添加“日期”作为此函数也需要引用的类型之一。谢谢你的评论!
  • 关于R: sqlAppendTable 只适用于数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43145145/

    相关文章:

    mysql - 当分类向量存储在引号中时的 RSQLite 查询

    mysql - 使用单个事务发送查询

    sql - ODBC 连接,在 R 中获取一个表

    r - 将 MS Access 数据库连接到 R

    r - 将分组的 geom_vline 添加到多个方面

    r - 在非焦点选项卡上在后台绘制 ggplot react 值变化

    从函数返回数据帧并将其存储在工作区中

    r - 在 Mac 上从 R 连接到 Oracle

    RSQLite loadNamespace(i, c(lib.loc, .libPaths()), versionCheck = vI[[i]]) 中出现错误 : namespace ‘DBI’ 0. 4-1 正在加载,但需要 >= 0.8

    sql - 如何检查 "Send Query"是否结束?