J'essaie d'apprendre à transformer XML dans des tables SQL héritière.
J'ai trouvé un ancien essai de code d'un forum Microsoft qui est fondamentalement ce que j'essaie de faire, mais je me demandais si quelqu'un pouvait aider à comprendre ce qui se passe en ligne par ligne sur ce code, en particulier après que le XML a été chargé sur @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="eng">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="eng">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
Le forum que je faisais appelé et essayant d'apprendre de l'ancienne post est la suivante:
http://social.msdn.microsoft.com/forums/en/sqlxml/thread/7216CCC9-C1D7-418D-95A2-EC3A96DE2C27
Bol dit:
syntaxe:
nodes (XQuery) as Table(Column)
Voici un exemple simple:
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
C'est un notticien spécial pour "convertir" ou déchiqueter le type de données XML en données relationnelles. Il mesure que des pièces XML dans les colonnes de table. T - Tableau, C - Colonne, Nœuds () - Méthode
value (XQuery, SQLType)
Donc, t.c.value ('Titre [1]', 'Varchar (50)') lit la valeur du titre d'élément et le convertit sur le type de données Varcharchar (50). [1] est ajouté à la fin de l'expression de chemin dans la méthode de la valeur () pour indiquer explicitement que l'expression du chemin renvoie un singleton (juste cela me confond, cela signifie le premier élément du groupe dans XPATH).
Donc, t.c.value ('(Titre/@ Lang) [1]' ',' Varchar (20) ') lit la valeur de l'attribut Lang au titre de l'élément et la convertit en type de données Varcharchar (20).
Et @ xml.nodes ('/ Librairie/Book') est situé le point pour lancer la lecture de XML, dans ce cas, il renvoie tous les éléments du livre (nœuds) à partir de ce XML.
Cette requête a 2 alias T1 (emplacements) et T2 (étapes)
AJOUTÉ
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