AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 1419
Accepted
fa1c0n3r
fa1c0n3r
Asked: 2011-02-24 21:46:58 +0800 CST2011-02-24 21:46:58 +0800 CST 2011-02-24 21:46:58 +0800 CST

tentando transformar XML em tabelas SQL hierárquicas, alguém pode fornecer uma boa explicação de duas partes deste exemplo de código?

  • 772

Estou tentando aprender como transformar XML em tabelas SQL hierárquicas.

Encontrei um trecho de código antigo de um fórum da Microsoft que é basicamente o que estou tentando fazer, mas gostaria de saber se alguém poderia ajudar a descobrir o que está acontecendo linha por linha neste código, principalmente depois que o xml foi carregado no @XML

--I understand this part, just making the tables  

DECLARE @Books TABLE (BookID int identity(1,1),BookTitle varchar(50),BookLanguage varchar(20),BookPrice decimal(18,2))  
DECLARE @Topics TABLE (TopicID int identity(1,1),BookID int,TopicTitile varchar(50),Page int)  

--I understand this part, defining the @xml variable to be the xml below.. just a usual xml...


DECLARE @xml XML  
SET @xml = '  
<bookstore>  
    <name>My Bookstore</name><br/>  
    <location>New York</location><br/>  
    <book>  
        <title lang=&quot;eng&quot;>Harry Potter</title>  
        <price>29.99</price>  
        <tableOfContents>  
            <topic>  
                <title>Harry Potter Topic 1</title>  
                <page>2</page>  
            </topic>  
            <topic>  
                <title>Harry Potter Topic 2</title>
                <page>5</page>
            </topic>
        </tableOfContents>
    </book>
    <book>
        <title lang=&quot;eng&quot;>Learning XML</title>
        <price>39.95</price>
        <tableOfContents>
            <topic>
                <title>Learning XML Topic 1</title>
                <page>1</page>
            </topic>
            <topic>
                <title>Learning XML Topic 2</title>
                <page>2</page>
            </topic>
        </tableOfContents>
    </book>
</bookstore>'



--what is going on below here?  I am familiar with inserting data into tables,  
--but what kind of insert is this where you are selecting some things and then doing a  
--from @xml.nodes also, what is that T(c) at the end?  and do we always have to put    
--a [1] after each xml element to denote we are referring to the first one we encounter?  


INSERT INTO @Books  
SELECT T.c.value('title[1]','varchar(50)') AS 'BookTitle',  
    T.c.value('(title/@lang)[1]','varchar(20)') AS 'BookLanguage',  
    T.c.value('price[1]','decimal(18,2)') AS 'BookPrice'  
FROM @xml.nodes('/bookstore/book') T(c)  


--what is going on here as well?  what is n(x) ? 
--could you explain this line by line-ish as well? I ran this on  
--SQL Server Management Studio and noticed that both of the 'topic titles' for each  
--book got inserted.  Where in the code did those get put into the table?

INSERT INTO @Topics  
SELECT b.BookID,n.x.value('title[1]','varchar(50)') AS 'TopicTitile',  
    n.x.value('page[1]','int') AS 'TopicPage'  
FROM @Books b   
cross apply @xml.nodes('/bookstore/book/tableOfContents/topic[../../title=sql:column("b.BookTitle")]') n(x)  


--below here is just regular sql selects so this makes sense.  

SELECT BookID,BookTitle,BookLanguage,BookPrice FROM @Books  
SELECT TopicID,BookID,TopicTitile,Page FROM @Topics  

O fórum ao qual eu estava me referindo e tentando aprender com o post antigo é:

http://social.msdn.microsoft.com/Forums/en/sqlxml/thread/7216ccc9-c1d7-418d-95a2-ec3a96de2c27

sql-server-2008 sql-server-2005
  • 1 1 respostas
  • 15966 Views

1 respostas

  • Voted
  1. Best Answer
    garik
    2011-02-24T23:56:59+08:002011-02-24T23:56:59+08:00

    BOL disse:

    sintaxe:

    nodes (XQuery) as Table(Column)
    

    Aqui está um exemplo simples:

    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
    

    É um aviso especial para "converter" ou fragmentar o tipo de dados xml em dados relacionais. Ele apenas mapeia partes xml nas colunas da tabela. T - tabela, c - coluna, nodes() - método

    value (XQuery, SQLType)
    

    Portanto, Tcvalue('title[1]','varchar(50)') lê o valor do elemento title e o converte no tipo de dados varchar(50). [1] é adicionado no final da expressão de caminho no método value() para indicar explicitamente que a expressão de caminho retorna um singleton (só me confunde, significa o primeiro elemento no grupo em XPath).

    Portanto, Tcvalue('(title/@lang)[1]','varchar(20)') lê o valor do atributo lang no elemento title e o converte no tipo de dados varchar(20).

    E @xml.nodes('/bookstore/book') está localizado o ponto para iniciar a leitura do xml, neste caso ele retorna todos os elementos do livro (nós) deste xml.

    Esta consulta tem 2 aliases T1(Locations) e T2(steps)

    ADICIONADO

    SELECT 
    ProductModelID
    , Locations.value('./@LocationID','int') as LocID
    , steps.query('.') as Step       
    FROM Production.ProductModel       
    
    CROSS APPLY Instructions.nodes('       
    declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";       
    /MI:root/MI:Location') 
    as T1(Locations) 
    
    CROSS APPLY T1.Locations.nodes('       
    declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";       
    ./MI:step ') 
    as T2(steps)       
    GO       
    
    • 4

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve