none
XML RRS feed

  • Pergunta

  • A duvida é bastante simples mas nao encontrei nada de relevante na net... Tenho em uma variavel xml, um xml do tipo:
    a
    Joao
    Pedro
    Maria
    a

    Estou montando uma query dinamica Preciso implementar algo que nao use cursor para pegar esses valores e ir contruindo a query. Eu deixei um xml simples só para exemplificar o problema. Na situação que eu estou nao tem como como contornar muito. Queria com xquery fazer algo do tipo: while(node <> null) @query = query + node..... Pega cada node nome dentro de a e vai concatenando... Alguem tem ideia como fazer isso com xquery?
    Guns!
    • Movido Gustavo Maia Aguiar segunda-feira, 14 de dezembro de 2009 14:56 (De:SQL Server - Desenvolvimento Geral)
    segunda-feira, 14 de dezembro de 2009 12:55

Respostas

  • veja se este exemplo te ajuda.

    DECLARE @tb AS TABLE(ID INT IDENTITY(1,1), ColXml XML)
    
    INSERT INTO @tb 
    SELECT 
    '<no>
    	<Nomes>A</Nomes>
    	<Nomes>Joao</Nomes>
    	<Nomes>Pedro</Nomes>
    	<Nomes>Maria</Nomes>
    	<Nomes>A</Nomes>
    </no>'
    UNION SELECT 
    '<no>
    	<Nomes>Leonardo</Nomes>
    	<Nomes>Marcelino</Nomes>
    </no>'
    
    
    SELECT 
        A.ID,
        (
         SELECT B.Col.value('.','varchar(max)') AS [data()] 
         FROM   @tb 
         CROSS APPLY ColXml.nodes('/no/Nomes') as B(Col)
         WHERE ID = A.ID
         FOR XML PATH('')
        ) AS Nomes
    FROM
        @tb AS A
    
    
    /*
    
    ID          Nomes
    ----------- --------------------------
    1           A Joao Pedro Maria A
    2           Leonardo Marcelino
    
    (2 linha(s) afetadas)
    
    */

    Se a minha ajuda lhe for útil não esqueça de classificar. Att. Leonardo Marcelino
    • Marcado como Resposta Under terça-feira, 15 de dezembro de 2009 13:21
    segunda-feira, 14 de dezembro de 2009 14:21
  • Bom Dia,

    Segue um exemplo para tentar achar o caminho:

    declare @xml xml
    set @xml = '
    <comando>
     <select>
      <coluna>Codigo</coluna>
      <coluna>Nome</coluna>
      <coluna>UF</coluna>
     </select>
     <from>
      <tabela>Cliente</tabela>
     </from>
    </comando>'
    select replace(replace(cast(@xml.query('
    <cmd>{
     for $c in /comando/select/coluna
     return concat(($c/text()[1]),",")}</cmd>') as varchar(200)),'<cmd>','SELECT '),',</cmd>',
     ' FROM ' + @xml.value('(/comando/from/tabela)[1]','varchar(20)'))


    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    SQL Server Saturday Night
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!878.entry


    Classifique as respostas. O seu feedback é imprescindível
    • Marcado como Resposta Under terça-feira, 15 de dezembro de 2009 15:11
    terça-feira, 15 de dezembro de 2009 13:37

Todas as Respostas

  • Olá.

          Você deve usar o método Nodes e o Método Value. Veja se o exemplo abaixo ajuda você.

    create table #tabela (dados xml)
    insert into #tabela values ('<a><nome>João</nome><nome>Maria</nome><nome>Pedro</nome></a>')
    
    select T2.Dados.value('.', 'varchar(50)')
    from #tabela 
    cross apply dados.nodes('/a/nome') as T2(Dados)
    
    drop table #tabela
    O resultado será um resultset de valores que você deve percorrer e montar sua query.

    MCT / MCITP - Database Administrator 2008 MCITP - Database Developer 2008
    segunda-feira, 14 de dezembro de 2009 13:39
    Moderador
  • veja se este exemplo te ajuda.

    DECLARE @tb AS TABLE(ID INT IDENTITY(1,1), ColXml XML)
    
    INSERT INTO @tb 
    SELECT 
    '<no>
    	<Nomes>A</Nomes>
    	<Nomes>Joao</Nomes>
    	<Nomes>Pedro</Nomes>
    	<Nomes>Maria</Nomes>
    	<Nomes>A</Nomes>
    </no>'
    UNION SELECT 
    '<no>
    	<Nomes>Leonardo</Nomes>
    	<Nomes>Marcelino</Nomes>
    </no>'
    
    
    SELECT 
        A.ID,
        (
         SELECT B.Col.value('.','varchar(max)') AS [data()] 
         FROM   @tb 
         CROSS APPLY ColXml.nodes('/no/Nomes') as B(Col)
         WHERE ID = A.ID
         FOR XML PATH('')
        ) AS Nomes
    FROM
        @tb AS A
    
    
    /*
    
    ID          Nomes
    ----------- --------------------------
    1           A Joao Pedro Maria A
    2           Leonardo Marcelino
    
    (2 linha(s) afetadas)
    
    */

    Se a minha ajuda lhe for útil não esqueça de classificar. Att. Leonardo Marcelino
    • Marcado como Resposta Under terça-feira, 15 de dezembro de 2009 13:21
    segunda-feira, 14 de dezembro de 2009 14:21
  • Desde ja agradeço a ajuda povo! O que esta mais dificil para mim não é trazer os resultados do xml mas sim conseguir montar a query dinamica por exemplo... Tenho essa saida... 1 A Joao Pedro Maria A 2 Leonardo Marcelino Até ai tudo bem mas a ideia seria por exemplo de alguma forma fazer algo como um while... eu estava olhando pelo for do xquery mas ainda nao consegui... Pegaria esses valores e jogaria dentro de uma variavel formatando devidamente. Exemplo Ficaria @sql = @sql + 'where = '' Joao ''' e agregaria tmb @sql + 'where = '' Pedro'''e assim por diante. E outra dificuldade é por conta de precisar comparar o valor pego para ver se adiciono um parametro na query ou nao. Exemplo tem um node valor que dentro pode ter n valores ai preciso acrescentar na clausula where só o que tiver valor mais que 5 por... Entao eu precisaria ir retornando formatando e jogando dentro do @sql que sera executado depois Nao sei se to sendo muito claro na explicação
    Guns!
    segunda-feira, 14 de dezembro de 2009 16:19
  • Under,

    Veja se este outro exemplo poderá ajudar:

    declare @dadosxml xml

    set @dadosxml = '<?xml version="1.0"?>

    <root>

    <cliente id="1">

    <prod id="321"/>

    <prod id="543"/>

    <prod id="762"/>

    <prod id="325"/>

    </cliente>

    <cliente id="2">

    <prod id="289"/>

    <prod id="776"/>

    <prod id="335"/>

    <prod id="1020"/>

    </cliente>

    </root>'

    --print convert(nvarchar(4000),@dadosxml)

    SELECT

    t.c.value('../@id[1]','int') as IdCliente,

    t.c.value('@id[1]','int') as IdProduto

    FROM

    @dadosxml.nodes('/root/cliente/prod') as t(c)

    dECLARE @x xml
    SET @x='<Root>
        <row id="1"><name>Larry</name><oflw>some text</oflw></row>
        <row id="2"><name>moe</name></row>
        <row id="3" />
    </Root>'
    SELECT T.c.query('.') AS result
    FROM   @x.nodes('/Root/row') T(c)
    GO


    Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA
    segunda-feira, 14 de dezembro de 2009 22:39
  • A ideia é trazer em uma linha só o resultado do xml DECLARE @str VARCHAR(100) SELECT @str = COALESCE(@str, '') + Numbers FROM #Temp Print @str Esse codigo por exemplo traz o valor de number "inline" se na tabela eu tenho os valores one two three O resultado sai OneTwoThree É isso que eu quero fazer se tinho o xml com nomes quero trazer todos os nome juntos em um campo só...
    Guns!
    terça-feira, 15 de dezembro de 2009 12:23
  • veja este outro exemplo:

    DECLARE @tb AS TABLE(ID INT IDENTITY(1,1), ColXml XML)
    
    INSERT INTO @tb 
    SELECT 
    '<no>
    	<Nomes>A</Nomes>
    	<Nomes>Joao</Nomes>
    	<Nomes>Pedro</Nomes>
    	<Nomes>Maria</Nomes>
    	<Nomes>A</Nomes>
    </no>'
    UNION SELECT 
    '<no>
    	<Nomes>Leonardo</Nomes>
    	<Nomes>Marcelino</Nomes>
    </no>'
    
    
     SELECT ColXml.value('.','varchar(max)')
     FROM   @tb 
    
     /*
     ------------------------------
    AJoaoPedroMariaA
    LeonardoMarcelino
    
    (2 linha(s) afetadas)
     
     */

    Se a minha ajuda lhe for útil não esqueça de classificar. Att. Leonardo Marcelino
    terça-feira, 15 de dezembro de 2009 12:29
  • Exemplo mais claro DECLARE @xmlDoc xml
    DECLARE @handle INT
    SET @xmlDoc = N'
    ELETRI
    ARCOND

    '

    EXEC sp_xml_preparedocument @handle OUTPUT, @xmlDoc

    ## eu quero aqui trazer um retorno assim 'ELETRI,ARCOND' (uma linha com todos os valores de pmbldsys)
    exec sp_xml_removedocument @handle


    Guns!
    terça-feira, 15 de dezembro de 2009 12:36
  • Under,

    O sp_xml_preparedocument é um procedimento mais indicado para o SQL Server 2000.
    Pedro Antonio Galvão Junior - MVP - Windows Server System - SQL Server/Coordenador de Projetos/DBA
    terça-feira, 15 de dezembro de 2009 12:59
  • Tenho esse xml... to pondo = pq ta cortando...

    =root=
    =nome=A=/nome=
    =nome=B=/nome=
    =root=

    Quero trazer o resultado assim
    'A,B' ou AB só...
    vou trazer o retorno em uma linha todos os elementos nomes concatenados
    Guns!
    terça-feira, 15 de dezembro de 2009 13:18
  • Bom Dia,

    Segue um exemplo para tentar achar o caminho:

    declare @xml xml
    set @xml = '
    <comando>
     <select>
      <coluna>Codigo</coluna>
      <coluna>Nome</coluna>
      <coluna>UF</coluna>
     </select>
     <from>
      <tabela>Cliente</tabela>
     </from>
    </comando>'
    select replace(replace(cast(@xml.query('
    <cmd>{
     for $c in /comando/select/coluna
     return concat(($c/text()[1]),",")}</cmd>') as varchar(200)),'<cmd>','SELECT '),',</cmd>',
     ' FROM ' + @xml.value('(/comando/from/tabela)[1]','varchar(20)'))


    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    SQL Server Saturday Night
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!878.entry


    Classifique as respostas. O seu feedback é imprescindível
    • Marcado como Resposta Under terça-feira, 15 de dezembro de 2009 15:11
    terça-feira, 15 de dezembro de 2009 13:37