【问题标题】:Excel - does not show varbinary(16) column from SQL Server DatabaseExcel - 不显示 SQL Server 数据库中的 varbinary(16) 列
【发布时间】:2016-11-09 01:40:05
【问题描述】:

我有一个 SQL Server 2014 存储过程,已作为数据连接添加到 Excel 2013 工作簿中。

存储过程返回一个定义如下的表:

create table #rollups
(
    ID_INT_EXT_KEY varbinary(16) not null,
    AS_OF_DATE date not null,
    FOR_MONTH int not null,
    FOR_YEAR int not null,
    FINAL_REPORT_DEPT varchar(100) null,
    PROV_NAME varchar(100) null,
    EXTERNAL_FLAG bit not null,
    YTD_VISITS decimal(15,2) not null default 0,
    YTD_CHARGED decimal(15,2) not null default 0,
    YTD_PROCS decimal(15,2) not null default 0,
    MTD_VISITS decimal(15,2) not null default 0,
    MTD_CHARGED decimal(15,2) not null default 0,
    MTD_PROCS decimal(15,2) not null default 0,
    YTD_VISITS_DIFFLASTMONTH decimal(15,2) not null default 0,
    YTD_CHARGED_DIFFLASTMONTH decimal(15,2) not null default 0,
    YTD_PROCS_DIFFLASTMONTH decimal(15,2) not null default 0
);

-- insert data to the temp table
-- select from the temp table

我的存储过程没有问题,它按预期工作。

我已将它添加到 Excel 工作表中,作为 OLE DB 查询,命令类型是 SQL,命令文本只是存储过程的名称。

它按预期返回数据(几千行),但第一列 ID_INT_EXT_KEY(它是几列的哈希)除外。该列根本没有被拉到工作表中,不是空白的,也不是隐藏的。它只是不存在。我尝试打开行号,认为这可能与它有关,但没有。

在 SSMS 中,该列存在。

这对于我使用它的目的来说并不是一个真正的问题,但它令人困惑,我想知道我能做些什么,除了改变返回表的数据类型。

编辑:

问题:假设我有一个返回表的存储过程,并且其中一列是 varbinary,有没有办法将此列导入 Excel (使用标准外部数据连接),不创建或修改任何数据库对象?

【问题讨论】:

  • A VARBINARY(16) 是一种不 可见 或 - 更好的措辞 - 可显示 的数据类型...有 16 个字节的东西。您希望 Excel 应该如何处理这个问题?您可以将其转换为十六进制字符串(由 0-9 和 A 到 H 组成,并且主要以 0x 开头来表示这一点。您可以将其转换为 base64 或者将其转换为 16 字节长度的类型一个相当随机的值...糟糕的 Excel 应该如何处理该值?
  • 嗯,SSMS 将其转换为十六进制字符串,正如您所建议的那样。我有一种感觉,这与该列包含二进制数据的事实有关。这告诉我为什么会发生这种情况,但是我可以做些什么来解决它而不求助于修改数据库对象? IE。我可以从 Excel 做些什么来将此列显示为十六进制值?
  • 我刚刚更新了我的问题...

标签: sql-server excel sql-server-2014 type-conversion varbinary


【解决方案1】:

根据您的评论,我认为 SSMS 将其转换为十六进制字符串

这不是真的,它只是看起来像一个十六进制字符串...

SSMS 与 Excel 有同样的问题:如何显示二进制数据? SSMS 选择了 HEX 字符串,但是该列的数据类型仍然是 VARBINARY...

如果您想获得 看起来像十六进制值的真实字符串,您可以使用内置函数:

DECLARE @Varbin VARBINARY(16)=0x00112233445566778899AABBCCDDEEFF;
SELECT @Varbin AS A_varbinary_VALUE;
SELECT DATALENGTH(@Varbin);

DECLARE @ConvertedToString NVARCHAR(MAX)= sys.fn_varbintohexstr(@Varbin);
SELECT @ConvertedToString;

更新

由于您的列是 VARBINARY(16),最好直接转换为 GUID,即每个定义 16 个字节:

DECLARE @CovertedToGUID UNIQUEIDENTIFIER=CAST(@Varbin AS UNIQUEIDENTIFIER);
SELECT @CovertedToGUID;

你可以把它扔回去:

SELECT CAST(@CovertedToGUID AS VARBINARY(MAX))

但还有一个问题:为什么?

【讨论】:

  • 我的意思不是从字面上将其转换为十六进制字符串 - 我的意思是在数据显示方式的上下文中“转换”。 “为什么”与这个问题无关——我出于各种原因坚持这个哈希(它是底层存储过程的一部分,用于连接和汇总数据,并且在此之外不时有用)。就像我说的那样,这个特定的工作簿没有必要,但我只是在寻找任何方法来拉入列而不修改 SP 或创建另一个 db 对象 - 以防我将来需要它,并满足我的好奇心。
  • 啊,我明白了……在大多数情况下,最好不要使用 SP 来检索数据,而是使用 内联表值函数。在这种情况下,您可以使用 从 EXCEL 的 SQL 语句导入它并在那里进行转换...您可以尝试再定义一个 SP,如果您不想更改它,则包装第一个。 Excel 会显示一个十六进制字符串,因为它会显示一个 GUID...无需欺骗(VBA!)我不知道任何使用简单导入功能的解决方法...
  • 我相信我探索了 TVF 路线,这是不可行的,因为 SP 出于性能原因使用临时表(表变量非常慢)。我最近了解到可以索引表变量,所以也许我很快会重新审视函数的想法。那会很好,因为这样我就可以将哈希转换为数据连接本身中的 varchar。
  • @Eric,是的,如果 SP 使用多语句方法、临时表之类的东西,您将无法轻松将其转移到 TVF 中。这就是为什么我建议使用包装 SP 的原因,您首先将现有的 SP 结果插入到表中,然后使用适当的转换创建新的输出。无论如何:如果这个答案有帮助,我会请你投票。如果解决了您的问题,请勾选验收,谢谢!
  • @Eric,是你在谈论将其更改为 TVF 等 :-) 据我所知,没有办法让 Excel dsiplay 来自 SP 结果的 VARBINARY用它的名字来称呼它。您可以使用 VBA 填充 Recordset 并自己填充单元格,或者您可以提供 TVF,或者您可以更改(或包装)SP 以提供正确的类型。我想就是这样。不要怪我缺少功能:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多