sql >> Databasteknik >  >> RDS >> Sqlserver

FÖR XML PATH i SQL-server och [text()]

De andra aktuella svaren förklarar inte mycket om var detta kommer ifrån, eller erbjuder bara länkar till dåligt formaterade webbplatser och svarar inte riktigt på frågan.

I många svar på webben för att gruppera strängar finns copy paste-svaren utan en massa förklaringar av vad som händer. Jag ville bättre svara på den här frågan eftersom jag undrade samma sak, och även ge insikt i vad som faktiskt händer överlag.

tldr;

Kort sagt, detta är syntax för att hjälpa till att transformera XML-utdata när du använder FOR XML PATH som använder kolumnnamn (eller alias) för att strukturera utdata. Om du namnger din kolumn text() data kommer att representeras som text i root-taggen.

<row>
    My record's data
<row>

I exemplen du ser online för hur man grupperar strängar och sammanfogar med , det kanske inte är uppenbart (förutom det faktum att din fråga har så lite for xml del) att du faktiskt bygger en XML-fil med en specifik struktur (eller snarare, brist på struktur) genom att använda FOR XML PATH ('') . ('') tar bort xml-root-taggarna och spottar bara ut data.

Affären med AS [text()]

Som vanligt, AS agerar för att namnge eller byta namn på kolumnaliaset. I det här exemplet aliasar du denna kolumn som [text()] . [] s är helt enkelt SQL Servers standardkolumnavgränsare, ofta onödiga, förutom idag eftersom vårt kolumnnamn har () s. Det lämnar oss med text() för vårt kolumnnamn.

Styra XML-strukturen med kolumnnamn

När du använder FOR XML PATH du matar ut en XML-fil och kan styra strukturen med dina kolumnnamn. En detaljerad lista över alternativ finns här:https://msdn.microsoft .com/en-us/library/ms189885.aspx

Ett exempel inkluderar att börja ditt kolumnnamn med ett @-tecken, till exempel:

SELECT color as '@color', name
FROM #favorite_colors
FOR XML PATH

Detta skulle flytta denna kolumns data till ett attribut för den aktuella xml-raden, i motsats till ett objekt i den. Du slutar med

<row color="red">
  <name>tim</name>
</row>
<row color="blue">
  <name>that guy</name>
</row>

Så tillbaka till [text()] . Detta anger faktiskt ett XPath-nodtest . I samband med MS SQL Server kan du lära dig om denna beteckning här . I grund och botten hjälper det att bestämma vilken typ av element vi lägger till denna data till, till exempel en normal nod (standard), en xml-kommentar eller i det här exemplet någon text i taggen.

Ett exempel som använder några få drag för att strukturera utdata

SELECT 
  color as [@color]
  ,'Some info about ' + name AS [text()]
  ,name + ' likes ' + color AS [comment()]
  ,name
  ,name + ' has some ' + color + ' things' AS [info/text()]
FROM #favorite_colors
FOR XML PATH

Observera att vi använder några beteckningar i våra kolumnnamn:

  • @color :ett taggattribut
  • text() :lite text för denna rottagg
  • comment() :en xml-kommentar
  • info/text() :lite text i en specifik xml-tagg, <info>

Utdatan ser ut så här:

<row color="red">
    Some info about tim
    <!--tim likes red-->
    <name>tim</name>
    <info>tim has some red things</info>
</row>
<row color="blue">
    Some info about that guy
    <!--that guy likes blue-->
    <name>that guy</name>
    <info>that guy has some blue things</info>
</row>

Att sammanfatta det, hur kan dessa verktyg gruppera och sammanfoga strängar?

Så med de lösningar vi ser för att gruppera strängar tillsammans med FOR XML PATH , det finns två nyckelkomponenter.

  • AS [text()] :Skriver data som text, istället för att slå in den i en tagg
  • FOR XML PATH ('') :Byter namn på rottaggen till '' , eller snarare, tar bort det helt

Detta ger oss "XML" (luftcitattecken) utdata som i huvudsak bara är en sträng.

SELECT name + ', ' AS [text()] -- no 'name' tags
FROM #favorite_colors
FOR XML PATH ('')  -- no root tag

returnerar

tim, that guy, 

Därifrån är det bara en fråga om att sammanfoga den datan tillbaka till den större datamängden som den kom från.



  1. Distribuerar MySQL Galera Cluster 4.0 på Amazon AWS EC2

  2. Ta bort-knappen fungerar inte i CodeIgniter

  3. fe_sendauth:inget lösenord angett fel i postgresql + laravel

  4. Hur TO_SECONDS() fungerar i MariaDB