Ваш собственный код выглядит так, как будто вы хотите получить несколько повторяющихся элементов из XML.Поэтому вы используете цикл WHILE для чтения первого, второго, n-го значения одно за другим.Правильно ли пока?
Предположительно, вы действительно ищете это:
--create a mockup-table with two rows
DECLARE @tbl TABLE(ID INT IDENTITY, SomeXml XML);
INSERT INTO @tbl VALUES
('<a>
<b>b11</b>
<b>b12</b>
<b>b13</b>
<b>b14</b>
<b>b15</b>
</a>>')
,('<a>
<b>b21</b>
<b>b22</b>
<b>b23</b>
</a>');
- Запрос
SELECT b.value('text()[1]','varchar(10)')
FROM @tbl t
CROSS APPLY t.SomeXml.nodes('/a/b') A(b);
Метод .nodes()
будет возвращать каждый <b>
в одной строке как производная таблица (имя таблицы A
, имя столбца b
. Вы можете установить оба имени так, как вам нравится. Возвращаемый столбец имеет тип XML, и онявляется относительным фрагментом. В этом столбце для извлечения содержимого используется метод .value()
.
Некоторые подсказки, как избежать циклов
В любом случае следует избегать циклов всякий раз, когдаВы можете избежать их. Ваш собственный подход может быть решен на основе набора способом с подсчетом на лету :
DECLARE @count INT=5;
WITH Tally(Nmbr) AS (SELECT TOP(@count) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values)
SELECT t.ID
,Nmbr
,t.SomeXml.value('(/a/b[sql:column("Nmbr")])[1]','varchar(10)') AS Numbered_B
FROM @tbl t
CROSS JOIN Tally;
Это будетиспользуйте список от 1 до 5, чтобы прочитать элементы XML по их позиции, используя sql:column()
. Вторая строка вернет два NULL-значения, так как нет четвертого или пятого элемента.
Мы могли бы дажеиспользуйте динамически создаваемый список номеров
Но вы даже можете создать Tally-on-the-fly в зависимости от фактического количества <b>
элементов, как здесь:
SELECT t.ID
,Nmbr
,t.SomeXml.value('(/a/b[sql:column("Nmbr")])[1]','varchar(10)') AS Numbered_B
FROM @tbl t
CROSS APPLY (SELECT TOP(t.SomeXml.value('count(/a/b)','int')) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values) A(Nmbr);
Это работает как запрос раньше, но будет использовать список от 1 до n, где n найдено динамически.