none
XQUERY RRS feed

  • Pergunta

  • Pessoal,

    Preciso fazer um loop na tag <segmento> pois ele pode vir variável, 1 ou 10 por exemplo. Consegui fazer. So que quando coloco esse código para rodar em uma proc que vai receber 1500 XMLs de uma tabela cada um numa linha da tabela esse comando demora muito. Acredito que seja alguma coisa relacionada a esse "Where". Pois quando diminuo os campos, ele vai muito mais rápido, mas preciso de todos os campos. E so consegui fazer dessa forma. Alguem sabe se esse "Where" pode ser substituido por algo parecido e mais rápido ?


    declare @venda XML, @Temp2 XML

    set @venda='<venda>
                         <origem>aaa</origem>
                         <idvenda>11111</idvenda>
                         <tipoproduto>aaa</tipoproduto>
                         <clasproduto>N</clasproduto>
                         <idemissor/>
                         <dtemissao>01/1/2012</dtemissao>
                         <idcliente/>
                         <idoperador>aaa</idoperador>
                         <idfornecedor>JddJ</idfornecedor>
                         <formpagtos>
                            <formpagto>
                               <tipo>1</tipo>
                            </formpagto>
                         </formpagtos>
                         <centrocustocli/>
                         <setorcli/>
                         <solicitante/>
                         <movimentos>
                            <aereorodoviario>
                               <pax>aaaaa</pax>
                               <tipo>aa</tipo>
                               <basetarifaria/>
                               <tarifa>0000</tarifa>
                               <tarifacheia>000</tarifacheia>
                               <moeda>BRL</moeda>
                               <cambio>aaaaa</cambio>
                               <datacambio>01/01/01</datacambio>
                               <taxaembarque>1111</taxaembarque>
                               <taxaservico>1111</taxaservico>
                               <repassedu>0000</repassedu>
                               <taxacartaodu>000</taxacartaodu>
                               <voosugerido>
                                  <tarifasugerida/>
                                  <numvoosugerido/>
                                  <motivosugerido/>
                                  <siglasugerida/>
                               </voosugerido>
                               <bilhetes>
                                  <bilhete>
                                     <numero>11111</numero>
                                  </bilhete>
                               </bilhetes>
                               <comisrecforvalor>000</comisrecforvalor>
                               <descpagclivalor>0000</descpagclivalor>
                               <observacao/>
                               <numautorizacao/>
                            </aereorodoviario>
                            <trechos>
                               <segmento>
                                  <de>aaa</de>
                                  <para>Aaa</para>
                                  <datasaida>01/01/01</datasaida>
                                  <datachegada>01/01/01</datachegada>
                                  <horasaida>0000</horasaida>
                                  <horachegada>0000</horachegada>
                                  <Voo>1111</Voo>
                                  <classe>a</classe>
                                  <localizador>aaa</localizador>
                                  <status>aaaa</status>
                                  <conexao>a</conexao>
                                  <ciaaerea>aa</ciaaerea>
                               </segmento>
                               <segmento>
                                  <de>bbb</de>
                                  <para>bbb</para>
                                  <datasaida>01/01/01</datasaida>
                                  <datachegada>01/01/01</datachegada>
                                  <horasaida>0000</horasaida>
                                  <horachegada>0000</horachegada>
                                  <Voo>111</Voo>
                                  <classe>a</classe>
                                  <localizador>aaa</localizador>
                                  <status>Aaa</status>
                                  <conexao>A</conexao>
                                  <ciaaerea>aa</ciaaerea>
                               </segmento>
                            </trechos>
                         </movimentos>
                      </venda>'


    SET  @temp2 = @venda.query('
    for $a in /venda/movimentos/trechos/segmento/de,
    $b in /venda/movimentos/trechos/segmento/para,
    $c in /venda/movimentos/trechos/segmento/datasaida,
    $d in /venda/movimentos/trechos/segmento/datachegada,
    $e in /venda/movimentos/trechos/segmento/Voo,
    $f in /venda/movimentos/trechos/segmento/ciaaerea,
    $g in /venda/movimentos/trechos/segmento/localizador,
    $h in /venda/movimentos/trechos/segmento/classe,
    $i in /venda/movimentos/trechos/segmento/status,
    $j in /venda/movimentos/trechos/segmento/conexao
    where $a/.. is  $b/.. 
    and $a/.. is  $c/..
    and $a/.. is  $d/..
    and $a/.. is  $e/..
    and $a/.. is  $f/..
    and $a/.. is  $g/..
    and $a/.. is  $h/..
    and $a/.. is  $i/..
    and $a/.. is  $j/..
    return element detail {attribute de {string($a)},
      attribute para {string($b)},
      attribute datasaida {string($c)},
      attribute datachegada {string($d)},
      attribute Voo {string($e)},
      attribute ciaaerea {string($f)},
      attribute localizador {string($g)},
      attribute classe {string($h)},
      attribute status {string($i)},
      attribute conexao {string($j)}}')
    SELECT t.c.value('@de','varchar(10)') as [de],
    t.c.value('@para','varchar(10)') as [para],
    t.c.value('@ciaaerea','varchar(20)') as [ciaaerea],
    t.c.value('@datasaida','varchar(30)') as [datasaida],
    t.c.value('@datachegada','varchar(30)') as [datachegada],
    t.c.value('@Voo','varchar(20)') as [Voo],
    t.c.value('@localizador','varchar(20)') as [localizador],
    t.c.value('@classe','varchar(20)') as [classe],
    t.c.value('@status','varchar(20)') as [status],
    t.c.value('@conexao','varchar(20)') as [conexao]
    FROM @temp2.nodes('/detail') as t(c)

    • Movido Roberson Ferreira _ quarta-feira, 22 de agosto de 2012 02:28 (De:SQL Server - Desenvolvimento Geral)
    quarta-feira, 22 de agosto de 2012 02:09

Respostas

Todas as Respostas

  • Boa Noite,

    Estou vendo que por esse e por sua outra thread, você está utilizando o método query em lugares onde ele não é necessário e nem performático. Veja que o nodes e o value diretamente é muito mais enxuto e eficiente. Coloquei um exemplo a partir de uma coluna e não de uma variável. Espero que ajude

    create table #tmp (id int, val xml)
    insert into #tmp values (1,'<venda>
      <origem>aaa</origem>
      <idvenda>11111</idvenda>
      <tipoproduto>aaa</tipoproduto>
      <clasproduto>N</clasproduto>
      <idemissor />
      <dtemissao>01/1/2012</dtemissao>
      <idcliente />
      <idoperador>aaa</idoperador>
      <idfornecedor>JddJ</idfornecedor>
      <formpagtos>
        <formpagto>
          <tipo>1</tipo>
        </formpagto>
      </formpagtos>
      <centrocustocli />
      <setorcli />
      <solicitante />
      <movimentos>
        <aereorodoviario>
          <pax>aaaaa</pax>
          <tipo>aa</tipo>
          <basetarifaria />
          <tarifa>0000</tarifa>
          <tarifacheia>000</tarifacheia>
          <moeda>BRL</moeda>
          <cambio>aaaaa</cambio>
          <datacambio>01/01/01</datacambio>
          <taxaembarque>1111</taxaembarque>
          <taxaservico>1111</taxaservico>
          <repassedu>0000</repassedu>
          <taxacartaodu>000</taxacartaodu>
          <voosugerido>
            <tarifasugerida />
            <numvoosugerido />
            <motivosugerido />
            <siglasugerida />
          </voosugerido>
          <bilhetes>
            <bilhete>
              <numero>11111</numero>
            </bilhete>
          </bilhetes>
          <comisrecforvalor>000</comisrecforvalor>
          <descpagclivalor>0000</descpagclivalor>
          <observacao />
          <numautorizacao />
        </aereorodoviario>
        <trechos>
          <segmento>
            <de>aaa</de>
            <para>Aaa</para>
            <datasaida>01/01/01</datasaida>
            <datachegada>01/01/01</datachegada>
            <horasaida>0000</horasaida>
            <horachegada>0000</horachegada>
            <Voo>1111</Voo>
            <classe>a</classe>
            <localizador>aaa</localizador>
            <status>aaaa</status>
            <conexao>a</conexao>
            <ciaaerea>aa</ciaaerea>
          </segmento>
          <segmento>
            <de>bbb</de>
            <para>bbb</para>
            <datasaida>01/01/01</datasaida>
            <datachegada>01/01/01</datachegada>
            <horasaida>0000</horasaida>
            <horachegada>0000</horachegada>
            <Voo>111</Voo>
            <classe>a</classe>
            <localizador>aaa</localizador>
            <status>Aaa</status>
            <conexao>A</conexao>
            <ciaaerea>aa</ciaaerea>
          </segmento>
        </trechos>
      </movimentos>
    </venda>')

    SELECT ID,
     t.c.value('(de)[1]','varchar(10)') as [de],
     t.c.value('(para)[1]','varchar(10)') as [para],
     t.c.value('(ciaaerea)[1]','varchar(20)') as [ciaaerea],
     t.c.value('(datasaida)[1]','varchar(30)') as [datasaida],
     t.c.value('(datachegada)[1]','varchar(30)') as [datachegada],
     t.c.value('(Voo)[1]','varchar(20)') as [Voo],
     t.c.value('(localizador)[1]','varchar(20)') as [localizador],
     t.c.value('(classe)[1]','varchar(20)') as [classe],
     t.c.value('(status)[1]','varchar(20)') as [status],
     t.c.value('(conexao)[1]','varchar(20)') as [conexao]
    FROM #tmp
    cross apply val.nodes('/venda/movimentos/trechos/segmento') t(c)

    [ ]s,

    Gustavo Maia Aguiar
    Blog: http://gustavomaiaaguiar.wordpress.com
    Vídeos:http://www.youtube.com/user/gmasql


    Classifique as respostas. O seu feedback é imprescindível

    quarta-feira, 22 de agosto de 2012 03:05
  • Entao caro Gustavo, 

    É justamente isso que eu não posso fazer, usar fixando [1] ou [2], pois como disse anteriormente, o ,<segmento> nesse caso são 2, mas poderia ser 4 ou 3 ou 10. Preciso entao fazer um loop de qualquer forma. So consegui usando essa estrutura onde o for usa as variaveis $a, $b, $c... o que deixa isso lento é justamente o "Where"... Por isso não posso usar o value e o nodes. Entendeu ?

    quarta-feira, 22 de agosto de 2012 03:42
  • Bom Dia Jacinto,

    A menos que eu não tenha compreendido sua dúvida, creio que sua percepção sobre o [1] está equivocada. No seu exemplo há dois segmentos, mas o uso do [1] foi capaz de resolver o problema, pois retornou os dois registros (tanto o nodes quanto a sua XQuery retornaram o mesmo resultado). O [1] de fato é para retornar a primeira ocorrência, mas como a navegação via XPath foi no nó mais baixo, você consegue retornar todas as ocorrências. Ex:

    declare @xml xml
    set @xml = '
    <Ocorrencias>
     <Ocorrencia Cod="1">
      <Dados>
       <Solicitante>João</Solicitante>
       <Data>2012-08-20</Data>
      </Dados>
     </Ocorrencia>
     <Ocorrencia Cod="2">
      <Dados>
       <Solicitante>José</Solicitante>
       <Data>2012-08-21</Data>
      </Dados>
     </Ocorrencia>
     <Ocorrencia Cod="3">
      <Dados>
       <Solicitante>Armando</Solicitante>
       <Data>2012-08-22</Data>
      </Dados>
     </Ocorrencia>
    </Ocorrencias>'

    select
     X.x.value('(Solicitante)[1]','varchar(100)')
    from @xml.nodes('/Ocorrencias/Ocorrencia/Dados') X(x)

    Nesse exemplo, existem três ocorrências e tudo é retornado. Se você colocar uma quarta ocorrência, ela também seria retornada. Você conseguiria postar uma situação que você tenha que o nodes não foi capaz de resolver ?

    [ ]s,

    Gustavo Maia Aguiar
    Blog: http://gustavomaiaaguiar.wordpress.com
    Vídeos:http://www.youtube.com/user/gmasql


    Classifique as respostas. O seu feedback é imprescindível

    • Marcado como Resposta Flavio Climaco quarta-feira, 22 de agosto de 2012 16:28
    • Não Marcado como Resposta Flavio Climaco quarta-feira, 22 de agosto de 2012 16:28
    quarta-feira, 22 de agosto de 2012 12:40
  • Sim Gustavo realmente cara... Obrigado pela ajuda meu amigo.

    • Marcado como Resposta Flavio Climaco quarta-feira, 22 de agosto de 2012 16:27
    • Não Marcado como Resposta Flavio Climaco quarta-feira, 22 de agosto de 2012 16:27
    quarta-feira, 22 de agosto de 2012 16:27
  • Jacinto,

    Se você precisa retornar as outras Tags do seu XML, basta especificar no comando Select, veja o exemplo:

    declare

    @xml xml


    set @xml = '

    <Ocorrencias>

      <Ocorrencia Cod="1">

       <Dados>

        <Solicitante>Joo</Solicitante>

        <Data>2012-08-20</Data>

       </Dados>

      </Ocorrencia>

      <Ocorrencia Cod="2">

       <Dados>

        <Solicitante>Jos</Solicitante>

        <Data>2012-08-21</Data>

       </Dados>

      </Ocorrencia>

      <Ocorrencia Cod="3">

       <Dados>

        <Solicitante>Armando</Solicitante>

        <Data>2012-08-22</Data>

       </Dados>

      </Ocorrencia>

    </Ocorrencias>'



    select


      X.x.value('(Solicitante)[1]','varchar(100)'),


      X.x.value('(Data)[1]','varchar(10)')


    from @xml.nodes('/Ocorrencias/Ocorrencia/Dados') X(x)


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    quarta-feira, 22 de agosto de 2012 16:42
  • Olá Flávio,

    Espero que tenhamos conseguido resolver sem o loop.
    Caso a solução tenha sido satisfatória, você poderia marcar a resposta ?

    [ ]s,

    Gustavo Maia Aguiar
    Blog: http://gustavomaiaaguiar.wordpress.com
    Vídeos:http://www.youtube.com/user/gmasql


    Classifique as respostas. O seu feedback é imprescindível

    • Marcado como Resposta Flavio Climaco sexta-feira, 24 de agosto de 2012 18:50
    quinta-feira, 23 de agosto de 2012 00:05