2017-02-09 10 views
1

Я хотел бы удалить все значения в столбце «F250N» строки типа между известным символом char] и выражением «[G56]» в Таблица 'T250'Как удалить значения строки между символом и выражением - SQL Server

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

Например:

SYSADMIN[G63]Z-GHQ[G62]Z-WE[G56]Z-MEX[G56]Z-NAZ[G56]Z-LAS[G56]Z-LAN[G56]Z-CEE[G56]Z-APAC[G56]Z-CAD[G56] 

бы стать:

SYSADMIN[G63]Z-GHQ[G62] 

и:

LVN-CHNG[G62]LVN-READ[G56]LVN-FULL[G63] 

бы стать:

LVN-CHNG[G62]LVN-FULL[G63] 

До сих пор я пытался что-то вроде:

update T250 
set F250N = replace(F250N, '[G56]', '') 
from T250 

однако это не учитывает часть строки предыдущего [G56] до последнего ]

+1

, когда вы заявляете «известный символ»], «а как насчет граничного случая, когда токен, завершенный с помощью [G56], будет первым? – dlatikay

+0

Ваш желаемый результат гораздо более активен, чем ваш вопрос. Второй пример - это не удаление символов после символа ']', а вместо цепочки '[G62] LVN-'. Пожалуйста, будьте более конкретными по правилам здесь. – iamdave

+1

в более длинном примере все оставшиеся «токены» заканчиваются на [G56], поэтому нам нужно вырезать все вхождения, а не только первые. – dlatikay

ответ

1

не мог придумать, как решить эту инлайн, в статья UPDATE. Таким образом, было бы это процедурный подход:

set nocount on 

declare 
    @T250 table(pk int primary key, F250N nvarchar(max)) 
declare 
    @s nvarchar(max), 
    @pk int, 
    @i int, 
    @left nvarchar(max), 
    @right nvarchar(max), 
    @lenbefore int 

insert @T250 values 
    (1, N'SYSADMIN[G63]Z-GHQ[G62]Z-WE[G56]Z-MEX[G56]Z-NAZ[G56]Z-LAS[G56]Z-LAN[G56]Z-CEE[G56]Z-APAC[G56]Z-CAD[G56]'), 
    (2,N'LVN-CHNG[G62]LVN-READ[G56]LVN-FULL[G63]') 

--before 
select F250N from @T250 

declare c cursor for select pk, F250N from @T250 
where F250N like N'%[[]G56]%' --skip rows that do not even contain the marker 
open c 
fetch next from c into @pk,@s 
while @@FETCH_STATUS=0 begin 
    --handle single value 
    set @lenbefore=len(@s) 
    while @s like N'%[[]G56]%' begin 
    set @i=CHARINDEX(N'[G56]', @s) 
    if @i>0 begin 
     set @right=SUBSTRING(@s, @i+len(N'[G56]'),len(@s)) 
     set @left = REVERSE(substring(@s, 1, @i - 1)) 
     if @i>0 begin 
     set @left=reverse(SUBSTRING(@left,@i,len(@left))) 
     set @[email protected][email protected] 
     end else begin 
     set @[email protected] 
     end 
    end else begin 
     break 
    end 
    --fuse 
    if len(@s)[email protected] break 
    end 
    --persist 
    update t set [email protected] from @T250 t where [email protected] 
    --advance 
    fetch next from c into @pk, @s 
end 
close c 
deallocate c 

--after 
select F250N from @T250 

я не проверял на пограничных случаях, но, по крайней мере, это не будет идти в бесконечный цикл.

0

Я до сих пор не могу решить, если я люблю или ненавижу T-SQL для поддержки не regex без всех tom-foolery, как Oracle делает ...

Некоторые люди, сталкиваясь с проблемой, думаю «я Знаю, я буду использовать регулярные выражения ». Теперь у них есть две проблемы. - Programming Aphorism

Честно говоря, это похоже на проблему с регулярным выражением (вопросы по дизайну базы данных в стороне). Хотя T-SQL не поддерживает regex, он может поддерживаться через CLR.

Подробнее here. Godspeed!

0

Здесь моя трещина. Сначала найдите функцию разделения. Вот тот, который я использовал: http://www.sqlservercentral.com/blogs/querying-microsoft-sql-server/2013/09/19/how-to-split-a-string-by-delimited-char-in-sql-server/

Это работает для обоих образцов. Предоставьте больше, и мы увидим.

IF OBJECT_ID('tempdb..#holdingtable') IS NOT NULL 
    DROP TABLE #holdingtable 

--DECLARE @ VARCHAR(1000) = REPLACE('SYSADMIN[G63]Z-GHQ[G62]Z-WE[G56]Z-MEX[G56]Z-NAZ[G56]Z-LAS[G56]Z-LAN[G56]Z-CEE[G56]Z-APAC[G56]Z-CAD[G56]', '[G56]', ',') 

declare @ varchar(1000) = REPLACE('LVN-READ[G56]LVN-CHNG[G62]LVN-READ[G56]LVN-FULL[G63]LVN-READ[G56]', '[G56]', ',') 
SELECT * 
INTO #holdingtable 
FROM [fnSplitString](@, ',') 

IF (
     SELECT COUNT(*) 
     FROM #holdingtable 
     WHERE splitdata LIKE '%[[]%' 
     ) > 1 
BEGIN 
     ; 

    WITH cte 
    AS (
     SELECT LEFT(splitdata, LEN(splitdata) - CHARINDEX(']', REVERSE(splitdata)) + 1) AS col_ 
     FROM #holdingtable 
     WHERE LEFT(splitdata, LEN(splitdata) - CHARINDEX(']', REVERSE(splitdata)) + 1) LIKE '%[[]%' 
     ) 
    SELECT col_ AS [text()] 
    FROM cte 
    ORDER BY col_ 
    FOR XML PATH('') 
END 
ELSE IF (
     SELECT COUNT(*) 
     FROM #holdingtable 
     WHERE splitdata LIKE '%[[]%' 
     ) = 1 
BEGIN 
    SELECT LEFT(splitdata, LEN(splitdata) - CHARINDEX(']', REVERSE(splitdata)) + 1) 
    FROM #holdingtable 
    WHERE LEFT(splitdata, LEN(splitdata) - CHARINDEX(']', REVERSE(splitdata)) + 1) LIKE '%[[]%' 
END 
+0

маленькое редактирование в ветви> 1 – dfundako

 Смежные вопросы

  • Нет связанных вопросов^_^