我正在尝试将行转换为逗号分隔的字符串。这是我的表和数据
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)
查询给出以下结果
, <1> - <d>, <2> - <d>, <3> - <d>, <4> - <d>, <5> - <d>, <6> - <d>
因此我添加了.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,因为它会与我的其他查询冲突。 谁能告诉我这个问题的解决方案是什么?
提前致谢。
P.S。 我在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
答案 0 :(得分:1)
根据BOL,XML类型值方法需要设置concat_null_yields_null。如果我想将concat_null_yields_null设置为off我无法使用
FOR XML PATH(''), type).value('(./text())[1]','varchar(max)')
所以我转向一个不太合理的解决方案作为创可贴。我使用replace函数来替换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, '' )
,'"','"'),'&','&'),''',''''),'<','<'),'>','>') auto_products
FROM test tp
GROUP BY tp.a, tp.b
以上解决了我目前的恐慌。任何更好的解决方案仍然是受欢迎的。