Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara Terbaik untuk menghancurkan data XML ke dalam kolom database SQL Server

Menemukan pertanyaan ini ketika memiliki masalah yang sangat mirip, saya telah menjalankan kueri yang memproses file XML 7,5MB (~kira-kira 10.000 node) selama sekitar 3,5~4 jam sebelum akhirnya menyerah.

Namun, setelah sedikit penelitian lebih lanjut, saya menemukan bahwa setelah mengetik XML menggunakan skema dan membuat Indeks XML (saya akan memasukkan secara massal ke dalam tabel) kueri yang sama diselesaikan dalam ~ 0,04 ms.

Bagaimana dengan peningkatan kinerja!

Kode untuk membuat skema:

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

Kode untuk membuat tabel dengan kolom XML yang diketik:

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]

Kode untuk membuat Indeks

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

Ada beberapa hal yang perlu diingat. Implementasi Skema SQL Server tidak mendukung xsd:include. Artinya, jika Anda memiliki skema yang mereferensikan skema lain, Anda harus menyalin semua ini ke dalam satu skema dan menambahkannya.

Saya juga akan mendapatkan kesalahan:

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) ?'.

jika saya mencoba menavigasi di atas node yang saya pilih dengan fungsi node. Mis.

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)

Menemukan bahwa cara terbaik untuk menangani ini adalah dengan menggunakan OUTER APPLY untuk melakukan "outer join" pada XML.

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)

Semoga itu bisa membantu seseorang karena itu adalah hari saya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah ada cara untuk mendapatkan daftar semua tabel sementara saat ini di SQL Server?

  2. Cara memasukkan gumpalan ke dalam database menggunakan studio manajemen server sql

  3. Cara Menginstal sqlcmd &bcp di Ubuntu

  4. Terhubung ke Database MSSQL menggunakan Flask-SQLAlchemy

  5. SQL Server v.Berikutnya :Performa STRING_AGG, Bagian 2