Обработка строк SQL для добавления узлов xml

#sql-server #xml #string #tsql #sql-server-2008-r2

#sql-сервер #xml #строка #tsql #sql-server-2008-r2

Вопрос:

Я использую 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 не имеет значения 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>
 

Комментарии:

1. затем добавьте текст там, где его нет, в 2 раза — покажите, как должен выглядеть ожидаемый результат

2. Действительно ли ваш XML без корневого элемента (не невозможно, но не лучший выбор …)? И, пожалуйста, объясните, что вы имеете в виду, добавляя / вставляя следующий текст, в 2 раза . Я не вижу никакого следующего текста и где / почему / что вы хотите вставить два раза? Как уже спрашивал @Romanperekhr: пожалуйста, укажите ожидаемый результат и код, который вы пробовали до сих пор…

3. добавление / вставка означает добавление кодов XML. Этот код требуется для приложения Java basd. Записи XXX должны быть 2 раза для каждого уникального scalename

4. XXX записи = <Новый> <Из> <Масштаб> ***XXX***</Scale> <Имя масштаба>Соответствующее имя масштаба</ScaleName> </From> </New>

5. ожидаемый результат ниже ОЖИДАЕМОГО РЕЗУЛЬТАТА ——

Ответ №1:

Я не знаю, полностью ли я понял, что вам нужно, но это может помочь:

внимание: это — в большинстве случаев! — плохая идея работать с магическими значениями, такими как ***XXX***

Это ваш пример XML. У scale Name нет ***XXX*** записи, а у scale 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 позволит перестроить весь 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>
 

Комментарии:

1. вау!!! это супер круто, я проверю и обновлю. что касается magic word, то это часть выпадающего списка java frontend. Большое вам спасибо.

2. кстати, есть ли какой-нибудь способ сделать это, прочитав xml как строку. на всякий случай

3. @Priya, рад вам помочь! Если вам это нравится, было бы любезно поставить галочку под счетчиком голосов для ответа. О чтении XML как строки : пока строка содержит допустимый XML, это просто выполняется DECLARE @xml XML=(SELECT CAST(@SomeValidXML AS XML)) . Лучше всего использовать переменную типа NVARCHAR , но убедитесь, что XML не начинается с объявления with utf-8 . Если у вас есть XML как литерал, лучше всего добавить a N перед строкой, чтобы получить его unicode (ОБЪЯВИТЬ @myXML NVARCHAR(MAX)=N’ some xml here’)

4. Я здесь новичок, любая возможность поделиться отзывом или рейтингом, пожалуйста

5. @Priya Что вы имеете в виду, говоря поделиться отзывами или рейтингом ?