#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 не начинается с объявления withutf-8
. Если у вас есть XML как литерал, лучше всего добавить aN
перед строкой, чтобы получить егоunicode
(ОБЪЯВИТЬ @myXML NVARCHAR(MAX)=N’ some xml here’)4. Я здесь новичок, любая возможность поделиться отзывом или рейтингом, пожалуйста
5. @Priya Что вы имеете в виду, говоря поделиться отзывами или рейтингом ?