Найти значение между некоторыми символами - PullRequest
1 голос
/ 25 марта 2020

У меня есть значения между этим символом (<>). Мне нужно написать запрос, который будет их извлекать.

Например, учитывая следующее:

DECLARE @a VARCHAR(MAX) = N'(<1002>+<1003>+<1004>+<1048>+<1049>+<1050>)/(<1400>*2)'

Я хотел бы извлечь следующие значения в таблицу:

table 
1002
1003
1004
1048
1049
1050
1400

Ответы [ 3 ]

1 голос
/ 25 марта 2020

Это можно выразить немного проще:

DECLARE @yourStr VARCHAR(MAX) = N'(<1002>+<1003>+<1004>+<1048>+<1049>+<1050>)/(<1400>*2)';

SELECT AllX.value('@z','int')
FROM (VALUES (CAST(REPLACE(REPLACE(@yourStr,'<','<x z="'),'>','" />') AS XML))) A(Casted)
CROSS APPLY A.Casted.nodes('/x') B(AllX);

Вот и все: -)

Идея вкратце:

Заменив < и > мы можем создать (не правильно сформированный) XML следующим образом:

(<x z="1002" />+<x z="1003" />+<x z="1004" />+<x z="1048" />+<x z="1049" />+<x z="1050" />)/(<x z="1400" />*2)

T- SQL может иметь дело с фрагментами , поэтому мы можем использовать .nodes('/x') прочитать все элементы <x> на уровне root. Любой другой контент - это просто шум между элементами, плавающий вокруг в text() узлах, которые мы можем игнорировать.

Мы просто читаем z -атрибут и возвращаем его как int.

0 голосов
/ 25 марта 2020

Вы можете достичь того, что вы хотите, с помощью функции REPLACE для удаления любых ненужных символов, а затем выполнить инструкцию с помощью SP_EXECUTE SQL следующим образом: -

Create table #TempTable (col1 int)

DECLARE @a VARCHAR(MAX) = N'(<1002>+<1003>+<1004>+<1048>+<1049>+<1050>)/(<1400>*2)'

Declare @SqlStatement  NVARCHAR(MAX) =  'Insert into #TempTable Values ' + 

REPLACE(Replace(REPLACE(REPLACE(Replace(REPLACE(@a,'<',''),'>',''),'/(','+'),')+','+'),'*2',''),'+','),(')

Exec sp_executesql @SqlStatement 

Select * from #TempTable

Drop table #TempTable

Результат: -

col1
1002
1003
1004
1048
1049
1050
1400
0 голосов
/ 25 марта 2020

Это будет действительно легко сделать, если вы реализуете SQL функции регулярного выражения CLR, но если у вас нет времени или навыков, вы можете использовать что-то вроде этого:

DECLARE @a VARCHAR(MAX) = N'(<1002>+<1003>+<1004>+<1048>+<1049>+<1050>)/(<1400>*2)'

SET @A = REPLACE(@A, '<', 'lt;');
SET @A = REPLACE(@A, '>', 'gt;');

DECLARE @xml XML

SET @xml = '<node>' + REPLACE(@A, 'gt;', '</node><node>') + '</node>'


SELECT ROW_NUMBER() OVER (ORDER BY T.c)
      ,SUBSTRING(T.c.value('.', 'VARCHAR(MAX)'), CHARINDEX('lt;', T.c.value('.', 'VARCHAR(MAX)')) + 3, 1024)
FROM @xml.nodes('node') T(c)
WHERE CHARINDEX('lt;', T.c.value('.', 'VARCHAR(MAX)')) >0;

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...