2017-02-09 65 views
1

我想删除字符串中已知字符']'和表达式'[G56]'之间的字符串类型字符串'F250N'中的所有值表'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

当你声明“一个已知的char']'”时,当以[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的,不用所有tom-foolery像Oracle不支持regex不能决定...

一些人,当遇到一个问题,认为“我知道,我会用正则表达式。“现在他们有两个问题。 - Programming Aphorism

老实说,这看起来像一个正则表达式问题(抛开数据库设计问题)。尽管T-SQL是正规表达式,但它可以通过CLR来支持。

了解更多here。一帆风顺!

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

相关问题