Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

XML डेटा को SQL सर्वर डेटाबेस कॉलम में विभाजित करने का सबसे अच्छा तरीका

एक बहुत ही समान समस्या होने पर इस प्रश्न में ठोकर खाई, मैं अंत में हार मानने से पहले लगभग 3.5 ~ 4 घंटे के लिए 7.5MB XML फ़ाइल (~ लगभग 10,000 नोड्स) को संसाधित करने वाली क्वेरी चला रहा था।

हालांकि, थोड़ा और शोध करने के बाद मैंने पाया कि स्कीमा का उपयोग करके एक्सएमएल टाइप करने और एक्सएमएल इंडेक्स (मैं एक टेबल में थोक में डाला गया) बनाया है, वही क्वेरी ~ 0.04ms में पूरी हुई है।

प्रदर्शन में सुधार के लिए यह कैसा है!

स्कीमा बनाने के लिए कोड:

IF EXISTS ( SELECT * FROM sys.xml_schema_collections where [name] = 'MyXmlSchema')
DROP XML SCHEMA COLLECTION [MyXmlSchema]
GO

DECLARE @MySchema XML
SET @MySchema = 
(
    SELECT * FROM OPENROWSET
    (
        BULK 'C:\Path\To\Schema\MySchema.xsd', SINGLE_CLOB 
    ) AS xmlData
)

CREATE XML SCHEMA COLLECTION [MyXmlSchema] AS @MySchema 
GO

टाइप किए गए XML कॉलम के साथ तालिका बनाने के लिए कोड:

CREATE TABLE [dbo].[XmlFiles] (
    [Id] [uniqueidentifier] NOT NULL,

    -- Data from CV element 
    [Data] xml(CONTENT dbo.[MyXmlSchema]) NOT NULL,

CONSTRAINT [PK_XmlFiles] PRIMARY KEY NONCLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

इंडेक्स बनाने के लिए कोड

CREATE PRIMARY XML INDEX PXML_Data
ON [dbo].[XmlFiles] (Data)

हालांकि कुछ बातों को ध्यान में रखना है। SQL सर्वर का स्कीमा का कार्यान्वयन xsd का समर्थन नहीं करता:शामिल करें। इसका मतलब यह है कि यदि आपके पास एक स्कीमा है जो अन्य स्कीमा को संदर्भित करता है, तो आपको इन सभी को एक ही स्कीमा में कॉपी करना होगा और उसे जोड़ना होगा।

साथ ही मुझे एक त्रुटि मिलेगी:

XQuery [dbo.XmlFiles.Data.value()]: Cannot implicitly atomize or apply 'fn:data()' to complex content elements, found type 'xs:anyType' within inferred type 'element({http://www.mynamespace.fake/schemas}:SequenceNumber,xs:anyType) ?'.

अगर मैंने नोड के ऊपर नेविगेट करने का प्रयास किया तो मैंने नोड्स फ़ंक्शन के साथ चुना था। उदा.

SELECT
    ,C.value('CVElementId[1]', 'INT') AS [CVElementId]
    ,C.value('../SequenceNumber[1]', 'INT') AS [Level]
FROM 
    [dbo].[XmlFiles]
CROSS APPLY
    [Data].nodes('/CVSet/Level/CVElement') AS T(C)

पाया गया कि इसे संभालने का सबसे अच्छा तरीका एक्सएमएल पर "बाहरी जुड़ाव" करने के लिए OUTER APPLY का उपयोग करना था।

SELECT
    ,C.value('CVElementId[1]', 'INT') AS [CVElementId]
    ,B.value('SequenceNumber[1]', 'INT') AS [Level]
FROM 
    [dbo].[XmlFiles]
CROSS APPLY
    [Data].nodes('/CVSet/Level') AS T(B)
OUTER APPLY
    B.nodes ('CVElement') AS S(C)

आशा है कि यह किसी की मदद करता है क्योंकि यह मेरा दिन काफी अच्छा रहा है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर प्रतीक्षा ईवेंट -1

  2. कॉलम फ़ील्ड के लिए दो पंक्तियों के बीच अंतर कैसे प्राप्त करें?

  3. SQL सर्वर में डेटा प्रकार की आईडी प्राप्त करने के लिए TYPE_ID() का उपयोग करें

  4. SQL सर्वर में मौजूदा SQL सर्वर तालिका से बैकअप या नई तालिका कैसे बनाएं - SQL सर्वर / TSQL ट्यूटोरियल भाग 105

  5. SQL सर्वर कर्सर प्रकार - SQL सर्वर में स्टेटिक कर्सर क्या हैं | SQL सर्वर ट्यूटोरियल / TSQL ट्यूटोरियल