Ler arquivo XML no SQL Server 2008

12

Como posso ler um arquivo XML e armazenar os dados em XML em nossa tabela no SQL Server 2008?

pooja
fonte
2
Se você nos der um XML, podemos mostrar como.
gbn 28/02
por favor, torne-o mais específico. Atualize sua pergunta para mostrar a amostra xml que você deseja importar para o banco de dados.
CoderHawk
1
você tem 3 soluções aqui, escolha uma que combina com você e marque como resposta. Isso ajudará o respondente :-).
Marian
Marque a resposta ajudada. Agora você tem reputação suficiente para votar. upvote = dizer obrigado :)
CoderHawk
Aceite e / ou vote em respostas úteis ou finais. meta.stackexchange.com/questions/5234/… e meta.stackexchange.com/questions/7237
gbn em

Respostas:

6

Este XML de nó de análise baseado. É diferente ler atributos, mas não é tão comum

Eu tive isso por aí como uma demonstração com 3 consultas XPath ligeiramente 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)
gbn
fonte
5

Eu tentei com a resposta acima. Tente,

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)
pooja
fonte
esta resposta funcionou para você? Eu acho que você deve atualizar sua pergunta e adicionar este xml lá!
CoderHawk
Sim Sandy. Está funcionando bem.
pooja
2

Necromancing:

Da sequência:

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

De arquivo:

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)

por exemplo

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

Então você pode ter uma função 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)
)
Dilema
fonte
1

Vou apenas adicionar uma resposta para que você saiba que tem outra opção. Você também pode usar o OPENXML para ler dados xml. Essa era a maneira de fazer isso nas versões mais antigas do SQL Server. Não é perfeito, mas funciona. E é fácil abusar :-). Basta comparar os planos de dois xmls idênticos tratados com consultas XPATH (resposta de gbn) em comparação com OPENXML ou OPENROWSET. Vou usar um exemplo do artigo do MSDN agora, mas você pode obter uma imagem 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))
Marian
fonte