2011-12-13 8 views
5

No es capaz de conseguir la salida XML deseadaTSQL FOR XML EXPLICIT

la siguiente:

SELECT 1 as Tag, 
      0 as Parent, 
      sID  as [Document!1!sID], 
      docID  as [Document!1!docID], 
      null  as [To!2!value] 
    FROM docSVsys with (nolock) 
    where docSVsys.sID = '57' 
    UNION ALL 
    SELECT 2 as Tag, 
     1 as Parent, 
     sID, 
     NULL, 
     value   
    FROM docMVtext 
    WHERE docMVtext.sID = '57' 
    ORDER BY [Document!1!sID],[To!2!value] 
    FOR XML EXPLICIT; 

Produce:

<Document sID="57" docID="3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA"> 
     <To value="Frank Ermis" /> 
     <To value="Keith Holst" /> 
     <To value="Mike Grigsby" /> 
    </Document> 

Lo que quiero es:

<Document sID="57"> 
     <docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA</docID> 
     <To> 
     <Value>Frank Ermis</Value> 
     <Value>Keith Holst</Value> 
     <Value>Mike Grigsby</Value> 
     </To> 
    </Document> 

¿Puedo obtener esa salida con FOR XML?

Ok, entiendo que pueden ser técnicamente equivalentes.
Lo que quiero y lo que necesito no es lo mismo.

Usar xDocument para esto es LENTO.
Hay millones de documentos y necesita XML hasta 1 millón a la vez en XML.
El TSQL FOR XML es superrápido.
Solo necesito obtener FOR XML para formatear.

La solución (basada en respuesta aceptada):

SELECT top 4 
    [sv].[sID] AS '@sID' 
    ,[sv].[sParID] AS '@sParID' 
    ,[sv].[docID] AS 'docID' 
    ,[sv].addDate as 'addDate' 
    ,(SELECT [value] AS 'value' 
     FROM [docMVtext] as [mv] 
     WHERE [mv].[sID] = [sv].[sID] 
     AND [mv].[fieldID] = '113' 
     ORDER BY [mv].[value] 
     FOR XML PATH (''), type 
    ) AS "To" 
    ,(SELECT [value] AS 'value' 
     FROM [docMVtext] as [mv] 
     WHERE [mv].[sID] = [sv].[sID] 
     AND [mv].[fieldID] = '130' 
     ORDER BY [mv].[value] 
     FOR XML PATH (''), type 
    ) AS "MVtest" 
    FROM [docSVsys] as [sv] 
    WHERE [sv].[sID] >= '57' 
    ORDER BY 
     [sv].[sParID], [sv].[sID] 
    FOR XML PATH('Document'), root('Documents') 

Produce:

<Documents> 
    <Document sID="57" sParID="57"> 
    <docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA</docID> 
    <addDate>2011-10-28T12:26:00</addDate> 
    <To> 
     <value>Frank Ermis</value> 
     <value>Keith Holst</value> 
     <value>Mike Grigsby</value> 
    </To> 
    <MVtest> 
     <value>MV test 01</value> 
     <value>MV test 02</value> 
     <value>MV test 03</value> 
     <value>MV test 04</value> 
    </MVtest> 
    </Document> 
    <Document sID="58" sParID="57"> 
    <docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA.1</docID> 
    <addDate>2011-10-28T12:26:00</addDate> 
    </Document> 
    <Document sID="59" sParID="59"> 
    <docID>3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA</docID> 
    <addDate>2011-10-28T12:26:00</addDate> 
    <To> 
     <value>Vladimir Gorny</value> 
    </To> 
    </Document> 
    <Document sID="60" sParID="59"> 
    <docID>3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA.1</docID> 
    <addDate>2011-10-28T12:26:00</addDate> 
    </Document> 
</Documents> 

Ahora lo que tengo que hacer es añadir un atributo al elemento DispName MVtext. El atributo no puede tener espacios y me gustaría incluir el nombre descriptivo, p. Ej. Texto de valor múltiple

+4

Nunca debe usar FOR XML EXPLICIT. Es una pesadilla. Está utilizando SQL Server 2008, entonces use "FOR XML PATH" en su lugar. –

+0

@JohnSaunders OK John, dame una pista. Me cansé XML PATH y no llegué a ningún lado. – Paparazzi

+0

[Sugerencia] (http://msdn.microsoft.com/en-us/library/ms189885.aspx) –

Respuesta

3

Pruebe algo como esto (no probado, ya que no tengo las tablas de base de datos para poner a prueba contra ...):

SELECT 
    sv.sID AS '@sID', 
    sv.docID AS 'docID', 
    (SELECT 
     value AS 'value' 
     FROM 
     dbo.docMVtext mv 
     WHERE 
     mv.sID = sv.sID 
     ORDER BY mv.value 
     FOR XML PATH (''), TYPE) AS 'To'  
    FROM 
     dbo.docSVsys sv 
    WHERE 
     sv.sID = '57' 
    ORDER BY 
     sv.sID 
    FOR XML PATH('Document') 

¿Eso le da lo ¿¿estas buscando?? Y no está de acuerdo con John y conmigo: esto es mucho más simple que FOR XML EXPLICIT .....

+0

Todo es difícil cuando no está funcionando. Tu código estaba cerca. Solo falta una coma al final de la tercera línea. Tengo una publicación relacionada ahora sobre cómo obtener un atributo de valor único en 'Para' – Paparazzi

+0

Oh, estuve casi allí antes de publicar esta pregunta. Me faltaba el ", TIPO". – Paparazzi

2

De Examples: Using PATH Mode:

USE AdventureWorks2008R2; 
GO 
SELECT ProductModelID AS "@ProductModelID", 
     Name AS "@ProductModelName", 
     (SELECT ProductID AS "data()" 
     FROM Production.Product 
     WHERE Production.Product.ProductModelID = 
       Production.ProductModel.ProductModelID 
     FOR XML PATH ('') 
     ) AS "@ProductIDs", 
     (
     SELECT Name AS "ProductName" 
     FROM Production.Product 
     WHERE Production.Product.ProductModelID = 
       Production.ProductModel.ProductModelID 
     FOR XML PATH (''), type 
     ) AS "ProductNames" 

FROM Production.ProductModel 
WHERE ProductModelID= 7 OR ProductModelID=9 
FOR XML PATH('ProductModelData');