อ่านไฟล์ XML ใน SQL Server 2008


12

ฉันจะอ่านไฟล์ XML และเก็บข้อมูลใน XML ลงในตารางของเราใน SQL Server 2008 ได้อย่างไร


2
หากคุณให้ XML แก่เราเราสามารถแสดงให้คุณเห็นได้ว่า
gbn

โปรดระบุให้ชัดเจนยิ่งขึ้น อัปเดตคำถามของคุณเพื่อแสดงตัวอย่าง xml ที่คุณต้องการนำเข้าสู่ฐานข้อมูล
CoderHawk

1
คุณมีวิธีแก้ปัญหา 3 ข้อที่นี่เลือกวิธีที่เหมาะสมกับคุณและทำเครื่องหมายเป็นคำตอบ นั่นจะช่วยผู้ตอบ :-)
Marian

กรุณาทำเครื่องหมายคำตอบช่วย ตอนนี้คุณมีชื่อเสียงพอที่จะโหวตขึ้น upvote = พูดว่าขอบคุณ :)
CoderHawk

โปรดยอมรับและ / หรือลงคะแนนในคำตอบที่เป็นประโยชน์หรือสุดท้าย meta.stackexchange.com/questions/5234/…และmeta.stackexchange.com/questions/7237
gbn

คำตอบ:


6

การแยกวิเคราะห์ XML ตามโหนดนี้ มันแตกต่างจากการอ่านคุณสมบัติ แต่มันไม่ธรรมดา

ฉันมีสิ่งนี้โกหกรอบเป็นตัวอย่างที่มี 3 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

Necromancing:

จากสตริง:

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 เวอร์ชันเก่า มันไม่สมบูรณ์แบบ แต่ใช้งานได้ และมันเป็นเรื่องง่ายที่จะละเมิด :-) เพียงเปรียบเทียบแผนของ xml ที่เหมือนกันสองตัวที่รับการรักษาด้วยการค้นหา 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))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.