SQL Server: применить регулярное выражение с заменой

Nov 09 2020

Вот мой SQL-запрос:

select codi_nivell 
from anc_documents

Примеры данных:

06080100000000
06080100000000
06080100000000
06080100000000
06080100000000
06080100000000
06080100000000
06080100000000
06080100000000
06080100000000
06080100000000
06080100000000

Мне нужно применить это регулярное выражение к моему SQL-запросу:

Во-первых, мне нужен удаленный трейлинг 0.

Затем примените это регулярное выражение, чтобы добавить /каждые две цифры:

regex: \d{2}(?=(?:\d{2})+$) replace: $0/

Есть идеи?

Ответы

GordonLinoff Nov 09 2020 at 11:57

SQL Server не поддерживает регулярные выражения. Но вы можете сделать это, используя некоторые строковые манипуляции и рекурсивные CTE:

with ad as (
      select row_number() over (order by code) as seqnum, replace(rtrim(replace(code, '0', ' ')), ' ', '0') as new_code
      from anc_documents
     ),
     cte as (
      select seqnum, new_code, 0 as offset, 0 as lev
      from ad
      union all
      select seqnum, stuff(new_code, offset + 3, 0, '-'), offset + 3, lev + 1
      from cte
      where offset + 3 < len(new_code) 
     )
select *
from (select max(lev) over (partition by seqnum) as max_lev, cte.*
      from cte
     ) cte
where max_lev = lev;

Вот скрипка db <>.

Tyron78 Nov 09 2020 at 12:29

Вы можете добиться этого, используя XML PATH:

DECLARE @codi_nivell NVARCHAR(100) = (SELECT REVERSE(CAST(REVERSE('06080100000000') AS BIGINT)))

;WITH cte AS(
 SELECT @codi_nivell AS codi_nivell, LEFT(@codi_nivell, 2) AS codi_nivell_left, RIGHT(@codi_nivell, LEN(@codi_nivell)-2) AS codi_nivell_right
 UNION ALL
 SELECT @codi_nivell, LEFT(codi_nivell_right, 2), RIGHT(codi_nivell_right, LEN(codi_nivell_right)-2)
   FROM cte
   WHERE LEN(codi_nivell_right) >= 2
)
SELECT STUFF((SELECT '/' + c2.codi_nivell_left
  FROM cte c2
  FOR XML PATH('')), 1, 1, '') y
  FROM cte c1
  GROUP BY c1.codi_nivell