如何在不转义特殊字符的情况下在查询中使用FOR XML PATH('')?

时间:2014-04-17 17:52:30

标签: sql sql-server tsql escaping for-xml-path

我有这个问题:

SELECT DISTINCT
            f.CourseEventKey,
            (
                SELECT      f.Title + '; ' AS [text()]
                FROM        @Facilities
                WHERE       CourseEventKey = f.CourseEventKey
                ORDER BY    f.Title
                FOR XML PATH('')
            ) Facilities
FROM        @Facilities f

它产生这个结果集:

CourseEventKey Facilities
-------------- -----------------------------------
29             Test Facility 1; 
30             Memphis Training Room; 
32             Drury Inn & Suites Creve Coeur;

数据很好,但&实际上是编码&,不适合我的目的。

如何修改此查询以返回数据中特殊字符的原始值?

3 个答案:

答案 0 :(得分:9)

使用,TYPE).value('.','NVARCHAR(MAX)'),您的特殊字符不会被转义:

SELECT DISTINCT
            f.CourseEventKey,
            (
                SELECT      f.Title + '; ' AS [text()]
                FROM        @Facilities
                WHERE       CourseEventKey = f.CourseEventKey
                ORDER BY    f.Title
                FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)')
            AS Facilities
FROM        @Facilities f

归功于Rob Farley

<强>更新
我刚刚听说过这种新方法。我尚未彻底测试它,并会感谢任何反馈。我们可以将[text()]替换为[processing-instruction(x)],就像这样

select 'hello & there >' as [processing-instruction(x)] FOR XML PATH('')

将返回

<?x hello & there >?>

我们只需要剥离<? ... ?>

答案 1 :(得分:2)

我认为您将不得不使用REPLACE语句手动包装Facilities inline查询块以反转自动转义。

听起来你想要做的就是连接可以呈现给定课程的多个设施。你考虑过其他选择吗? This question有几种可能的方法,不会出现转义角色的问题。

答案 2 :(得分:1)

除了@Baodad提供的最新解决方案之外,只需REPLACE<? ... ?>

SELECT DISTINCT
        f.CourseEventKey,
        REPLACE(
        REPLACE(
                (
                SELECT f.Title + '; ' AS [processing-instruction(x)]
                FROM Facilities
                WHERE CourseEventKey = f.CourseEventKey
                ORDER BY f.Title
                FOR XML PATH('')
                )
                , '<?x','')
                , '?>','') Facilities
FROM Facilities f`

您的输出将是:

| CourseEventKey |                                 Facilities |
|----------------|--------------------------------------------|
|             29 |        Test Facility 1;  Test Facility 1;  |
|             29 |      Test Facility 33;  Test Facility 33;  |
|             30 |                    Memphis Training Room;  |
|             31 |                            Another place;  |
|             32 |  Drury Inn & Suites;  Drury Inn & Suites;  |
|             32 |    Yet Another place;  Yet Another place;  |

之所以可行,是因为最终输出不是XML格式的,否则REPLACE根本无法工作,因为字符将保持编码状态。