2011-03-09 6 views
5

Update para aclararCuando se consulta XML en SQL Server 2005, varias etiquetas del documento se encuentran en la misma fila

Aquí está una copia completa de uno de los archivos xml I "m que tienen problemas con el.

<Grower_Run xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Puller xsi:type="Puller"> 
    <Puller_Number xsi:type="xsd:int">16</Puller_Number> 
    </Puller> 
    <Run_ID xsi:type="xsd:string">SA1611030B</Run_ID> 
    <Crucible xsi:type="Crucible"> 
    <Crucible_Type xsi:type="xsd:string">RWNTYPE</Crucible_Type> 
    <Section> 
     <Grower_Run_Section> 
     <SectionID xsi:type="xsd:string">SA1611030B1</SectionID> 
     <Crystal_Growth> 
      <Growth_StartTime xsi:type="xsd:dateTime">2011-03-01T12:59:30</Growth_StartTime> 
      <Growth_Process> 
      <Growth_Process> 
       <Process_Name xsi:type="xsd:string">BODY</Process_Name> 
       <Single_Moment_Snapshot> 
       <Single_Moment_Snapshot> 
        <Snapshot_Name xsi:type="xsd:string">Body Start</Snapshot_Name> 
        <Snapshot_Datetime xsi:type="xsd:dateTime">2011-03-01T17:11:30</Snapshot_Datetime> 
        <Ingot_Length xsi:type="xsd:decimal">228.19</Ingot_Length> 
        <Heater_Temp xsi:type="xsd:decimal">1337.09</Heater_Temp> 
        <LS_Temp xsi:type="xsd:decimal">1243.00</LS_Temp> 
        <Heater_Power xsi:type="xsd:decimal">56.10</Heater_Power> 
       </Single_Moment_Snapshot> 
       <Single_Moment_Snapshot> 
        <Snapshot_Name xsi:type="xsd:string">Mid Body</Snapshot_Name> 
        <Snapshot_Datetime xsi:type="xsd:dateTime">2011-03-01T17:11:30</Snapshot_Datetime> 
        <Ingot_Length xsi:type="xsd:decimal">228.19</Ingot_Length> 
        <Heater_Temp xsi:type="xsd:decimal">1337.09</Heater_Temp> 
        <LS_Temp xsi:type="xsd:decimal">1243.00</LS_Temp> 
        <Heater_Power xsi:type="xsd:decimal">56.10</Heater_Power> 
       </Single_Moment_Snapshot> 
       <Single_Moment_Snapshot> 
        <Snapshot_Name xsi:type="xsd:string">Tail Start</Snapshot_Name> 
        <Snapshot_Datetime xsi:type="xsd:dateTime">2011-03-02T01:34:24</Snapshot_Datetime> 
        <Ingot_Length xsi:type="xsd:decimal">230.40</Ingot_Length> 
        <Heater_Temp xsi:type="xsd:decimal">1338.20</Heater_Temp> 
        <LS_Temp xsi:type="xsd:decimal">1243.40</LS_Temp> 
        <Heater_Power xsi:type="xsd:decimal">56.39</Heater_Power> 
       </Single_Moment_Snapshot> 
       </Single_Moment_Snapshot> 
      </Growth_Process> 
      </Growth_Process> 
      <Growth_FinishTime xsi:type="xsd:dateTime">2011-03-02T01:35:24</Growth_FinishTime> 
     </Crystal_Growth> 
     </Grower_Run_Section> 
     <Grower_Run_Section> 
     <SectionID xsi:type="xsd:string">SA1611030B9</SectionID> 
     <Crystal_Growth> 
      <Growth_StartTime xsi:type="xsd:dateTime">2011-03-02T04:02:37</Growth_StartTime> 
      <Growth_Process> 
      <Growth_Process> 
       <Process_Name xsi:type="xsd:string">BODY</Process_Name> 
       <Single_Moment_Snapshot> 
       <Single_Moment_Snapshot> 
        <Snapshot_Name xsi:type="xsd:string">Body Start</Snapshot_Name> 
        <Snapshot_Datetime xsi:type="xsd:dateTime">2011-03-02T07:54:39</Snapshot_Datetime> 
        <Ingot_Length xsi:type="xsd:decimal">231.80</Ingot_Length> 
        <Heater_Temp xsi:type="xsd:decimal">1340.00</Heater_Temp> 
        <LS_Temp xsi:type="xsd:decimal">1246.70</LS_Temp> 
        <Heater_Power xsi:type="xsd:decimal">56.60</Heater_Power> 
       </Single_Moment_Snapshot> 
       <Single_Moment_Snapshot> 
        <Snapshot_Name xsi:type="xsd:string">Mid Body</Snapshot_Name> 
        <Snapshot_Datetime xsi:type="xsd:dateTime">2011-03-02T07:54:39</Snapshot_Datetime> 
        <Ingot_Length xsi:type="xsd:decimal">231.80</Ingot_Length> 
        <Heater_Temp xsi:type="xsd:decimal">1340.00</Heater_Temp> 
        <LS_Temp xsi:type="xsd:decimal">1246.70</LS_Temp> 
        <Heater_Power xsi:type="xsd:decimal">56.60</Heater_Power> 
       </Single_Moment_Snapshot> 
       <Single_Moment_Snapshot> 
        <Snapshot_Name xsi:type="xsd:string">Tail Start</Snapshot_Name> 
        <Snapshot_Datetime xsi:type="xsd:dateTime">2011-03-03T06:47:19</Snapshot_Datetime> 
        <Ingot_Length xsi:type="xsd:decimal">1778.00</Ingot_Length> 
        <Heater_Temp xsi:type="xsd:decimal">1388.80</Heater_Temp> 
        <LS_Temp xsi:type="xsd:decimal">1330.70</LS_Temp> 
        <Heater_Power xsi:type="xsd:decimal">63.50</Heater_Power> 
       </Single_Moment_Snapshot> 
       </Single_Moment_Snapshot> 
      </Growth_Process> 
      </Growth_Process> 
      <Growth_FinishTime xsi:type="xsd:dateTime">2011-03-03T06:48:19</Growth_FinishTime> 
     </Crystal_Growth> 
     </Grower_Run_Section> 
    </Section> 
    </Crucible> 
