【问题标题】:SQL string manipulation to add xml nodesSQL 字符串操作以添加 xml 节点
【发布时间】:2017-02-26 02:50:31
【问题描述】:

我正在使用 sql 2008R2,该表具有类似 xml 列-

<New>
   <From>
        <Scale>Tony</Scale>
        <ScaleName>Name</ScaleName>
    </From>
</New>
<New>
    <From>
        <Scale>Tom</Scale>
        <ScaleName>Name</ScaleName>
    </From>
</New>

 <New>
    <From>
        <Scale>Seven</Scale>
        <ScaleName>Height</ScaleName>
    </From>
</New>
<New>
    <From>
        <Scale>Ten</Scale>
        <ScaleName>Height</ScaleName>
    </From>
</New>
<New>
    <From>
        <Scale>***XXX***</Scale>
        <ScaleName>Height</ScaleName>
   </From>
</New>

.......等等

我需要编写一个 SQL,它可以检查 ScaleName 的 Scale 没有 XXX 作为值的所有节点,然后添加/插入以下文本,为 2次。当只有一个 ***XXX**** 条目时,它应该只添加/插入一次

<New>
    <From>
        <Scale>***XXX***</Scale>
        <ScaleName>Respective Scalename</ScaleName>
    </From>
</New>  

预期结果-----

<New>
   <From>
        <Scale>Tony</Scale>
        <ScaleName>Name</ScaleName>
    </From>

<New>
    <From>
        <Scale>Tom</Scale>
        <ScaleName>Name</ScaleName>
    </From>
</New>
<New>
   <From>
        <Scale>***XXX***</Scale>
        <ScaleName>Name</ScaleName>
    </From>
</New>
<New>

   <From>
        <Scale>***XXX***</Scale>
        <ScaleName>Name</ScaleName>
    </From>
</New>


 <New>
    <From>
        <Scale>Seven</Scale>
        <ScaleName>Height</ScaleName>
    </From>
 </New>
 <New>
    <From>
        <Scale>Ten</Scale>
        <ScaleName>Height</ScaleName>
    </From>
 </New>
 <New>
    <From>
        <Scale>***XXX***</Scale>
        <ScaleName>Height</ScaleName>
   </From>
 </New>
 <New>
    <From>
        <Scale>***XXX***</Scale>
        <ScaleName>Height</ScaleName>
    </From>
</New>

【问题讨论】:

  • 然后在没有的地方添加文本,重复 2 次​​i> - 显示预期结果的外观
  • 您的 XML 真的没有根元素吗(不是不可能,但不是最佳选择...)?请解释一下,add/insert the following text, for 2 times 是什么意思。我没有看到任何 以下文本 以及您想在哪里/为什么/什么插入两次?正如@RomanPerekhrest 已经问过的那样:请提供预期的输出和您迄今为止尝试过的代码......
  • add/insert 表示添加 XML 代码。 Java basd 应用程序需要此代码。每个唯一的 scalename 的 XXX 条目需要 2 次​​span>
  • XXX 条目 = ***XXX***各自的Scalename跨度>
  • 预期结果 - 预期结果 -----

标签: sql-server xml string tsql sql-server-2008-r2


【解决方案1】:

我不知道我是否完全理解您的需要,但这可能会有所帮助:

注意:大多数情况下是这样! - 使用 magic 值(例如 ***XXX***...

是个坏主意

这是您的示例 XML。标尺Name 没有***XXX*** 条目,而标尺height 有一个...

DECLARE @xml XML=
(N'<New>
  <From>
    <Scale>Tony</Scale>
    <ScaleName>Name</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>Tom</Scale>
    <ScaleName>Name</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>Seven</Scale>
    <ScaleName>Height</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>Ten</Scale>
    <ScaleName>Height</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>***XXX***</Scale>
    <ScaleName>Height</ScaleName>
  </From>
</New>');

--CTE 将 XML 读入派生表中,省略带有 ***XXX*** 的条目

WITH ScaleNames AS
(
    SELECT  fr.value('(Scale)[1]','nvarchar(100)') AS Scale
           ,fr.value('(ScaleName)[1]','nvarchar(100)') AS ScaleName
    FROM @xml.nodes('/New/From') AS A(fr)
    WHERE fr.value('(Scale)[1]','nvarchar(100)')<>'***XXX***'
)

--SELECT 将使用 real 值重建整个 XML,并添加两倍的 ***XXX*** 节点。

SELECT (
            SELECT x.Scale AS [From/Scale]
                  ,x.ScaleName AS [From/ScaleName]
            FROM ScaleNames AS x
            WHERE x.ScaleName=ScaleNames.ScaleName
            FOR XML PATH('New'),TYPE
       )
      ,(SELECT
        (SELECT '***XXX***' AS Scale, ScaleName FOR XML PATH('From'),ROOT('New'),TYPE )
        ,(SELECT '***XXX***' AS Scale, ScaleName FOR XML PATH('From'),ROOT('New'),TYPE )
        FOR XML PATH(''),TYPE
       ) AS [node()]
FROM ScaleNames
GROUP BY ScaleName
FOR XML PATH('')

结果

<New>
  <From>
    <Scale>Seven</Scale>
    <ScaleName>Height</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>Ten</Scale>
    <ScaleName>Height</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>***XXX***</Scale>
    <ScaleName>Height</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>***XXX***</Scale>
    <ScaleName>Height</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>Tony</Scale>
    <ScaleName>Name</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>Tom</Scale>
    <ScaleName>Name</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>***XXX***</Scale>
    <ScaleName>Name</ScaleName>
  </From>
</New>
<New>
  <From>
    <Scale>***XXX***</Scale>
    <ScaleName>Name</ScaleName>
  </From>
</New>

【讨论】:

  • 哇!那太酷了,我会检查并更新。关于魔术词,它是java前端下拉列表的一部分。非常感谢。
  • 顺便说一句,有没有办法通过将 xml 读取为字符串来完成它。以防万一
  • @Priya,很高兴为您提供帮助!如果您喜欢这样,最好在答案的投票计数器下方勾选接受检查。关于读取 XML 作为字符串:只要字符串包含有效的 XML,DECLARE @xml XML=(SELECT CAST(@SomeValidXML AS XML)) 就会简单地完成。最好使用NVARCHAR 类型的变量,但要确保XML 不以utf-8 的声明开头。如果您将 XML 作为文字,最好在字符串前面添加一个 N 以获取它 unicode (DECLARE @myXML NVARCHAR(MAX)=N'some xml here')
  • 我是新来的,请有任何可能分享您的反馈或评分
  • @Priya 分享你的反馈或评分是什么意思?
猜你喜欢
  • 1970-01-01
  • 2023-04-06
  • 2012-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
  • 1970-01-01
相关资源
最近更新 更多