从 SQL Server 中获取序列化为 varbvinary 的 R 对象并取消序列化() 它

get R object serialized as varbvinary from SQL Server and unserialize() it

提问人:MikeB 提问时间:8/9/2023 最后编辑:MikeB 更新时间:8/10/2023 访问量:47

问:

有人曾经将 R 对象粘贴到 SQL Server 的 VARBINARY 列中。serialize()

我怎么能出来?unserialize()

下面是获取数据的代码:

library(RODBC)
dbhandle <- odbcDriverConnect("MyConnection String")
x = sqlQuery(dbhandle, sprintf('select SomevarbinaryColumn from MyTAble WHERE the_key = 8675309'))

如果我尝试这个:

unserialize(x$SomevarbinaryColumn[1])

我得到

Error in unserialize(x$SomevarbinaryColumn[1]) :
   'connection' must be a connection

令人困惑的是,第一个参数被命名为 。文档说“unserialize 从连接或原始向量读取对象(由 serialize 写入)。这里可能提供什么样的连接?相反,我认为我正在尝试传递原始向量,但我无法弄清楚如何将 RODBC 结果转换为原始向量。unserialize()connection

我试图弄清楚什么是类型,这样我就可以将其转换为喜欢的东西:x$SomevarbinaryColumn[1]unserialize()

print(typeof(x$SomevarbinaryColumn[1]))

[1] "list"

RODBC 文档说 varbinary 将作为“原始向量列表”返回。

如何从这个返回的列表中获取想要的原始向量?unserialize()

R 反序列化 rodbc

评论

1赞 MrFlick 8/9/2023
您能否提供输出,以便我们可以看到数据是如何返回的?它是原始值列表吗?dput(x)
0赞 MikeB 8/9/2023
@MrFlick对不起,我不能。 打印许多兆字节的十六进制数据。最后几行是:dput(x)0x28, 0xf5, 0xc7, 0x46, 0xeb, 0x55, 0x00, 0x00, 0x98, 0xf5, 0xc7, 0x46, 0xeb, 0x55, 0x00, 0x00, 0x05, 0x00, 0x00))), class = "ODBC_binary")), class = "data.frame", row.names = 1L)
1赞 MrFlick 8/9/2023
怎么样,那行得通吗?如果不是,是什么?unserialize(x$SomevarbinaryColumn[[1]][[1]])class(x$SomevarbinaryColumn[[1]])
0赞 MikeB 8/9/2023
@MrFlick 的结果为 ,并给出 。在这一点上,我想我已经将其追溯到 RODBC 中的一个错误,如果我能确认的话,我会把它写下来。unserailize()read errorclass()[1] "raw"

答:

0赞 MikeB 8/10/2023 #1

这里有两个问题。一是 RODBC 无法可靠地从 SQL Server 获取二进制数据;另一个是我必须弄清楚如何解压缩返回的二进制数据(如果它被返回),以便我可以调用它并重新冻结我的对象。unserialize()

在相关问题中,我解释了我在调查 RODBC 处理 .varbinary(max)

现在,让我们假设 RODBC 可以工作并获取正确的数据。我有时可以哄骗它这样做,但从长远来看,需要更好的修复。也许软件包维护者会做出回应,或者我会为软件包做一些修复,或者我会切换到不同的软件包。

问题是,即使 RODBC 看起来正在工作,它也可能返回错误数据。如果我对此进行编码:

x = sqlQuery(dbhandle, sprintf('select SomevarbinaryColumn from MyTAble WHERE the_key = 8675309'))

然后 R 遇到 GPE,或者我取回数据。返回的数据长度正确,但数据不正确,即是未初始化的垃圾。它永远无法取消序列化到我的对象中。

但是,有时我可以对此进行编码以解决 RODBC 错误:

x = sqlQuery(dbhandle, sprintf('select CAST(SomevarbinaryColumn AS IMAGE) AS SomevarbinaryColumn from MyTAble WHERE the_key = 8675309'))

然后我发现我确实得到了正确的数据。它的长度是正确的,并且包含预期的字节!

剩下的就是找到正确的方法把我的对象拿出来。这就是这里:

x = unserialize(as.raw(unlist(x$SomevarbinaryColumn[1]))) 

希望这个答案能帮助那些使用更可靠的存储的人,并面对如何解压缩序列化数据的问题。