我想删除表'T250'中已知字符'''和表达式'[G56]'之间的字符串'F250N'中的所有值
这还需要涵盖无法找到前面的char的情况,例如。在字符串的开头。
例如:
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]
之前的字符串部分到最后]
答案 0 :(得分: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 @s=@left+@right
end else begin
set @s=@right
end
end else begin
break
end
--fuse
if len(@s)=@lenbefore break
end
--persist
update t set t.F250N=@s from @T250 t where t.pk=@pk
--advance
fetch next from c into @pk, @s
end
close c
deallocate c
--after
select F250N from @T250
我没有测试边框情况,但至少它不会进入无限循环。
答案 1 :(得分:0)
如果没有像Oracle一样的所有tom-foolery,我仍然无法决定是否喜欢T-SQL而不支持regex
...
有些人在面对问题时会想到,我知道,我会使用正则表达式。"现在他们有两个问题。 - Programming Aphorism
老实说,这看起来像是一个正则表达式问题(除了数据库设计问题)。虽然T-SQL是正则表达式,但它可以通过CLR支持。
了解更多here。一帆风顺!
答案 2 :(得分: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