Cách đơn giản nhất để giải thích nó là xem cách FOR XML PATH
hoạt động cho XML thực tế. Hãy tưởng tượng một bảng đơn giản Employee
:
EmployeeID Name
1 John Smith
2 Jane Doe
Bạn có thể sử dụng
SELECT EmployeeID, Name
FROM emp.Employee
FOR XML PATH ('Employee')
Điều này sẽ tạo ra XML như sau
<Employee>
<EmployeeID>1</EmployeeID>
<Name>John Smith</Name>
</Employee>
<Employee>
<EmployeeID>2</EmployeeID>
<Name>Jane Doe</Name>
</Employee>
Xóa 'Nhân viên' khỏi PATH
loại bỏ các thẻ xml bên ngoài để truy vấn này:
SELECT Name
FROM Employee
FOR XML PATH ('')
Sẽ tạo
<Name>John Smith</Name>
<Name>Jane Doe</Name>
Những gì bạn đang làm sau đó không phải là lý tưởng, tên cột 'data ()' tạo ra lỗi sql vì nó đang cố tạo thẻ xml không phải là thẻ hợp pháp, do đó, lỗi sau được tạo ra:
Tên cột 'Dữ liệu ()' chứa mã định danh XML không hợp lệ theo yêu cầu của FOR XML; '(' (0x0028) là ký tự đầu tiên bị lỗi.
Truy vấn con tương quan ẩn lỗi này và chỉ tạo XML không có thẻ:
SELECT Name AS [Data()]
FROM Employee
FOR XML PATH ('')
tạo
John Smith Jane Doe
Sau đó, bạn thay thế khoảng trắng bằng dấu phẩy, khá tự giải thích ...
Nếu tôi là bạn, tôi sẽ điều chỉnh truy vấn một chút:
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;
Không có bí danh cột sẽ có nghĩa là không có thẻ xml nào được tạo và việc thêm dấu phẩy trong truy vấn chọn có nghĩa là bất kỳ tên nào có dấu cách sẽ không gây ra lỗi, STUFF
sẽ xóa dấu phẩy và dấu cách đầu tiên.
BỔ SUNG
Để giải thích kỹ hơn những gì KM đã nói trong một nhận xét, vì điều này dường như nhận được nhiều lượt xem hơn, nên cách chính xác để thoát các ký tự XML là sử dụng .value
như sau:
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;