【问题标题】:Upload to SQL Server 2012 via ODBC dbWriteTable - Error "String data, right truncation" column type chr vs. nvarchar(50)通过 ODBC dbWriteTable 上传到 SQL Server 2012 - 错误“字符串数据,右截断”列类型 chr 与 nvarchar(50)
【发布时间】:2017-12-15 10:25:10
【问题描述】:

我尝试将一个 data.table 从 R 插入 SQL Server 2012 数据库:

library(data.table)
library(odbc)
library(dplyr)

upload.data <- data.table(readxl::read_excel(path = uploadfile.file, sheet = 
sheet_no, skip = skip_rows), col_names = TRUE)

odbcChannel <- dbConnect(odbc::odbc(), "SQL")

dbWriteTable(odbcChannel, "Table_Name", upload.data, append = TRUE, overwrite = FALSE, row.names=FALSE, encoding = "latin1")

数据表中的列是 chr 类型。 SQL Server 中目标表的列类型为varchar(50)

我的理解是 chr 将被上传为varchar(255)。因此,我会收到错误:

result_insert_dataframe(rs@ptr, values) 中的错误:
nanodbc/nanodbc.cpp:1587:22001:[Microsoft][ODBC SQL Server Driver]字符串数据,右截断

如何更改 R 中的列以匹配数据库中表的特定需求?

如果列中的内容不适合数据库表,我希望将信息删除。

一种解决方案:将数据表上传到服务器的新表中,然后编辑要匹配的类型:

dbSendStatement(odbcChannel,"ALTER  TABLE Table_Name
                             ALTER COLUMN Batch_Name Nvarchar(50)")

之后我可以将数据插入到目标表中。但这似乎相当复杂,尤其是如果数据库中的每一列都有不同的类型。

最好的问候和感谢,

生命值

【问题讨论】:

    标签: sql-server r database data.table


    【解决方案1】:

    我找到了解决这个问题的方法。

    如果我使用以下代码,我可以定义字段类型和长度:

    sql.field.types <- list(Batch_Name = "nvarchar(50)")
    
    dbWriteTable(odbcChannel, "Table_Name", upload.data, append = TRUE, overwrite = FALSE, 
                                  row.names=FALSE, encoding = "latin1", field.types = sql.field.types )
    

    如果数据表中的一列中的内容比数据库中定义的更长,这仍然会产生错误消息。

    但是最好用R来调整数据表中的数据,以满足数据库的要求。因此,您始终拥有一个已定义且可重现的过程。

    最好的问候,

    生命值

    【讨论】:

      【解决方案2】:

      有同样的问题。尝试了建议的解决方案,但没有奏效。

      一个选项是太截断数据(不是最优的)

      b <- upload.data[, lapply(upload.data, function(x) max(nchar(x), na.rm=TRUE)) > 240] %>% colnames()
      upload.data[b] <- substr(upload.data[b], 1, 240)
      

      其中 240 是用于剪切字符串的任意最大字符长度。

      然后,你可以追加数据

      DBI::dbWriteTable(odbcChannel,
                              name = "Table_Name".
                              value = upload.data,
                              append = TRUE, overwrite = FALSE, 
                              row.names=FALSE, encoding = "latin1")
      

      仍然很高兴听到避免截断数据的替代方法!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-18
        • 1970-01-01
        • 2013-01-15
        • 1970-01-01
        • 2020-07-26
        • 2015-04-05
        • 1970-01-01
        相关资源
        最近更新 更多