1

我正在尝试将行转换为逗号分隔的字符串。这是我的表格和数据

drop table test
create table test (a int, b int, c varchar(30), d varchar(30))
insert into test values(1,1,'<1>','<d>')
insert into test values(1,1,'<2>','<d>')
insert into test values(1,2,'<3>','<d>')
insert into test values(1,2,'<4>','<d>')
insert into test values(1,3,'<5>','<d>')
insert into test values(1,3,'<6>','<d>')

我期待的结果

, <1> - <d>, <2> - <d>, <3> - <d>, <4> - <d>, <5> - <d>, <6> - <d>

如果我使用

select 
(SELECT ',' + ' ' +ltrim(rtrim(tc.c)) +' - '+ ltrim(rtrim(tc.d))
   FROM  test tc
    FOR XML PATH(''),type)

查询给出以下结果

, &lt;1&gt; - &lt;d&gt;, &lt;2&gt; - &lt;d&gt;, &lt;3&gt; - &lt;d&gt;, &lt;4&gt; - &lt;d&gt;, &lt;5&gt; - &lt;d&gt;, &lt;6&gt; - &lt;d&gt;

因此我添加了 .value 方法如下

select 
(SELECT ',' + ' ' +ltrim(rtrim(tc.c)) +' - '+ ltrim(rtrim(tc.d))
   FROM  test tc
    FOR XML PATH(''),type).value('(./text())[1]','varchar(max)')

这会产生正确的结果。这是我真正的问题:它仅在我设置 CONCAT_NULL_YIELDS_NULL 时才有效。如果我设置 CONCAT_NULL_YIELDS_NULL 关闭 Sql Server 抱怨

"Msg 1934, Level 16, State 1, Line 1
SELECT failed because the following SET options have incorrect settings: 'CONCAT_NULL_YIELDS_NULL'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations."

但我不想设置 CONCAT_NULL_YIELDS_NULL ,因为它会与我的其他查询冲突。谁能告诉我这个问题的解决方案是什么?

提前致谢。

PS我在SO中看到了这个

SELECT @XYList = @XYList + CONVERT(varchar, X) + ',' + CONVERT(varchar, Y) + ','
FROM POINTS

我的要求是建立一个视图。因此我不能使用使用变量的解决方案。

我的最终结果是这样的。

a   b   products
1   1    <1> - <d>, <2> - <d>
1   2    <3> - <d>, <4> - <d>
1   3    <5> - <d>, <6> - <d>

当 CONCAT_NULL_YIELDS_NULL 设置为 on 时由查询产生

SELECT  tp.a, tp.b ,
        STUFF((SELECT ',' + ' ' +ltrim(rtrim(tc.c)) +' - '+ ltrim(rtrim(tc.d))
                 FROM  test tc
                WHERE tp.a = tc.a
                  AND tp.b = tc.b
                  FOR XML PATH(''), type).value('(./text())[1]','varchar(max)'), 1, 1, '' ) products
 FROM test tp
GROUP BY tp.a, tp.b
4

1 回答 1

1

根据 BOL,XML 类型值方法需要将 concat_null_yields_null 设置为 on。如果我想将 concat_null_yields_null 设置为 off,我将无法使用

FOR XML PATH(''), type).value('(./text())[1]','varchar(max)')

所以我求助于一个不太健全的解决方案作为创可贴。我使用替换函数来替换 5 个基本的 XML 预定义实体。查询看起来像这样。

SELECT  tp.a, tp.b ,
        replace(replace(replace(replace(replace(
        STUFF((SELECT ',' + ' ' +ltrim(rtrim(tc.c)) +' - '+ ltrim(rtrim(tc.d))
                 FROM  test tc
                WHERE tp.a = tc.a
                  AND tp.b = tc.b
                  FOR XML PATH('')), 1, 1, '' )
                ,'&quot;','"'),'&amp;','&'),'&apos;',''''),'&lt;','<'),'&gt;','>') auto_products
 FROM test tp
GROUP BY tp.a, tp.b

以上解决了我目前的恐慌。仍然欢迎任何更好的解决方案。

于 2013-11-06T17:37:36.757 回答