La forma más sencilla de explicarlo es observar cómo funciona FOR XML PATH
para XML real.Imagine una sencilla tabla Employee
:
EmployeeID Name
1 John Smith
2 Jane Doe
Usted podría utilizar
SELECT EmployeeID, Name
FROM emp.Employee
FOR XML PATH ('Employee')
Esto crearía XML de la siguiente manera
<Employee>
<EmployeeID>1</EmployeeID>
<Name>John Smith</Name>
</Employee>
<Employee>
<EmployeeID>2</EmployeeID>
<Name>Jane Doe</Name>
</Employee>
Extracción del 'empleado' de PATH
elimina las etiquetas XML exteriores por lo que este consulta:
SELECT Name
FROM Employee
FOR XML PATH ('')
Crearía
<Name>John Smith</Name>
<Name>Jane Doe</Name>
Lo que se está haciendo no es lo ideal, 'datos()' El nombre de columna obliga a un error de SQL porque está tratando de crear una etiqueta XML que no es una etiqueta legal, por lo se genera el siguiente error:
El nombre de columna 'Data()' contiene un identificador XML no válido como lo requiere FOR XML; '(' (0x0028) es el primer carácter en falta
La consulta correlacionada esconde este error y apenas genera el XML sin etiquetas:.
SELECT Name AS [Data()]
FROM Employee
FOR XML PATH ('')
crea
John Smith Jane Doe
Usted están reemplazando espacios con comas, bastante autoexplicativo ...
Si yo fuera usted, adaptaría la consulta un poco:
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;
Al no tener alias de columna significará sin etiquetas XML son creados, y la adición de la coma dentro de la consulta de selección significa cualquier nombre con espacios en los que no se producirán errores, STUFF
eliminará la primera coma y el espacio.
ADENDA
Para más detalles sobre lo KM ha dicho en un comentario, ya que esto parece ser cada vez un poco más de puntos de vista, la forma correcta de escapar caracteres XML sería utilizar .value
de la siguiente manera:
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;
** Tenga en cuenta que el código se fallan por texto que contiene personajes como><** y obtendrá la expansión personaje como '' <, '>' '' & hay una mejor manera de hacer esto concatenación, vea: http://stackoverflow.com/a/5031297/65223 –