Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Co robi to zapytanie, aby utworzyć listę rozdzielaną przecinkami w programie SQL Server?

Najprostszym sposobem wyjaśnienia tego jest przyjrzenie się, jak FOR XML PATH działa dla rzeczywistego XML. Wyobraź sobie prostą tabelę Employee :

EmployeeID      Name
1               John Smith
2               Jane Doe

Możesz użyć

SELECT  EmployeeID, Name
FROM    emp.Employee
FOR XML PATH ('Employee')

Spowoduje to utworzenie XML w następujący sposób

<Employee>
    <EmployeeID>1</EmployeeID>
    <Name>John Smith</Name>
</Employee>
<Employee>
    <EmployeeID>2</EmployeeID>
    <Name>Jane Doe</Name>
</Employee>

Usuwanie „Pracownika” z PATH usuwa zewnętrzne znaczniki XML, więc to zapytanie:

SELECT  Name
FROM    Employee
FOR XML PATH ('')

Utworzyłby

    <Name>John Smith</Name>
    <Name>Jane Doe</Name>

To, co wtedy robisz, nie jest idealne, nazwa kolumny „data()” wymusza błąd sql, ponieważ próbuje utworzyć znacznik xml, który nie jest prawidłowym znacznikiem, więc generowany jest następujący błąd:

Nazwa kolumny „Data()” zawiera nieprawidłowy identyfikator XML wymagany przez FOR XML; '('(0x0028) to pierwszy znak błędu.

Skorelowane podzapytanie ukrywa ten błąd i po prostu generuje kod XML bez tagów:

SELECT  Name AS [Data()]
FROM    Employee
FOR XML PATH ('')

tworzy

John Smith Jane Doe

Następnie zastępujesz spacje przecinkami, co jest dość oczywiste...

Na Twoim miejscu nieznacznie dostosowałbym zapytanie:

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; 

Brak aliasu kolumny oznacza, że ​​nie są tworzone żadne znaczniki xml, a dodanie przecinka w zapytaniu wybierającym oznacza, że ​​nazwy zawierające spacje nie spowodują błędów,STUFF usunie pierwszy przecinek i spację.

UZUPEŁNIENIE

Aby rozwinąć to, co KM powiedział w komentarzu, ponieważ wydaje się, że uzyskuje się kilka dodatkowych widoków, prawidłowym sposobem ucieczki znaków XML byłoby użycie .value w następujący sposób:

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; 


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL — Odejmowanie wyczerpującej się wartości od wierszy

  2. Kryteria SQL Filter w kryteriach join lub klauzula where, która jest bardziej wydajna

  3. SQLException :ciąg znaków lub dane binarne zostaną obcięte

  4. Jak wstawić rekord z tylko wartościami domyślnymi?

  5. Utwórz zadanie agenta serwera SQL za pomocą programu SSMS