Comment puis-je lire un fichier XML et stocker les données en XML dans notre table dans SQL Server 2008?
Comment puis-je lire un fichier XML et stocker les données en XML dans notre table dans SQL Server 2008?
Réponses:
Ce XML basé sur le nœud d'analyse. C'est différent de lire les attributs mais ce n'est pas aussi courant
J'avais ce traîner comme une démo avec 3 requêtes XPath légèrement différentes
DECLARE @foo XML
SELECT @foo = N'
<harrys>
<harry>
<fish>0.015000000000</fish>
<bicycle>2008-10-31T00:00:00+01:00</bicycle>
<foo>ü</foo>
</harry>
<harry>
<fish>0.025000000000</fish>
<bicycle>2008-08-31T00:00:00+01:00</bicycle>
<foo>ä</foo>
</harry>
</harrys>
'
SELECT
CAST(CAST(y.item.query('data(fish)') AS varchar(30)) AS float),
CAST(LEFT(CAST(y.item.query('data(bicycle)') AS char(25)), 10) AS smalldatetime),
CAST(y.item.query('data(foo)') AS varchar(25))
FROM
@foo.nodes('/*') x(item)
CROSS APPLY
x.item.nodes('./*') AS y(item)
SELECT
CAST(CAST(x.item.query('data(fish)') AS varchar(30)) AS float),
CAST(LEFT(CAST(x.item.query('data(bicycle)') AS char(25)), 10) AS smalldatetime),
CAST(x.item.query('data(foo)') AS varchar(25))
FROM
@foo.nodes('harrys/harry') x(item)
SELECT
CAST(CAST(y.item.query('data(fish)') AS varchar(30)) AS float),
CAST(LEFT(CAST(y.item.query('data(bicycle)') AS char(25)), 10) AS smalldatetime),
CAST(y.item.query('data(foo)') AS varchar(25))
FROM
@foo.nodes('/harrys') x(item)
CROSS APPLY
x.item.nodes('./harry') AS y(item)
Je l'ai essayé avec la réponse ci-dessus. Essayez-le,
XML:
<?xml version="1.0" encoding="utf-8" ?>
- <FundingSought xml:lang="en">
- <Fund>
<FundName>sdfdsfd</FundName>
<FundValue>1</FundValue>
</Fund>
- <Fund>
<FundName>dfdgfdg</FundName>
<FundValue>2</FundValue>
</Fund>
- <Fund>
<FundName>fghghh</FundName>
<FundValue>3</FundValue>
</Fund>
- <Fund>
<FundName>sdfdgg</FundName>
<FundValue>4</FundValue>
</Fund>
- <Fund>
<FundName>hgfhh</FundName>
<FundValue>5</FundValue>
</Fund>
- <Fund>
<FundName>fghgh</FundName>
<FundValue>6</FundValue>
</Fund>
- <Fund>
<FundName>ghhhh</FundName>
<FundValue>7</FundValue>
</Fund>
- <Fund>
<FundName>hfghh</FundName>
<FundValue>8</FundValue>
</Fund>
</FundingSought>
SQL:
CREATE TABLE #XmlImportTest(
xmlFileName VARCHAR(300) NOT NULL,
xml_data XML NOT NULL
)
GO
DECLARE @xmlFileName VARCHAR(300)
SELECT @xmlFileName = 'C:\FundingSought.xml'
--– dynamic sql is just so we can use @xmlFileName variable in OPENROWSET
EXEC('INSERT INTO #XmlImportTest(xmlFileName, xml_data)
SELECT ''' + @xmlFileName + ''', xmlData
FROM(
SELECT *
FROM OPENROWSET (BULK ''' + @xmlFileName + ''', SINGLE_BLOB) AS XMLDATA
) AS FileImport (XMLDATA)
')
GO
DECLARE @foo XML
SET @foo = (SELECT xml_data from #XmlImportTest)
SELECT
CAST(y.item.query('data(FundName)') AS varchar(30)),
CAST(y.item.query('data(FundValue)') AS char(25))
FROM
@foo.nodes('/*') x(item)
CROSS APPLY
x.item.nodes('./*') AS y(item)
Nécromancement:
De la chaîne:
SELECT
--myTempTable.XmlCol.value('.', 'varchar(36)') AS val
myTempTable.XmlCol.query('./ID').value('.', 'varchar(36)') AS ID
,myTempTable.XmlCol.query('./Name').value('.', 'nvarchar(MAX)') AS Name
,myTempTable.XmlCol.query('./RFC').value('.', 'nvarchar(MAX)') AS RFC
,myTempTable.XmlCol.query('./Text').value('.', 'nvarchar(MAX)') AS Text
,myTempTable.XmlCol.query('./Desc').value('.', 'nvarchar(MAX)') AS Description
FROM
(
SELECT
CAST('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data-set>
<record>
<ID>1</ID>
<Name>A</Name>
<RFC>RFC 1035[1]</RFC>
<Text>Address record</Text>
<Desc>Returns a 32-bit IPv4 address, most commonly used to map hostnames to an IP address of the host, but it is also used for DNSBLs, storing subnet masks in RFC 1101, etc.</Desc>
</record>
<record>
<ID>2</ID>
<Name>NS</Name>
<RFC>RFC 1035[1]</RFC>
<Text>Name server record</Text>
<Desc>Delegates a DNS zone to use the given authoritative name servers</Desc>
</record>
</data-set>
' AS xml) AS RawXml
) AS b
--CROSS APPLY b.RawXml.nodes('//record/ID') myTempTable(XmlCol);
CROSS APPLY b.RawXml.nodes('//record') myTempTable(XmlCol);
Du fichier:
SELECT
--myTempTable.XmlCol.value('.', 'varchar(36)') AS val
myTempTable.XmlCol.query('./ID').value('.', 'varchar(36)') AS ID
,myTempTable.XmlCol.query('./Name').value('.', 'nvarchar(MAX)') AS Name
,myTempTable.XmlCol.query('./RFC').value('.', 'nvarchar(MAX)') AS RFC
,myTempTable.XmlCol.query('./Text').value('.', 'nvarchar(MAX)') AS Text
,myTempTable.XmlCol.query('./Desc').value('.', 'nvarchar(MAX)') AS Description
FROM
(
SELECT CONVERT(XML, BulkColumn) AS RawXml
FROM OPENROWSET(BULK 'D:\username\Desktop\MyData.xml', SINGLE_BLOB) AS RowSetName
) AS b
CROSS APPLY b.RawXml.nodes('//record') myTempTable(XmlCol)
par exemple
DECLARE @bla varchar(MAX)
SET @bla = 'BED40DFC-F468-46DD-8017-00EF2FA3E4A4,64B59FC5-3F4D-4B0E-9A48-01F3D4F220B0,A611A108-97CA-42F3-A2E1-057165339719,E72D95EA-578F-45FC-88E5-075F66FD726C'
-- http://stackoverflow.com/questions/14712864/how-to-query-values-from-xml-nodes
SELECT
x.XmlCol.value('.', 'varchar(36)') AS val
FROM
(
SELECT
CAST('<e>' + REPLACE(@bla, ',', '</e><e>') + '</e>' AS xml) AS RawXml
) AS b
CROSS APPLY b.RawXml.nodes('e') x(XmlCol);
Vous pouvez donc avoir une fonction comme
SELECT * FROM MyTable
WHERE UID IN
(
SELECT
x.XmlCol.value('.', 'varchar(36)') AS val
FROM
(
SELECT
CAST('<e>' + REPLACE(@bla, ',', '</e><e>') + '</e>' AS xml) AS RawXml
) AS b
CROSS APPLY b.RawXml.nodes('e') x(XmlCol)
)
Je vais juste ajouter une réponse pour que vous sachiez que vous avez une autre option. Vous pouvez également utiliser OPENXML pour lire les données xml. C'était le moyen de le faire dans les anciennes versions de SQL Server. Ce n'est pas parfait, mais ça marche. Et il est facile d'en abuser :-). Il suffit de comparer les plans de deux xml identiques traités avec des requêtes XPATH (réponse de gbn) par rapport à OPENXML ou OPENROWSET. J'utiliserai maintenant un exemple de l'article MSDN, mais vous pouvez obtenir l'image complète:
DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
<Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
<OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
<OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
</Order>
</Customer>
</ROOT>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customer',1)
WITH (CustomerID varchar(10),
ContactName varchar(20))