Най-простият начин да го обясните е да разгледате как FOR XML PATH
работи за действителен XML. Представете си проста таблица Employee
:
EmployeeID Name
1 John Smith
2 Jane Doe
Можете да използвате
SELECT EmployeeID, Name
FROM emp.Employee
FOR XML PATH ('Employee')
Това ще създаде XML, както следва
<Employee>
<EmployeeID>1</EmployeeID>
<Name>John Smith</Name>
</Employee>
<Employee>
<EmployeeID>2</EmployeeID>
<Name>Jane Doe</Name>
</Employee>
Премахване на „Служител“ от PATH
премахва външните xml тагове, така че тази заявка:
SELECT Name
FROM Employee
FOR XML PATH ('')
Ще създаде
<Name>John Smith</Name>
<Name>Jane Doe</Name>
Това, което правите тогава, не е идеално, името на колоната 'data()' предизвиква sql грешка, защото се опитва да създаде xml маркер, който не е легален, така че се генерира следната грешка:
Името на колоната „Data()“ съдържа невалиден XML идентификатор, както се изисква от FOR XML; '('(0x0028) е първият знак за грешка.
Свързаната подзаявка скрива тази грешка и просто генерира XML без етикети:
SELECT Name AS [Data()]
FROM Employee
FOR XML PATH ('')
създава
John Smith Jane Doe
След това заменяте интервалите със запетаи, доста разбираемо...
Ако бях на твое място, щях да адаптирам леко заявката:
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;
Ако няма псевдоним на колона, това означава, че няма създадени xml тагове, а добавянето на запетая в заявката за избор означава, че всички имена с интервали няма да причиняват грешки,STUFF
ще премахне първата запетая и интервал.
ДОБАВКА
За да уточним какво е казал KM в коментар, тъй като това изглежда получава още няколко изгледа, правилният начин за избягване на XML знаци би бил да използвате .value
както следва:
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;