从 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;
我有一个 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;