从 R 脚本插入 SQL 服务器 VARBINARY 列

Inserting into SQL Server VARBINARY column from R script

我有一个 plots table,它的列包括 plot,它存储图像文件的二进制数据。我是 运行 一个 T-SQL 查询,它调用 R 脚本并取回要插入的数据的数据帧。数据框如下所示:

    plot     name  date_from    date_to
1 ABCDEF  plot1   2016-08-25   2016-08-31
2 AAAAAA  plot2   2016-08-25   2016-08-31

如您所见,绘图列已包含原始数据。

澄清一下,我想要做的是将两行与数据框中的数据一起插入数据库(数据框列名与数据库列匹配)。

我遇到的问题

INSERT INTO dbo.plots
EXECUTE sp_execute_external_script
    @language = N'R'
    ,@script = N'source("path/to/r/script.R")'
    ,@output_data_1_name = N'output_dataset'

是"Implicit conversion from data type nvarchar(max) to varbinary(max) is not allowed. Use the CONVERT function to run this query"。

但是我不确定如何纠正这个错误。我会将 CONVERT 函数放在哪里?或者有其他方法吗?

不幸的是,我的 SQL 服务器版本无法完成您所做的所有很棒的 R 功能。所以我能提供的最好的是一个 R 脚本,它可以成功地将二进制数据导入 table,希望您能够进行必要的调整。

我在 SQL 服务器上使用 table 定义为

CREATE TABLE [dbo].[InsertFile](
    [OID] [int] IDENTITY(1,1) NOT NULL,
    [filename] [varchar](50) NULL,
    [filedata] [varbinary](max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

我的 R 脚本是

library(RODBCext)
library(magrittr)

# My example just grabs all the text files out of a directory,
# but as long as you have the full filename, this will work.

file_name <- list.files([directory_to_files],
                        pattern = "[.]txt$",
                        full.names = TRUE)

file_content <- 
  vapply(
    file_name,
    function(x)
    {
      # read the binary data from the file
      readBin(x,
              what = "raw",
              n = file.info(x)[["size"]]) %>%
        # convert the binary data to a character string suitable for import
        as.character() %>%
        paste(collapse = "")
    },
    character(1)
  )

channel <- odbcConnect(...) # Create your connection object here

sqlExecute(
  channel = channel,
  query = paste0("INSERT INTO dbo.InsertFile ",
                 "(filename, filedata) ",
                 "VALUES ",
                 "(?, ?)"),
  data = list(filename = basename(file_name),
              filedata = file_content)
)

执行该脚本后,file_name.

中的每个文件在 dbo.InsertFile table 中都有一个新行

对于 SQL 服务器 R 服务,字符类型映射到 VARCHAR,原始类型映射到 VARBINARY(参见 Working with R Data Types)。要将数据存储为 VARBINARY,必须将十六进制字符串转换为原始字节,这可以在 R 或 SQL 中完成。这是一个在 SQL 中使用临时 table 完成转换的示例(受 scsimon 的评论启发)

CREATE TABLE #test
(
    [data] VARBINARY(MAX),
)


CREATE TABLE #temp
(
    [data] VARCHAR(MAX),
)

INSERT INTO #temp
EXEC sp_execute_external_script
@language=N'R',
@script=N'OutputDataSet <- as.data.frame("ABCDEF")' 

INSERT INTO #test SELECT CONVERT(VARBINARY(MAX), data, 2) FROM #temp;