</Grower_Run> 

Ok por lo que se aclare aquí está mi consulta completa.

DECLARE @FILES TABLE(FILENAME VARCHAR(20),DEPTH INT,FILE_FLAG INT) 
DECLARE @XML_TABLE TABLE(
    xmlFileName VARCHAR(300), 
    xml_data xml 
) 
DECLARE @xmlFileName VARCHAR(300) 
DECLARE @FILENAME VARCHAR(20) 

INSERT INTO @FILES 
EXEC Master.dbo.xp_DirTree '\\SASSOAPPSRV\Grower XML Files\',1,1 

DECLARE XML_CURSOR CURSOR FOR SELECT FILENAME FROM @FILES 

OPEN XML_CURSOR 
FETCH NEXT FROM XML_CURSOR 
INTO @FILENAME 

WHILE @@FETCH_STATUS = 0 
BEGIN 

SELECT @xmlFileName = '\\SASSOAPPSRV\Grower XML Files\' + @FILENAME 

INSERT INTO @XML_TABLE(xmlFileName, xml_data) 
EXEC(' 
SELECT ''' + @xmlFileName + ''', xmlData 
FROM 
(
    SELECT * 
    FROM OPENROWSET (BULK ''' + @xmlFileName + ''' , SINGLE_BLOB) AS XMLDATA 
) AS FileImport (XMLDATA) 
') 
FETCH NEXT FROM XML_CURSOR 
INTO @FILENAME 

END 
CLOSE XML_CURSOR 
DEALLOCATE XML_CURSOR 

DECLARE @PARSED_XML TABLE(
S VARCHAR(200), 
RUN_ID VARCHAR(20) 
,SECTION_ID VARCHAR(50) 
) 



INSERT INTO @PARSED_XML 
SELECT 
T.xmlFileName AS S, 
    t.xml_data.value('(/Grower_Run/Run_ID)[1]', 'varchar(50)') AS 'RunID', 
    Section.value('(Grower_Run_Section/SectionID)[1]', 'varchar(50)') as 'SectionID' 
FROM 
    @xml_table t 
CROSS APPLY 
    t.xml_data.nodes('/Grower_Run/Crucible/Section') AS Tmp(Section) 

SELECT 
S 
,RUN_ID 
,SECTION_ID 
FROM @PARSED_XML 
WHERE RUN_ID = 'SA1611030B' 
ORDER BY RUN_ID 

Y este es el resultado que estoy recibiendo.

\\SASSOAPPSRV\Grower XML Files\SA1611030B.xml SA1611030B SA1611030B1 

Este es el problema ya que necesito ver los datos de ambas copias del nodo en filas separadas.


así que tengo muchos documentos XML con la siguiente estructura

<Grower_Run xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Run_ID xsi:type="xsd:string">SA0111023B</Run_ID> 
    <Crucible xsi:type="Crucible"> 
    <Section> 
     <Grower_Run_Section> 
     <SectionID xsi:type="xsd:string">SA0111023B1</SectionID> 
     </Grower_Run_Section> 
    </Section> 
    <Section> 
     <Grower_Run_Section> 
     <SectionID xsi:type="xsd:string">SA0111023B9</SectionID> 
     </Grower_Run_Section> 
    </Section> 
    </Crucible> 
</Grower_Run> 

que he importado en un campo XML de una tabla temporal, que estoy en contra de la consulta con una consulta como éste

SELECT 
    CAST(XML_DATA.query('data(/Grower_Run/Run_ID)') AS VARCHAR(20)) AS [RUN ID] 
    ,CAST(XML_DATA.query('data(/Grower_Run/Crucible/Section/Grower_Run_Section/SectionID)') AS VARCHAR(50)) AS [SECTION ID] 
FROM @XML_TABLE 

El problema es que los resultados de las múltiples instancias de la etiqueta "SectionID" se muestran en la misma fila.

es decir

RunID | SectionID 
-------------------------- 
SA0111023B | SA0111023B1 SA0111023B9 

cuando debería ser

RunID  | SectionID 
----------------------------- 
SA0111023B | SA0111023B1 
SA0111023B | SA0111023B9 

Si tuviera [1] a continuación, final de la consulta xml como este

CAST(XML_DATA.query('data(/Grower_Run/Crucible/Section/Grower_Run_Section/SectionID)')[1] 

caerá la segunda identificación de la sección todos juntos que no funciona porque yo necesito ambos.

¿Algún ayuda?

Respuesta

4

Si desea seleccionar a cabo múltiples "filas" de un documento XML, es necesario utilizar la función de servidor XML .nodes() SQL - algo como esto:

SELECT 
    @XMLTable.value('(/Grower_Run/Run_ID)[1]', 'varchar(50)') AS 'RunID', 
    Section.value('(Grower_Run_Section/SectionID)[1]', 'varchar(50)') as 'SectionID' 
FROM 
    @XMLTable.nodes('/Grower_Run/Crucible/Section') AS Tmp(Section) 

Esa declaración XPath en la cláusula FROM define básicamente una "pseudo-tabla" de elementos XML, basada en esa XPath. De modo que aquí obtendrá una pseudo-tabla para cada entrada <Section> en su XML, desde la cual puede seleccionar elementos individuales usando la función .value().

Si desea seleccionar que a partir de una tabla que contiene una columna de tipo XML, puede que tenga que comprobar en el comando CROSS APPLY:

SELECT 
    t.SomeColumn,   
    t.XmlColumn.value('(/Grower_Run/Run_ID)[1]', 'varchar(50)') AS 'RunID', 
    Section.value('(Grower_Run_Section/SectionID)[1]', 'varchar(50)') as 'SectionID' 
FROM 
    dbo.YourTable t 
CROSS APPLY 
    t.XmlColumn.nodes('/Grower_Run/Crucible/Section') AS Tmp(Section) 
+0

Veo la idea de lo que sugiere aquí, pero estoy teniendo problemas para implementarlo. Al tratar de aplicar la sugerencia superior, recibo un error: debe declarar la variable escalar "@XML_TABLE". Estoy cargando mi xml en una columna de una variable de tabla y luego ejecuto estas consultas fuera de lo que realmente importa. – Neberu

+0

@Neberu: el primer enfoque sería válido si tuviera su XML en una variable de SQL. Si tiene una tabla, debe usar la segunda aproximación –

+0

Gracias, probé la segunda aproximación y está consultando sin errores, pero parece que solo devuelve la primera instancia de los nodos, al igual que poner [1] al fin de la consulta mencionada al final de mi pregunta anterior. – Neberu

1

esto va a funcionar ..., por ejemplo:

pref.value('(OriginatorAgency/text())[1]','varchar(50)'), 
pref.value('(OriginatorAgency/text())[2]','varchar(50)'), 
pref.value('(OriginatorAgency/text())[3]','varchar(50)') 

Si hay 3 artículos OriginatorAgency.

Cuestiones relacionadas