Прочитайте XML-файл у SQL Server 2008


12

Як я можу прочитати XML-файл і зберігати дані в XML до нашої таблиці в SQL Server 2008?


2
Якщо ви дасте нам трохи XML, ми можемо показати вам, як.
gbn

будь ласка, зробіть це більш конкретним. Оновіть своє запитання, щоб показати зразок xml, який потрібно імпортувати в базу даних.
CoderHawk

1
у вас є 3 рішення тут, виберіть те, що вам підходить, і позначте як відповідь. Це допоможе відповіді :-).
Маріан

Позначте, будь ласка, відповідь. Тепер у вас достатньо репутації, щоб підняти участь. upvote = сказати спасибі :)
CoderHawk

Будь ласка, приймайте та / або голосуйте за корисні чи остаточні відповіді. meta.stackexchange.com/questions/5234/… та meta.stackexchange.com/questions/7237
gbn

Відповіді:


6

Цей вузол розбору на основі XML. Читати атрибути по-різному, але це не так часто

У мене це було як демонстрація з трьома дещо різними запитами 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)

5

Я спробував це з вищезазначеною відповіддю. Спробуй це,

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)

ця відповідь спрацювала для вас? Я думаю, ви повинні оновити своє запитання та додати туди xml!
CoderHawk

Так, Сенді. Це прекрасно працює.
pooja

2

Некромантування:

З рядка:

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

З файлу:

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)

напр

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

Так ви можете мати таку функцію

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

Я просто додам відповідь, щоб ви знали, що у вас є інший варіант. Ви також можете використовувати OPENXML для читання XML-даних. Так було зробити це в старих версіях SQL Server. Це не ідеально, але це працює. І це легко зловживати :-). Просто порівняйте плани двох однакових xmls, оброблених запитами XPATH (відповідь gbn) порівняно з OPENXML або OPENROWSET. Я зараз використаю приклад із статті MSDN, але ви можете отримати повне уявлення:

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))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.