結局、私はLievenの2番目の答えを使用しましたが、特定の文字列の組み合わせでは、このFOR XML PATH('')
トリックによって問題が発生することがわかりました。
declare @phrases table
(
id int
,phraseId int
,seqNum int
,word varchar(10)
)
insert
@phrases
values
(1,1,1,'hello'),
(2,1,2,'world'),
(3,2,1,'black'),
(4,2,2,'and'),
(5,2,3,'white')
SELECT
DISTINCT p1.PhraseID,
STUFF(
(
SELECT
' ' + p2.word
FROM
@phrases AS p2
WHERE
p2.PhraseID = p1.PhraseID
FOR XML PATH('')
), 1, 1, '') AS completePhrase
FROM
@phrases AS p1
ORDER BY
p1.PhraseID
正常に動作しますが、例でXMLで使用されている場合にエスケープが必要な文字を使用すると、問題が発生します。たとえば、次のデータを実行します。
insert
@words
values
(1,1,1,'hello>'), --notice the less than symbol
(2,1,2,'world'),
(3,2,1,'black')
与える
hello> world
また、ソーステーブルが順不同で宣言されている場合は、order by
が必要です。
元のクエリに小さなmodを加えると、すべてが修正されます。
SELECT
DISTINCT p1.PhraseID,
STUFF(
(
SELECT
' ' + p2.word
FROM
@words AS p2
WHERE
p2.PhraseID = p1.PhraseID
ORDER BY
p2.seqNum --required
FOR XML PATH(''),TYPE
).value('.','nvarchar(4000)'),
1,
1,
''
) AS completePhrase
FROM
@words AS p1
ORDER BY
p1.PhraseID
(FOR XML PATH(''):「特殊」文字のエスケープを参照してください)