¿Cómo puedo leer un archivo XML y almacenar los datos en XML en nuestra tabla en SQL Server 2008?
¿Cómo puedo leer un archivo XML y almacenar los datos en XML en nuestra tabla en SQL Server 2008?
Respuestas:
Este nodo de análisis basado en XML. Es diferente leer atributos pero no es tan común
Tenía esto por ahí como una demostración con 3 consultas XPath ligeramente diferentes
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)
Lo he intentado con la respuesta anterior. Intentalo,
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)
Nigromancia
De cadena:
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);
Desde el archivo:
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)
p.ej
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);
Entonces puedes tener una función como
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)
)
Solo agregaré una respuesta para que sepa que tiene otra opción. También puede usar OPENXML para leer datos xml. Esta era la forma de hacerlo en versiones anteriores de SQL Server. No es perfecto, pero funciona. Y es fácil de abusar :-). Simplemente compare los planes de dos xmls idénticos tratados con consultas XPATH (respuesta de gbn) en comparación con OPENXML u OPENROWSET. Usaré un ejemplo del artículo de MSDN ahora, pero puedes obtener la imagen completa:
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))