Leggi il file XML in SQL Server 2008


12

Come posso leggere un file XML e archiviare i dati in XML nella nostra tabella in SQL Server 2008?


2
Se ci dai un po 'di XML, possiamo mostrarti come.
gbn,

per favore rendilo più specifico. Aggiorna la tua domanda per mostrare l'XML di esempio che desideri importare nel database.
CoderHawk,

1
hai 3 soluzioni qui, scegline una adatta a te e segna come risposta. Ciò aiuterà il rispondente :-).
Marian

Per favore, mark ha aiutato a rispondere. Ora hai abbastanza reputazione da votare. upvote = dicendo grazie :)
CoderHawk

Risposte:


6

Questo XML basato su nodo di analisi. È diverso leggere gli attributi ma non è così comune

Ho avuto questo in giro come una demo con 3 query XPath leggermente diverse

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)

5

L'ho provato con la risposta sopra. Provalo,

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)

questa risposta ha funzionato per te? Penso che dovresti aggiornare la tua domanda e aggiungere questo xml lì dentro!
CoderHawk,

Sì Sandy. Funziona bene.
pooja

2

Necromancing:

Dalla stringa:

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);

Dal file:

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)

per esempio

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);

Quindi puoi avere una funzione simile

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)
)

1

Aggiungerò solo una risposta in modo da sapere che hai un'altra opzione. Puoi anche usare OPENXML per leggere i dati XML. Questo era il modo di farlo nelle versioni precedenti di SQL Server. Non è perfetto, ma funziona. Ed è facile abusare :-). Basta confrontare i piani di due xmls identici trattati con query XPATH (la risposta di gbn) rispetto a OPENXML o OPENROWSET. Userò un esempio dall'articolo MSDN ora, ma è possibile ottenere il quadro completo:

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))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.