简体   繁体   中英

How to find all parent node by a value in child node with SQL Server

I am new to XML queries in SQL Server. I would like write a query that

  1. Finds a value in child node and to remove its parent node
  2. Re-orders items order in child node

As my example below: my column's type is nvarchar(max) and stores value:

<Trainings>
    <Training>
        <Id>10</Id>
        <Data>test1</Data>
        <ItemOrder>1</ItemOrder>
    </Training> 
    <Training>
        <Id>12</Id>
        <Data>test12</Data>
        <ItemOrder>2</ItemOrder>
    </Training>
    <Training>
        <Id>101</Id>
        <Data>test111</Data>
        <ItemOrder>3</ItemOrder>
    </Training> 
    <Training>
        <Id>102</Id>
        <Data>test122</Data>
        <ItemOrder>4</ItemOrder>
    </Training> 
</Trainings>

The expected result must be:

<Trainings>
    <Training>
        <Id>10</Id>
        <Data>test1</Data>
        <ItemOrder>1</ItemOrder>
    </Training> 
    <Training>
        <Id>101</Id>
        <Data>test111</Data>
        <ItemOrder>2</ItemOrder>
    </Training> 
    <Training>
        <Id>102</Id>
        <Data>test122</Data>
        <ItemOrder>3</ItemOrder>
    </Training> 
</Trainings>

I've tried with the query as below but how can I find the Training node number with test12 in Data child? and then reorder all ItemOrder for all Training nodes.

CREATE TABLE Resume ([Training] nvarchar(max));

INSERT INTO Resume ([Training])
VALUES ('<Trainings><Training><Id>10</Id><Data>test1</Data><ItemOrder>1</ItemOrder></Training><Training><Id>12</Id><Data>test12</Data><ItemOrder>2</ItemOrder></Training><Training><Id>101</Id><Data>test111</Data><ItemOrder>3</ItemOrder></Training><Training><Id>102</Id><Data>test122</Data><ItemOrder>4</ItemOrder></Training></Trainings>');

DECLARE @string NVARCHAR(MAX)

SELECT @string = [Training] 
FROM Resume

DECLARE @xml XML

SET @xml = CONVERT(XML, @string)
SET @xml.modify('delete (/Trainings/Training)[2]')
SET @string = CONVERT(NVARCHAR(MAX), @xml)

SELECT @string

Here is the Fiddle link: http://sqlfiddle.com/#!6/894a0/3

Just use XPath with the predicate you search

set @xml.modify('delete (/Trainings/Training[./Data = "test12"])')

UPDATE: in order to solve also the second issue I propose to use a completely different XML-relational approach:

SELECT c.value('(./Id/node())[1]','int') AS Id,
       c.value('(./Data/node())[1]','nvarchar(max)') AS Data,
       row_number() over (order by c.value('(./Id/node())[1]','int')) as ItemOrder
FROM @xml.nodes('/Trainings/Training') AS A(c)
WHERE c.value('(./Data/node())[1]','nvarchar(max)') != 'test12'
FOR XML PATH('Training'),ROOT('Trainings'),TYPE

demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM