La forma más sencilla de explicarlo es ver cómo FOR XML PATH
funciona para XML real. Imagina una tabla simple Employee
:
EmployeeID Name
1 John Smith
2 Jane Doe
Podrías usar
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>
Eliminando el 'Empleado' de PATH
elimina las etiquetas xml externas, por lo que esta consulta:
SELECT Name
FROM Employee
FOR XML PATH ('')
Crearía
<Name>John Smith</Name>
<Name>Jane Doe</Name>
Lo que está haciendo entonces no es ideal, el nombre de la columna 'data()' fuerza un error de sql porque está tratando de crear una etiqueta xml que no es una etiqueta legal, por lo que se genera el siguiente error:
El nombre de columna 'Data()' contiene un identificador XML no válido según lo requiere FOR XML; '('(0x0028) es el primer carácter que falla.
La subconsulta correlacionada oculta este error y solo genera el XML sin etiquetas:
SELECT Name AS [Data()]
FROM Employee
FOR XML PATH ('')
crea
John Smith Jane Doe
Luego está reemplazando espacios con comas, bastante explicativo...
Si yo fuera usted, adaptaría ligeramente la consulta:
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;
No tener un alias de columna significará que no se crearán etiquetas xml, y agregar la coma dentro de la consulta de selección significa que cualquier nombre con espacios no causará errores, STUFF
eliminará la primera coma y el espacio.
ANEXO
Para profundizar en lo que KM ha dicho en un comentario, ya que parece que esto está recibiendo algunas visitas más, la forma correcta de escapar de los caracteres XML sería usar .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;