R DBI SQL Server:dbWriteTable truncates rows / field.types 参数不起作用 RJDBC列和类型插入数据

问题描述

我正在使用 SQL Server 数据库和 JDBC 以及带有 sqljdbc42.jar 驱动程序的池。

代码:

library(DBI)
library(RJDBC)
library(pool)

jar.path.ms.sql.driver <- "./www/base/sql_drivers/sqljdbc42.jar"

jdbc.sql.driver <- JDBC(
  driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver",classPath   = jar.path.ms.sql.driver
)
sql.url <- "jdbc:sqlserver://sql01" # our server url
sql.dname <-  "my_projects"
sql.username <- "user"
sql.password <- "password"

pool <- dbPool(
  drv      = jdbc.sql.driver,url      = sql.url,dname    = sql.dname,username = sql.username,password = sql.password
)

到目前为止,一切都很好。我可以使用 dbReadTable 从数据库中读取表。我还可以使用 dbWriteTable 将表写入数据库。对于写入情况,我在数据框中有列要用很长的字符串写入。在某些情况下,字符串长度超过 255 个字符。

我曾希望使用 field.types 函数的 dbWriteTable 参数来正确配置 SQL Server 列(comments 是我要写入数据库的数据框):

conn <- poolCheckout(pool)

DBI::dbWriteTable(conn = conn,DBI::Id(cluster = "my_projects",schema = "dbo",table = "comments"),value = comments,overwrite = TRUE,row.names = FALSE,field.types = c(
               STRATEGIC_AREA = "varchar(255)",OBJECTIVE = "varchar(255)",METHOD_OF_MEASURE = "varchar(MAX)",TARGET = "float",UNIT = "varchar(255)",MIN_MAX = "varchar(255)",JUL = "varchar(1024)",AUG = "varchar(MAX)",SEP = "varchar(MAX)",OCT = "varchar(MAX)",NOV = "varchar(MAX)",DEC = "varchar(MAX)",JAN = "varchar(MAX)",FEB = "varchar(MAX)",MAR = "varchar(MAX)",APR = "varchar(MAX)",MAY = "varchar(MAX)",JUN = "varchar(MAX)"
  ))
poolReturn(conn)
poolClose(pool)

问题是 SQL Server 数据库忽略了列类,并与 varchar(255) 列一致创建。 varchar(1024) 中的 varchar(MAX)field.types 等列类将被忽略。该函数似乎遵循数据框列类的映射:

  • char -> varchar(255)
  • num -> float

如果我用 DBI::Id(cluster = "my_projects",table = "comments") 替换 "my_projects.dbo.comments" 似乎没有什么区别。如果我引用传递给 field.types 的命名字符向量的左侧也没关系。

因此,包含长度超过 255 个字符的字符串的数据框行被截断(这些行被跳过),并且与数据框相比,SQL Server 表中的行最终更少。错误消息(非常长的字符串位于 FEB 列中):

.local(conn,statement,...) 中的错误:
在 dbSendUpdate 中执行 JDBC 更新查询失败(字符串或二进制数据将在表“my_projects.dbo.comments”,列“FEB”中被截断。截断的值:

我错过了什么?

更新

根据下面 sgoley 的更新,我将代码更改如下:

dbCreateTable(
  conn = conn,Id(
    database = "my_projects",table = "comments"
  ),fields = c(
    STRATEGIC_AREA = "varchar(255)",METHOD_OF_MEASURE = "varchar(255)",JUL = "varchar(MAX)",JUN = "varchar(MAX)"
  ),row.names = NULL
)


values <- DBI::sqlAppendTable(con = conn,table = Id(database = "my_projects",values = comments,row.names = FALSE)
RJDBC::dbSendUpdate(conn,values)

这现在可以正常工作,没有任何问题和错误消息。使用 Microsoft SQL Server Management Studio 进行的验证确认列现在是正确的类并遵循 fields 规范。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)