sql >> Database teknologi >  >> RDS >> Sqlserver

Hvad denne forespørgsel gør for at oprette kommasepareret liste SQL Server?

Den enkleste måde at forklare det på er at se på hvordan FOR XML PATH virker til egentlig XML. Forestil dig en simpel tabel Medarbejder :

Medarbejder-ID Navn1 John Smith2 Jane Doe 

Du kan bruge

VÆLG EmployeeID, NameFROM emp.EmployeeFOR XML PATH ('Medarbejder') 

Dette ville skabe XML som følger

 1 John Smith 2 Jane Doe  

Fjernelse af 'Medarbejder' fra PATH fjerner de ydre xml-tags, så denne forespørgsel:

VÆLG NameFROM EmployeeFOR XML PATH ('') 

Ville skabe

 John Smith Jane Doe 

Det du så gør er ikke ideelt, kolonnenavnet 'data()' fremtvinger en sql-fejl, fordi den forsøger at oprette et xml-tag, som ikke er et lovligt tag, så følgende fejl genereres:

Kolonnenavn 'Data()' indeholder en ugyldig XML-id som krævet af FOR XML; '('(0x0028) er det første tegn, der er fejlbehæftet.

Den korrelerede underforespørgsel skjuler denne fejl og genererer blot XML uden tags:

VÆLG navn SOM [Data()]FRA MedarbejderFOR XML-STI ('') 

skaber

John Smith Jane Doe 

Du erstatter så mellemrum med kommaer, ret selvforklarende...

Hvis jeg var dig, ville jeg tilpasse forespørgslen lidt:

SELECT E1.deptno, TING(( SELECT ', ' + E2.ename FROM emp AS e2 WHERE e1.deptno =e2.DEPTNO FOR XML PATH('') ), 1, 2, '') FRA EMP AS e1 GROUP AF DEPTNO;

Hvis du ikke har noget kolonnealias, vil det betyde, at der ikke oprettes xml-tags, og tilføjelse af kommaet i den valgte forespørgsel betyder, at alle navne med mellemrum ikke forårsager fejl,STUFF vil fjerne det første komma og mellemrum.

TILFØJELSE

For at uddybe, hvad KM har sagt i en kommentar, da dette ser ud til at få et par flere visninger, ville den korrekte måde at undslippe XML-tegn være at bruge .value som følger:

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, '') FRA EMP AS e1 GROUP BY DEPTNO;  


  1. Sådan returneres den aktuelle rækkeversionsværdi for en SQL Server-database (T-SQL-eksempel)

  2. 2 måder at returnere kun de numeriske værdier fra en SQLite-databasekolonne

  3. RMAN fejler med RMAN-06900 RMAN-06901 ORA-04031

  4. Kan jeg genbruge et beregnet felt i en SELECT-forespørgsel?