Cách đơn giản nhất để giải thích là xem xét cách FOR XML PATH
hoạt động với 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>
Loại bỏ các 'nhân viên' từ PATH
loại bỏ các thẻ xml bên ngoài vì vậy đây truy vấn:
SELECT Name
FROM Employee
FOR XML PATH ('')
có tạo ra
<Name>John Smith</Name>
<Name>Jane Doe</Name>
gì thì bạn đang làm không phải là lý tưởng, 'dữ liệu()' tên cột buộc một lỗi sql vì nó đang cố gắng để tạo ra một thẻ xml mà không phải là một thẻ quy phạm pháp luật, vì vậy lỗi sau được tạo:
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 có lỗi
Các subquery tương quan ẩn lỗi này và chỉ tạo ra XML không có thẻ:.
SELECT Name AS [Data()]
FROM Employee
FOR XML PATH ('')
tạo
John Smith Jane Doe
Bạn sau đó 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 lại 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ó xml thẻ được tạo ra, và thêm dấu phẩy trong truy vấn chọn có nghĩa là bất kỳ tên với khoảng trống trong sẽ không gây ra lỗi, STUFF
sẽ loại bỏ các dấu phẩy đầu tiên và không gian.
PHỤ LỤC
Để xây dựng trên những gì KM đã nói trong một chú thích, vì điều này dường như nhận được một vài quan điểm hơn, cách chính xác để thoát khỏi nhân vật XML sẽ được 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;
** XIN LƯU Ý R YOURNG MÃ CỦA BẠN S FA KHÔNG ĐỐI VỚI TEXT CONTAINING CHARACTERS LIKE><& ** bạn sẽ nhận được ký tự mở rộng như '< ',' > '' & 'có cách tốt hơn để thực hiện việc ghép nối này, xem: http://stackoverflow.com/a/5031297/65223 –