Monday, March 26, 2012

How can I query the appointed node in XML with XQuery quickly?

I store the xml info below in the XML field in SQL 2005, I hope to query all the Folder node with XQuery.

The result I hope to get

<Folder Name="Root" Id="a6dce8fe-749c-4e38-ab2f-3d03d9711b3d">
<Folder Name="Card" Id="b8dcf8fe-749c-4e38-ab2f-6d03d9711b8j">
</Folder>
</Folder>

================ Stored In XML field==========================

<Folder Name="Root" Id="a6dce8fe-749c-4e38-ab2f-3d03d9711b3d">
<Bookmark>
<Title>CodeGuru Forums - ASP.NET</Title>
<Url>http://www.codeguru.com/</Url>
<Description>This is a good site</Description>
<InputDate> 2005-12-5</InputDate>
<IsPrivate>False</IsPrivate>
</Bookmark>
<Bookmark>
<Title>We will e-mail your press release</Title>
<Url>http://www.dpdirectory.com/</Url>
<Description>This is a good site</Description>
<InputDate> 2004-12-5</InputDate>
<IsPrivate>False</IsPrivate>
</Bookmark>
<Folder Name="Card" Id="b8dcf8fe-749c-4e38-ab2f-6d03d9711b8j">
<Bookmark>
<Title>Welcome to ePassporte</Title>
<Url>https://www.epassporte.com/</Url>
<Description>Very Good</Description>
<InputDate> 2004-08-5</InputDate>
<IsPrivate>True</IsPrivate>
</Bookmark>
<Bookmark>
<Title>Keystone DreamCard</Title>
<Url>https://www.mydreamcardonline.com</Url>
<Description>Please note</Description>
<InputDate> 2004-08-5</InputDate>
<IsPrivate>True</IsPrivate>
</Bookmark>
</Folder>
</Folder>

=====================================================

Some pepole give me a anwser, It work well, but when the size of the XML field is little big, it run very slowly, could you give a code which can run quickly!


//--Code -
declare @.my xml

set @.my='
<Folder Name="Root" Id="a6dce8fe-749c-4e38-ab2f-3d03d9711b3d">
<Bookmark BId="f8dce8hj-846c-4e38-ab2f-6d03d9711b80">
<Title>CodeGuru Forums - ASP.NET</Title>
<Url>http://www.codeguru.com/</Url>
<Description>This is a good site</Description>
<InputDate> 2005-12-23</InputDate>
<IsPrivate>False</IsPrivate>
</Bookmark>
<Bookmark BId="fgdce3ak-846c-4e38-ab2f-8i03d9711b23">
<Title>We ll e-mail your press release</Title>
<Url>http://www.dpdirectory.com/</Url>
<Description>This is a good site</Description>
<InputDate> 2004-11-23</InputDate>
<IsPrivate>False</IsPrivate>
</Bookmark>

<Folder Name="Card1" Id="b8dcf8fe-749c-4e38-ab2f-6d03d9711b8j">
<Bookmark BId="ghdce3ak-456c-4e38-ab2f-5h02d9711b67">
<Title>Welcome to ePassporte</Title>
<Url>https://www.epassporte.com/</Url>
<Description>Very Good</Description>
<InputDate> 2004-08-12</InputDate>
<IsPrivate>True</IsPrivate>
</Bookmark>
<Bookmark BId="fkdfh3a8-456c-6y38-jk2f-5h0gh9711b45">
<Title>Keystone DreamCard</Title>
<Url>https://www.mydreamcardonline.com</Url>
<Description>Please note</Description>
<InputDate> 2004-09-25</InputDate>
<IsPrivate>True</IsPrivate>
</Bookmark>

<Folder Name="Card1in1" Id="l9dcf8fe-689c-0935-fghj-7u03d9711b5t">
<Bookmark BId="ghdfh3a8-896c-6y40-jkfg-5h0gh9711b89">
<Title>The News of CNN</Title>
<Url>https://www.cnn.com</Url>
<Description>Please note</Description>
<InputDate> 2004-09-23</InputDate>
<IsPrivate>True</IsPrivate>
</Bookmark>
</Folder>

</Folder>

<Folder Name="Card2" Id="67dcf8fe-734c-4e56-ab2f-6d03d9711bfg">
</Folder>

</Folder>
'


set @.my.modify('delete (//*[local-name(.) != "Folder"], //text()) ')

select @.my

//--Code-

That ususally is done using recursion. But provided SQL Server doesn't support user-defined functions in XQuery it seems to be unfeasible to implement. Another workaround would be using XSLT.

Are you sure you need such kind of filtering? You said you only need to query some node, not filtering XML tree.

|||

Another way to write it would be to use the nodes() method to generate a relational rowset that contains Name, Id and ParentID (see the other posting for code samples), then write a recursive relational user-defined function that recomposes the hierarchy (see the FOR XML whitepaper for a code sample).

However, what I assume in your case, is that the logging of the changes is slowing you down. Have you checked what your data and IO disk load is? Do you have your log file on a different disk drive/disk spindle than your data?

Best regards

Michael

No comments:

Post a Comment