De eenvoudigste manier om het uit te leggen is door te kijken hoe FOR XML PATH
werkt voor echte XML. Stel je een eenvoudige tabel voor Employee
:
EmployeeID Name
1 John Smith
2 Jane Doe
Je zou kunnen gebruiken
SELECT EmployeeID, Name
FROM emp.Employee
FOR XML PATH ('Employee')
Dit zou XML als volgt creëren
<Employee>
<EmployeeID>1</EmployeeID>
<Name>John Smith</Name>
</Employee>
<Employee>
<EmployeeID>2</EmployeeID>
<Name>Jane Doe</Name>
</Employee>
De 'Werknemer' verwijderen uit PATH
verwijdert de buitenste xml-tags, dus deze vraag:
SELECT Name
FROM Employee
FOR XML PATH ('')
Zou creëren
<Name>John Smith</Name>
<Name>Jane Doe</Name>
Wat je dan doet is niet ideaal, de kolomnaam 'data()' forceert een sql-fout omdat het probeert een xml-tag te maken die geen legale tag is, dus de volgende fout wordt gegenereerd:
Kolomnaam 'Data()' bevat een ongeldige XML-identificatie zoals vereist door FOR XML; '('(0x0028) is het eerste teken met een fout.
De gecorreleerde subquery verbergt deze fout en genereert alleen de XML zonder tags:
SELECT Name AS [Data()]
FROM Employee
FOR XML PATH ('')
maakt
John Smith Jane Doe
Je vervangt dan spaties door komma's, redelijk duidelijk...
Als ik jou was zou ik de vraag iets aanpassen:
SELECT E1.deptno,
STUFF(( SELECT ', ' + E2.ename
FROM emp AS e2
WHERE e1.deptno = e2.DEPTNO
FOR XML PATH('')
), 1, 2, '')
FROM EMP AS e1
GROUP BY DEPTNO;
Als er geen kolomalias is, worden er geen xml-tags gemaakt, en het toevoegen van de komma in de select-query betekent dat namen met spaties er geen fouten in zullen veroorzaken,STUFF
verwijdert de eerste komma en spatie.
TOEVOEGEN
Om in te gaan op wat KM in een opmerking heeft gezegd, aangezien dit een paar meer views lijkt te krijgen, is de juiste manier om XML-tekens te ontwijken het gebruik van .value
als volgt:
SELECT E1.deptno,
STUFF(( SELECT ', ' + E2.ename
FROM emp AS e2
WHERE e1.deptno = e2.DEPTNO
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM EMP AS e1
GROUP BY DEPTNO;