【问题标题】:How do I avoid character encoding when using "FOR XML PATH"?使用“FOR XML PATH”时如何避免字符编码?
【发布时间】:2013-03-16 15:19:51
【问题描述】:

我希望从 SQL Server 2005 表中创建以逗号分隔的值列表,就像在 JanetOhara's question 中一样。我使用的查询类似于techdo's answer 中提出的查询。

一切正常,除了值列表被 XML 编码。应该是什么:

Sports & Recreation,x >= y

返回为:

Sports & Recreation,x <= y

在 SQL Server 中使用“FOR XML”时,有没有办法禁用 XML 字符编码?

【问题讨论】:

    标签: xml sql-server-2005 encoding for-xml-path


    【解决方案1】:

    您只需要对FOR XML 使用正确的选项。这是避免编码的一种方法:

    USE tempdb;
    GO
    
    CREATE TABLE dbo.x(y nvarchar(255));
    
    INSERT dbo.x SELECT 'Sports & Recreation'
       UNION ALL SELECT 'x >= y'
       UNION ALL SELECT 'blat'
       UNION ALL SELECT '<hooah>';
    
    -- BAD:
    SELECT STUFF((SELECT N',' + y
      FROM dbo.x 
      FOR XML PATH(N'')),1, 1, N'');
    
    -- GOOD:
    SELECT STUFF((SELECT N',' + y
      FROM dbo.x 
      FOR XML PATH, TYPE).value(N'.[1]', N'nvarchar(max)'),1, 1, N'');
    
    GO
    DROP TABLE dbo.x;
    

    如果您使用的是较新版本的 SQL Server (2017+),则可以使用 STRING_AGG() 而完全不用担心 XML:

    SELECT STRING_AGG(y, N',') FROM dbo.x;
    

    db<>fiddle 演示所有三个。

    【讨论】:

    • 添加 type.value('.[1]',nvarchar(max)') 效果很好。感谢您的帮助。
    • TYPE 告诉 SQL 返回实际的 XML,然后你必须“查询”这个 XML 以获得你想要的值这是“.value('.[1]', nvarchar(max)') . 更多信息:technet.microsoft.com/en-us/library/ms190025.aspx
    • 我的字符串中的第一个字符是'
    • @alan 我无法重现该问题。您是否将',' + y 更改为其他内容? STUFF 用于去除第一个字符,除非您以其他方式更改查询,否则它应该是前导逗号。
    • 值得注意的是,我发现value 区分大小写,它无法识别VALUE
    【解决方案2】:

    您也可以这样做:

    -- BAD:
    SELECT STUFF((SELECT N',' + y
    FROM dbo.x 
    FOR XML PATH(N'')),1, 1, N'');
    
    -- GOOD:
    SELECT STUFF((SELECT N',' + y
    FROM dbo.x 
    FOR XML PATH(N''), TYPE).value('(./text())[1]','varchar(max)'),1, 1, N'');
    

    【讨论】:

      【解决方案3】:

      Creating concatenated delimited string from a SQL result set and avoid character encoding when using “FOR XML PATH”上查看此帖子

      另一种方法是依赖字符的连接(当然 sql 不适用于字符串操作,因为它是为使用集合论而开发的)

      USE tempdb;
      GO 
      
      CREATE TABLE dbo.x ( y NVARCHAR(255) );
      INSERT dbo.x
      SELECT 'Sports & Recreation'
      UNION ALL
      SELECT 'x >= y'
      UNION ALL
      SELECT 'blat'
      UNION ALL
      SELECT '<hooah>';
      
      DECLARE @delimitedText varchar(max)
      SET @delimitedText=''
      SELECT @delimitedText += CASE WHEN LEN(@delimitedText) > 0 THEN +','+ y ELSE y END
      FROM dbo.x 
      
      SELECT @delimitedText
      GO
      DROP TABLE dbo.x;
      GO
      

      【讨论】:

        猜你喜欢
        • 2017-03-10
        • 2022-01-07
        • 1970-01-01
        • 2021-09-06
        • 1970-01-01
        • 1970-01-01
        • 2016-06-24
        • 1970-01-01
        相关资源
        最近更新 更多