在 FOR XML SELECT 中使用 CHAR(13)

Using CHAR(13) in a FOR XML SELECT

我正在尝试使用 CHAR(13) 强制换行,但问题是,我在 FOR XML Select 语句中执行此操作:

SELECT 
    STUFF((SELECT CHAR(13) + Comment 
FROM 
   myTable 
FOR XML PATH ('')) , 1, 1, '')

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

#x0D;

所以数据看起来像这样:

#x0D;First Line of Data#x0D;Second Line of Data#x0D;Etc

所以我试着只替换#x0D;在 FOR XML:

之外使用 CHAR(13)
REPLACE(SELECT 
    STUFF((SELECT CHAR(13) + Comment 
FROM 
   myTable 
FOR XML PATH ('')) , 1, 1, '')), '#x0D;', CHAR(13))

这让我很接近。它确实添加了换行符,但它还在每一行的末尾包含一个 &,并且在第一行之后的每一行的开头:

First Line of Data&
&Second Line of Data&
&Etc

如果您使用以下查询和结果转文本选项,您将看到换行符。使用结果网格功能无法显示换行符。

SELECT 
    STUFF((SELECT CHAR(10) + Comment 
FROM 
   myTable 
FOR XML PATH ('')) , 1, 1, '')

我想既然你需要在 FK 上分组,你可以使用这样的东西......只需将#TempT 替换为你的table......

Select Pri.ForeignKey,
       Replace(Left(Pri.Notes,Len(Pri.Notes)-1),',',CHAR(13)) As Notes
From
    (
        Select distinct T2.ForeignKey, 
            (
                Select T1.Note + ',' AS [text()]
                From #TempT T1
                Where T1.ForeignKey = T2.ForeignKey
                ORDER BY T1.ForeignKey
                For XML PATH ('')
            ) Notes
        From #TempT T2
    ) Pri

同样在您在评论中列出的 OP 中,您有一个重复的主键。我觉得很奇怪。只是提醒一下。

我建议 Comment + Char(10) + Char(13)

"Carriage Return" "Line feed" 应该在行尾。

你的方法不真实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,''
)

CHAR(13)

#x0D;line 1
line 2
line 3

看到你的STUFF刚刚去掉了符号吗?

CHAR(10)

line 1
line 2
line 3

但你真正需要的是:

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,''
)

,TYPE 将 return 真实 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)')

感谢大家的帮助。

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

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

select 语句本身 returns XML 正如我们所期望的:

<comment>This is a comment</comment><comment>This is another comment</comment>

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

<comment> 

中间REPLACE去掉结束标签:

</comment> 

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

&#x0D;  

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

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

This is a comment.
This is another comment.

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

我觉得这样更干净。基本上从换行符(或其他一些特殊字符)开始,然后用回车 returns 替换它们,如果需要,再加上换行符。

Select REPLACE(STUFF((SELECT CHAR(10) + Comment 
                      FROM myTable FOR XML PATH ('')) , 1, 1, ''),
              CHAR(10), CHAR(13)+CHAR(10))

我相信这会有所帮助:

REPLACE(STUFF ((SELECT  CHAR(13)+CHAR(10) + Field1 + Field2
    FROM
    ((table
    WHERE
    field3= 'condition1'
    FOR XML PATH ('')), 1, 0, '') , '&#x0D;' , '')