Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用SQL Server在子节点中按值查找所有父节点_Sql_Sql Server - Fatal编程技术网

如何使用SQL Server在子节点中按值查找所有父节点

如何使用SQL Server在子节点中按值查找所有父节点,sql,sql-server,Sql,Sql Server,我不熟悉SQL Server中的XML查询。我想写一个查询 在子节点中查找值并删除其父节点 在子节点中重新排序项目顺序 如下面的示例所示:我的列的类型为nvarchar(max)并存储值: <Trainings> <Training> <Id>10</Id> <Data>test1</Data> <ItemOrder>1</ItemOrder>

我不熟悉SQL Server中的XML查询。我想写一个查询

  • 在子节点中查找值并删除其父节点
  • 在子节点中重新排序项目顺序
  • 如下面的示例所示:我的列的类型为
    nvarchar(max)
    并存储值:

    <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>
    

    这里是Fiddle链接:

    只需对搜索的谓词使用XPath即可

    set @xml.modify('delete (/Trainings/Training[./Data = "test12"])')
    
    更新:为了解决第二个问题,我建议使用完全不同的XML关系方法:

    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
    

    正如我所测试的,您的查询很好地将
    Training
    节点从
    test12
    中删除,这是我的第一点。在我看来,这很好,因为一个简单的查询,但它得到了最好的性能?你知道第二点吗?@HuyDQ对不起,我没有注意到第二点。这将是相当棘手的。我的想法是派生一个关系表,添加具有适当计数的新列,然后再次提取XML…@HuyDQ类似这样的内容:这将是一个好主意。但是,不可能添加一个新列:(.我的意思是,您有没有想法为第二点编写查询?@HuyDQ问题是用一个包含您需要的数据的新列替换
    ItemOrder
    列。不,我不知道如何编写它。
    set @xml.modify('delete (/Trainings/Training[./Data = "test12"])')
    
    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