在FOR XML SELECT中使用CHAR(13)

Cas*_*ton 6 sql t-sql for-xml sql-server-2008

我正在尝试使用CHAR(13)强制换行,但问题是,我在FOR XML Select语句中这样做:

SELECT 
    STUFF((SELECT CHAR(13) + Comment 
FROM 
   myTable 
FOR XML PATH ('')) , 1, 1, '')
Run Code Online (Sandbox Code Playgroud)

这个问题是,我没有得到一个真正的新行.相反,我得到:

#x0D;
Run Code Online (Sandbox Code Playgroud)

所以数据字面上看起来像这样:

#x0D;First Line of Data#x0D;Second Line of Data#x0D;Etc
Run Code Online (Sandbox Code Playgroud)

所以我试着替换#x0D; 在FOR XML之外使用CHAR(13):

REPLACE(SELECT 
    STUFF((SELECT CHAR(13) + Comment 
FROM 
   myTable 
FOR XML PATH ('')) , 1, 1, '')), '#x0D;', CHAR(13))
Run Code Online (Sandbox Code Playgroud)

这让我很亲近.它会添加换行符,但它还包括每行末尾的&,以及第一行后的每行的开头:

First Line of Data&
&Second Line of Data&
&Etc
Run Code Online (Sandbox Code Playgroud)

Shn*_*ugo 5

您的方法不是真正的 XML

用“输出到文本”试试这个:

DECLARE @tbl TABLE(TestText VARCHAR(100));
INSERT INTO @tbl VALUES('line 1'),('line 2'),('line 3');

SELECT STUFF
(
    (
        SELECT CHAR(10) + tbl.TestText
        FROM @tbl AS tbl
        FOR XML PATH('')
    ),1,1,''
)
Run Code Online (Sandbox Code Playgroud)

CHAR(13)

#x0D;line 1
line 2
line 3
Run Code Online (Sandbox Code Playgroud)

看到你STUFF刚刚拿走了&符号?

CHAR(10)

line 1
line 2
line 3
Run Code Online (Sandbox Code Playgroud)

但你真正需要的是:

SELECT STUFF
(
    (
        SELECT CHAR(10) + tbl.TestText --you might use 13 and 10 here
        FROM @tbl AS tbl
        FOR XML PATH(''),TYPE
    ).value('.','nvarchar(max)'),1,1,''
)
Run Code Online (Sandbox Code Playgroud)

,TYPE会返回真正的XML,并与.value()你读这个正确。

一些背景

你有一个误解“所以数据看起来像这样”

它没有“这个样子的”,它逃脱,以适应这些规则的XML。当您正确阅读它时,它将被隐式编码。

而且您对换行符有误解:

在(几乎)古代,您需要CR = Carriage Return, 13 or x0D将打印滑板移回,另外还需要LF = Line Feed, 10 or x0A转动压板来移动纸张。因此,广泛使用需要用两个字符(13/10 或 0D/0A)编码的换行符。

今天 ASCII 10 (0A) 经常单独出现......

但回到你的实际问题:你为什么要关心你的数据的外观?在 XML 中,某些字符串可能看起来很难看,但是 -如果您正确阅读了这个- 解码回原始外观是隐式完成的......

您的残基不只是编码的一部分,因为它以与号开头并以分号结尾:≶ 或
。您尝试替换它只是要短一个字符。但无论如何:你不应该这样做!

你试一试:

SELECT CAST('<x>&#x48;&#x65;&#x6c;&#x6c;&#x6f;</x>' AS XML).value('/x[1]','nvarchar(max)')
Run Code Online (Sandbox Code Playgroud)


use*_*704 5

感谢大家的帮助。

此处的最终目标是将 Excel 中的数据作为报告的一部分呈现。我确信有一种更优雅的方法可以做到这一点,但我至少通过这样做得到了我想要的结果:

REPLACE (
    REPLACE(
        REPLACE(
            (SELECT Comment FROM CallNotes WHERE ForeignId = a.ForeignId FOR XML PATH (''))
        , '<Comment>', '')  
    , '</Comment>', CHAR(13) + CHAR(10))
, '&#x0D;', '') AS Comments
Run Code Online (Sandbox Code Playgroud)

正如我们所期望的,select 语句本身会返回 XML:

<comment>This is a comment</comment><comment>This is another comment</comment>
Run Code Online (Sandbox Code Playgroud)

最里面的 REPLACE 只是去掉了开始标签:

<comment> 
Run Code Online (Sandbox Code Playgroud)

中间的 REPLACE 删除了结束标记:

</comment> 
Run Code Online (Sandbox Code Playgroud)

并将其替换为 CHAR(13) + CHAR(10)。而最外面的 REPLACE 去掉了这个:

&#x0D;  
Run Code Online (Sandbox Code Playgroud)

(我仍然不明白这是从哪里来的。)

因此,当结果发送到 Excel 时,它在单元格内看起来像这样:

This is a comment.
This is another comment.
Run Code Online (Sandbox Code Playgroud)

这正是我想要的。同样,我相信有更好的解决方案。但这至少目前是有效的。