sql >> Database >  >> RDS >> Sqlserver

Wat doet deze query om een ​​door komma's gescheiden lijst van SQL Server te maken?

De eenvoudigste manier om het uit te leggen is door te kijken hoe FOR XML PATH werkt voor echte XML. Stel je een eenvoudige tabel voor Employee :

EmployeeID      Name
1               John Smith
2               Jane Doe

Je zou kunnen gebruiken

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

Dit zou XML als volgt creëren

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

De 'Werknemer' verwijderen uit PATH verwijdert de buitenste xml-tags, dus deze vraag:

SELECT  Name
FROM    Employee
FOR XML PATH ('')

Zou creëren

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

Wat je dan doet is niet ideaal, de kolomnaam 'data()' forceert een sql-fout omdat het probeert een xml-tag te maken die geen legale tag is, dus de volgende fout wordt gegenereerd:

Kolomnaam 'Data()' bevat een ongeldige XML-identificatie zoals vereist door FOR XML; '('(0x0028) is het eerste teken met een fout.

De gecorreleerde subquery verbergt deze fout en genereert alleen de XML zonder tags:

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

maakt

John Smith Jane Doe

Je vervangt dan spaties door komma's, redelijk duidelijk...

Als ik jou was zou ik de vraag iets aanpassen:

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; 

Als er geen kolomalias is, worden er geen xml-tags gemaakt, en het toevoegen van de komma in de select-query betekent dat namen met spaties er geen fouten in zullen veroorzaken,STUFF verwijdert de eerste komma en spatie.

TOEVOEGEN

Om in te gaan op wat KM in een opmerking heeft gezegd, aangezien dit een paar meer views lijkt te krijgen, is de juiste manier om XML-tekens te ontwijken het gebruik van .value als volgt:

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. Hoe de ID van de laatst bijgewerkte rij in MySQL te krijgen?

  2. Preventietriggers

  3. Reguliere expressie (RegEx) voor IPv6 gescheiden van IPv4

  4. WAMP Geen toegang op lokaal netwerk 403 Verboden