Jak mogę odczytać plik XML i przechowywać dane w formacie XML w naszej tabeli w SQL Server 2008?
Jak mogę odczytać plik XML i przechowywać dane w formacie XML w naszej tabeli w SQL Server 2008?
Odpowiedzi:
Ten plik XML oparty na analizie węzła. Odczytywanie atrybutów różni się, ale nie jest tak powszechne
Miałem to jako demo z 3 nieco innymi zapytaniami XPath
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)
Próbowałem z powyższą odpowiedzią. Spróbuj,
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)
Nekromancja:
Z ciągu:
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);
Z pliku:
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)
na przykład
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);
Możesz mieć taką funkcję
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)
)
Dodam tylko odpowiedź, abyś wiedział, że masz inną opcję. Możesz także użyć OPENXML do odczytu danych XML. W ten sposób można to zrobić w starszych wersjach programu SQL Server. To nie jest idealne, ale działa. Łatwo jest nadużywać :-). Wystarczy porównać plany dwóch identycznych plików XML traktowanych za pomocą zapytań XPATH (odpowiedź gbn) w porównaniu do OPENXML lub OPENROWSET. Użyję teraz przykładu z artykułu MSDN, ale możesz uzyskać pełny obraz:
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))