【问题标题】:MSSQL Unexpected output of the binary field in XMLMSSQL XML 中二进制字段的意外输出
【发布时间】:2020-06-19 08:58:16
【问题描述】:

我尝试在 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_ID0x00D25E18AEFF4979A244C2EB132791C1 更改为 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>

【问题讨论】:

  • ANJeGK7/SXmiRMLrEyeRwQ== 不是 varbinary 值,因此您的底部 2 个查询无法返回该值。这里的实际问题是什么?什么不工作?示例数据和预期结果将帮助我们为您提供帮助。
  • 我想你误解了我 xD 我在我的数据库中得到了一个二进制 ID,即0x00D25E18AEFF4979A244C2EB132791C1,这就是我想要得到的。但我得到的是 ANJeGK7/SXmiRMLrEyeRwQ==。我还尝试了convert(binary(16)cast(... AS binar(16)) Too mut 没有任何效果......
  • 如果BinaryID 的值为0x00D25E18AEFF4979A244C2EB132791C,那么SELECT BinaryID 将返回该值... 至于CONVERT(varbinary(16), binaryID)binaryID 已经是binary 值(其中我假设它是基于它的名称和缺乏信息,否则)然后CONVERT 将什么也不做。 binary 不可能返回值 'ANJeGK7/SXmiRMLrEyeRwQ==',因为这不是 binary 值,而是 (n)varchar
  • 在 MSSQL Studio 上,但不在我的 JDBC 项目中...这就是我的问题,我也使用了不同的二进制 ID,结果是一样的
  • 然后给我们看你项目中的代码,这里的SQL与问题没有任何关系。

标签: sql-server xml tsql xslt mssql-jdbc


【解决方案1】:

提示: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

【讨论】:

  • 这么好,但我现在如何动态使用它?我现在尝试了很多方法,但每次都出错。我试图将 GUID 作为变量然后转换它,但它不适用于 @base64 示例。结果为空。
  • @RyffLe,GGUID的实际数据类型是什么,代表什么?
  • @RyffLe,只是为了证明,你得到的结果(在你的问题中)试试这个:DECLARE @YourBase64 VARCHAR(25)='ANJeGK7/SXmiRMLrEyeRwQ=='; SELECT CAST(@YourBase64 AS XML).value('.','binary(16)')。有多种方法可以在二进制和 base64 之间进行转换...
  • @Ryffle 如果您的GGUID 实际上是binary 类型,那么使用CONVERT(varchar(25),GGUID,1) 来获取十六进制字符串就足够了...
  • 我在我的 XSLT 项目中尝试过,结果与我的问题中的相同。但是CONVERT(varchar(25),GGUID,1) 似乎可以工作:) 谢谢。
【解决方案2】:

我使用主函数 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 2023-03-05
    • 2021-02-06
    • 1970-01-01
    相关资源
    最近更新 更多