XML 中二进制字段的 MSSQL 意外输出
MSSQL Unexpected output of the binary field in XML
我试图在 XML 文件中为我的 XSLT 项目获取 binary(16)
以对其进行转换。
这是我尝试过的:
SELECT BINARY_ID FROM dbo.MyTable
SELECT CONVERT(varbinary(16), BINARY_ID) AS BINARY_ID FROM dbo.MyTable
SELECT CAST(BINARY_ID AS varbinary(20)) AS BINARY_ID FROM dbo.MyTable
SELECT CONVERT(BINARY(16), BINARY_ID) AS BINARY_ID FROM dbo.MyTable
SELECT CAST(BINARY_ID AS binary(20)) AS BINARY_ID FROM dbo.MyTable
无论我怎样尝试,我的 BINARY_ID
从 0x00D25E18AEFF4979A244C2EB132791C1
变成了 ANJeGK7/SXmiRMLrEyeRwQ==
我正在使用 JDBC 连接器进行连接并从数据库中获取数据。
我开始不知道我的问题是什么原因造成的。
我的项目是否可行,或者我是否必须将其与其他项目结合起来才能实现?
在此先感谢您的帮助。
更新
这是我的 XSLT 脚本,它通过 Java 编译器进入 JDBC 连接器
<?xml version="1.0" encoding="UTF-8"?>
<xsl:output media-type="text/xml" method="xml"></xsl:output>
<xsl:template match="/">
<root>
<statement format="yyyy-MM-dd' 'hh:mm" resulttag="object_II" timezone="UTC">
<sql>
SELECT
AD.GGUID,
AD.COMPNAME AS Firmen_Name_1,
AD.COMPNAME2 AS Firmen_Name_2,
AD.GWBRANCH AS Branche,
AD.COUNTRY1 AS Land,
AD.STREET1 AS Straße,
AD.ZIP1 AS PLZ,
AD.TOWN1 AS Ort,
AD.GWSTATE1 AS Bundesland,
AD.PHONEFIELDSTR10 AS Telefon_Nr,
AD.MAILFIELDSTR5 AS EMail
FROM dbo.TABLE_I AS CL
inner join dbo.TABLE_II AS AD ON AD.GGUID = CL.TABLEGUID
Where CL.TABLENAME = 'ADDRESS'
AND CL.FIELDNAME = 'CHECKBOX'
AND AD.CHECKBOX= 1
AND AD.UPDATETIMESTAMP BETWEEN DATEADD(MINUTE, -60, SYSDATETIME()) AND SYSDATETIME()
Order BY ad.GGUID DESC
</sql>
</statement>
</root>
</xsl:template>
</xsl:stylesheet>
我使用主函数 varbintohexstr 自行修复了它
这是我完整的 MSSQL 语句。
SELECT
UPPER(master.sys.fn_varbintohexstr(AD.GGUID)) AS GGUID,
FROM dbo.TABLE_I AS CL
inner join dbo.TABLE_II AS AD ON AD.GGUID = CL.TABLEGUID
Where CL.TABLENAME = 'ADDRESS'
AND CL.FIELDNAME = 'Checkbox'
AND AD.Checkbox = 1
AND AD.UPDATETIMESTAMP BETWEEN DATEADD(MINUTE, -960, SYSDATETIME()) AND SYSDATETIME()
Order BY ad.GGUID DESC
结果:
0X00D25E18AEFF4979A244C2EB132791C1
提示:功能varbintohexstring()
是有限的...我在这里使用CONVERT()
。
一开始,十六进制字符串是在 XML 中嵌入二进制文件的默认格式。在 v2005 中,这已更改为 Base64,因为它可以表示字符较少的二进制值。
试试这个:
DECLARE @someGuid UNIQUEIDENTIFIER = NEWID();
SELECT @someGuid AS TheGuid
,CAST(@someGuid AS BINARY(16)) binValue_Base64
,CONVERT(VARCHAR(25),CAST(@someGuid AS BINARY(16)),1) binValue_HexString
FOR XML PATH('test');
结果
<test>
<TheGuid>67D4B263-CEDC-4164-AA32-B7F8F6DCA946</TheGuid>
<binValue_Base64>Y7LUZ9zOZEGqMrf49typRg==</binValue_Base64>
<binValue_HexString>0x63B2D467DCCE6441AA32B7</binValue_HexString>
</test>
简而言之:
- 您似乎在谈论 GUID,但以下内容适用于任何其他值。
- GUID 是一种非常特殊的值类型,因为它是二进制但使用其非常特殊的表示格式。
- 在 XML 中,这是一个基于文本的容器,任何值都必须由 可打印字符 表示(好吧,这里不讨论实体...)
- 将 GUID 转换为 BINARY(16) 将导致 XML.
中的 Base64 编码值
- 但是您可以使用
CONVERT()
将 BINARY 转换为 VARCHAR,这将生成 HEX 字符串 Read the section binary styles for details)
两个 string 值都可以重新转换为原始 GUID (67D4B263-CEDC-4164-AA32-B7F8F6DCA946
):
DECLARE @base64 VARCHAR(25)='Y7LUZ9zOZEGqMrf49typRg==';
SELECT CAST(@base64 AS xml).value('.','binary(16)') Base64_as_binary
,CAST(CAST(@base64 AS xml).value('.','binary(16)') AS UNIQUEIDENTIFIER) TheOriginalGuid
DECLARE @HexString VARCHAR(25)='0x63B2D467DCCE6441AA32B7';
SELECT CONVERT(BINARY(16),@HexString,1) Hex_as_binary
,CAST(CONVERT(BINARY(16),@HexString,1) AS UNIQUEIDENTIFIER) TheOriginalGuid
我试图在 XML 文件中为我的 XSLT 项目获取 binary(16)
以对其进行转换。
这是我尝试过的:
SELECT BINARY_ID FROM dbo.MyTable
SELECT CONVERT(varbinary(16), BINARY_ID) AS BINARY_ID FROM dbo.MyTable
SELECT CAST(BINARY_ID AS varbinary(20)) AS BINARY_ID FROM dbo.MyTable
SELECT CONVERT(BINARY(16), BINARY_ID) AS BINARY_ID FROM dbo.MyTable
SELECT CAST(BINARY_ID AS binary(20)) AS BINARY_ID FROM dbo.MyTable
无论我怎样尝试,我的 BINARY_ID
从 0x00D25E18AEFF4979A244C2EB132791C1
变成了 ANJeGK7/SXmiRMLrEyeRwQ==
我正在使用 JDBC 连接器进行连接并从数据库中获取数据。
我开始不知道我的问题是什么原因造成的。
我的项目是否可行,或者我是否必须将其与其他项目结合起来才能实现?
在此先感谢您的帮助。
更新
这是我的 XSLT 脚本,它通过 Java 编译器进入 JDBC 连接器
<?xml version="1.0" encoding="UTF-8"?>
<xsl:output media-type="text/xml" method="xml"></xsl:output>
<xsl:template match="/">
<root>
<statement format="yyyy-MM-dd' 'hh:mm" resulttag="object_II" timezone="UTC">
<sql>
SELECT
AD.GGUID,
AD.COMPNAME AS Firmen_Name_1,
AD.COMPNAME2 AS Firmen_Name_2,
AD.GWBRANCH AS Branche,
AD.COUNTRY1 AS Land,
AD.STREET1 AS Straße,
AD.ZIP1 AS PLZ,
AD.TOWN1 AS Ort,
AD.GWSTATE1 AS Bundesland,
AD.PHONEFIELDSTR10 AS Telefon_Nr,
AD.MAILFIELDSTR5 AS EMail
FROM dbo.TABLE_I AS CL
inner join dbo.TABLE_II AS AD ON AD.GGUID = CL.TABLEGUID
Where CL.TABLENAME = 'ADDRESS'
AND CL.FIELDNAME = 'CHECKBOX'
AND AD.CHECKBOX= 1
AND AD.UPDATETIMESTAMP BETWEEN DATEADD(MINUTE, -60, SYSDATETIME()) AND SYSDATETIME()
Order BY ad.GGUID DESC
</sql>
</statement>
</root>
</xsl:template>
</xsl:stylesheet>
我使用主函数 varbintohexstr 自行修复了它
这是我完整的 MSSQL 语句。
SELECT
UPPER(master.sys.fn_varbintohexstr(AD.GGUID)) AS GGUID,
FROM dbo.TABLE_I AS CL
inner join dbo.TABLE_II AS AD ON AD.GGUID = CL.TABLEGUID
Where CL.TABLENAME = 'ADDRESS'
AND CL.FIELDNAME = 'Checkbox'
AND AD.Checkbox = 1
AND AD.UPDATETIMESTAMP BETWEEN DATEADD(MINUTE, -960, SYSDATETIME()) AND SYSDATETIME()
Order BY ad.GGUID DESC
结果:
0X00D25E18AEFF4979A244C2EB132791C1
提示:功能varbintohexstring()
是有限的...我在这里使用CONVERT()
。
一开始,十六进制字符串是在 XML 中嵌入二进制文件的默认格式。在 v2005 中,这已更改为 Base64,因为它可以表示字符较少的二进制值。
试试这个:
DECLARE @someGuid UNIQUEIDENTIFIER = NEWID();
SELECT @someGuid AS TheGuid
,CAST(@someGuid AS BINARY(16)) binValue_Base64
,CONVERT(VARCHAR(25),CAST(@someGuid AS BINARY(16)),1) binValue_HexString
FOR XML PATH('test');
结果
<test>
<TheGuid>67D4B263-CEDC-4164-AA32-B7F8F6DCA946</TheGuid>
<binValue_Base64>Y7LUZ9zOZEGqMrf49typRg==</binValue_Base64>
<binValue_HexString>0x63B2D467DCCE6441AA32B7</binValue_HexString>
</test>
简而言之:
- 您似乎在谈论 GUID,但以下内容适用于任何其他值。
- GUID 是一种非常特殊的值类型,因为它是二进制但使用其非常特殊的表示格式。
- 在 XML 中,这是一个基于文本的容器,任何值都必须由 可打印字符 表示(好吧,这里不讨论实体...)
- 将 GUID 转换为 BINARY(16) 将导致 XML. 中的 Base64 编码值
- 但是您可以使用
CONVERT()
将 BINARY 转换为 VARCHAR,这将生成 HEX 字符串 Read the section binary styles for details)
两个 string 值都可以重新转换为原始 GUID (67D4B263-CEDC-4164-AA32-B7F8F6DCA946
):
DECLARE @base64 VARCHAR(25)='Y7LUZ9zOZEGqMrf49typRg==';
SELECT CAST(@base64 AS xml).value('.','binary(16)') Base64_as_binary
,CAST(CAST(@base64 AS xml).value('.','binary(16)') AS UNIQUEIDENTIFIER) TheOriginalGuid
DECLARE @HexString VARCHAR(25)='0x63B2D467DCCE6441AA32B7';
SELECT CONVERT(BINARY(16),@HexString,1) Hex_as_binary
,CAST(CONVERT(BINARY(16),@HexString,1) AS UNIQUEIDENTIFIER) TheOriginalGuid