The Best Way to shred XML data into SQL Server database columns -


what best way shred xml data various database columns? far have been using nodes , value functions so:

insert some_table (column1, column2, column3) select rows.n.value('(@column1)[1]', 'varchar(20)'), rows.n.value('(@column2)[1]', 'nvarchar(100)'), rows.n.value('(@column3)[1]', 'int'), @xml.nodes('//rows') rows(n) 

however find getting slow moderate size xml data.

stumbled across question whilst having similar problem, i'd been running query processing 7.5mb xml file (~approx 10,000 nodes) around 3.5~4 hours before giving up.

however, after little more research found having typed xml using schema , created xml index (i'd bulk inserted table) same query completed in ~ 0.04ms.

how's performance improvement!

code create schema:

if exists ( select * sys.xml_schema_collections [name] = 'myxmlschema') drop xml schema collection [myxmlschema] go  declare @myschema xml set @myschema =  (     select * openrowset     (         bulk 'c:\path\to\schema\myschema.xsd', single_clob      ) xmldata )  create xml schema collection [myxmlschema] @myschema  go 

code create table typed xml column:

create table [dbo].[xmlfiles] (     [id] [uniqueidentifier] not null,      -- data 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] 

code create index

create primary xml index pxml_data on [dbo].[xmlfiles] (data) 

there few things bear in mind though. sql server's implementation of schema doesn't support xsd:include. means if have schema references other schema, you'll have copy of these single schema , add that.

also error:

xquery [dbo.xmlfiles.data.value()]: cannot implicitly atomize or apply 'fn:data()' complex content elements, found type 'xs:anytype' within inferred type 'element({http://www.mynamespace.fake/schemas}:sequencenumber,xs:anytype) ?'. 

if tried navigate above node had selected nodes function. e.g.

select     ,c.value('cvelementid[1]', 'int') [cvelementid]     ,c.value('../sequencenumber[1]', 'int') [level]      [dbo].[xmlfiles] cross apply     [data].nodes('/cvset/level/cvelement') t(c) 

found best way handle use outer apply in effect perform "outer join" on xml.

select     ,c.value('cvelementid[1]', 'int') [cvelementid]     ,b.value('sequencenumber[1]', 'int') [level]      [dbo].[xmlfiles] cross apply     [data].nodes('/cvset/level') t(b) outer apply     b.nodes ('cvelement') s(c) 

hope that helps that's pretty been day.


Comments

Popular posts from this blog

windows - Why does Vista not allow creation of shortcuts to "Programs" on a NonAdmin account? Not supposed to install apps from NonAdmin account? -

c++ - How do I get a multi line tooltip in MFC -

unit testing - How to mock PreferenceManager in Android? -