tSQL - 替换字符串中的所有"ASCII/special characters"



编辑:我有大约80个字符在应用程序中引起问题,因此我不想为每个字符替换替换。我认为使用两个列"特殊字符"one_answers"替换字符"创建一个单独的表会更容易,我将从原始表中删除这些列,其中包含" StringTest"列。我的目标是弄清楚如何使用字符表替换字符串表中的字符。

我试图用SQL Server中的" MappedCharacters"(A,AE,C)替换所有"特殊字符"(即,IEà,æ,ç)。我尝试了两种不同的技术,一种使用光标,一个没有光标的技术来搜索字符串,并用映射的字符替换所有特殊字符。我的每种方法仅替换它们与字符串在同一行中的字符。以前的示例:

num   SpecialCharacter    MappedCharacter    StringTest
 1           À                   A             StringÀÆ
 2           Æ                   AE            ÆStringÆ
 3           Ç                   C             StrÇÀing

示例之后:

num   SpecialCharacter    MappedCharacter    StringTest
 1           À                   A             StringAÆ
 2           Æ                   AE            AEStringAE
 3           Ç                   C             StrCÀing

首选输出:

num   SpecialCharacter    MappedCharacter    StringTest
 1           À                   A             StringAAE
 2           Æ                   AE            AEStringAE
 3           Ç                   C             StrCAing

因此,您可以看到我想在字符串测试中替换所有"特殊字符",但只有同一行中的字符被替换。

我还没有弄清楚该怎么做。

这是我一直在尝试修改的两个SQL代码(我只需要一个可以工作)

第一个方法:

              DECLARE @cASCIINum INT;
              DECLARE @cSpecialChar VARCHAR(50);
              DECLARE @cMappedChar VARCHAR(50);
              DECLARE @cStringTest VARCHAR(50);
              DECLARE @mapCursor as CURSOR;
              SET @mapCursor = CURSOR FOR
              SELECT [ASCIINum]
                    ,[SpecialChar]
                    ,[MappedChar]
                    ,[StringTest]
              FROM [intranet].[dbo].[CharMapTestTab]; 
              OPEN @mapCursor;
              FETCH NEXT FROM @mapCursor INTO @cASCIINum,
                                              @cSpecialChar,
                                              @cMappedChar,
                                              @cStringTest;
                WHILE @@FETCH_STATUS = 0
                BEGIN
                  UPDATE [intranet].[dbo].[CharMapTestTab]
                  SET StringTest = REPLACE(StringTest, SpecialChar, MappedChar)
                  WHERE SpecialChar <> MappedChar
                END
                CLOSE @mapCursor;
                DEALLOCATE @mapCursor;

第二种方法:

            DECLARE @ASCIINum INT = 0
            WHILE (1 = 1) 
            BEGIN  
              SELECT @ASCIINum = ASCIINum
              FROM [intranet].[dbo].[CharMapTestTab]
              WHERE ASCIINum > @ASCIINum 
              ORDER BY ASCIINum
              IF @@ROWCOUNT = 0 BREAK;
                  UPDATE [intranet].[dbo].[CharMapTestTab]
                  SET StringTest = REPLACE(StringTest, SpecialChar, MappedChar)
                  WHERE SpecialChar <> MappedChar

              SELECT TOP 1000 [ASCIINum]
                  ,[SpecialChar]
                  ,[MappedChar]
                  ,[StringTest]
              FROM [intranet].[dbo].[CharMapTestTab]

            END

尝试一下,它比循环效果更好,因为只有1个更新:

-- create test table vc
create table vc(StringTest varchar(20))
insert vc values('StringÀÆ'), ('ÆStringÆ')
go
-- create test table CharacterMapping
create table CharacterMapping(SpecialCharacter char(1), MappedCharacter varchar(2))
insert CharacterMapping values('À', 'A'),('Æ', 'AE'), ('Ç', 'C')
go
--build the varchar for updating
declare @x varchar(max) = 'StringTest'
select @x = 'replace('+@x+', ''' + SpecialCharacter + ''','''+MappedCharacter+''')'  
from CharacterMapping
set @x = 'update vc set StringTest=' + @x +' from vc'
exec (@x)
select * from vc

结果:

StringAAE
AEStringAE

我将制作一个单独的映射表,其中包含不良字符及其相应的良好字符,每行一组。然后循环在该表上,对每个字符集进行替换。

DECLARE @map TABLE (
    id INT,
    badChar CHAR,
    goodChar CHAR
)
DECLARE @strings TABLE (
    searchString VARCHAR(50)
)
INSERT INTO @map 
VALUES 
(1, 'y', 'a'),
(2, 'z', 'b')
DECLARE @curRow INT, @totalRows INT
SET @curRow = 1
SELECT @totalRows = COUNT(*) FROM @map
INSERT INTO @strings
VALUES
('zcccyccz'),
('cccyccz')
WHILE @curRow <= @totalRows
BEGIN
    UPDATE @strings 
    SET searchString = REPLACE(searchString, badChar, goodChar) 
    FROM @map 
    WHERE id = @curRow
    SET @curRow = @curRow + 1
END
SELECT * FROM @strings
--Output
--bcccaccb
--cccaccb

知道桌上有多少行以及您估计有多少个具有"特殊字符"的行会很有帮助。另外,只有3个特殊字符吗?如果您有40个或更少的特殊字符,它看起来可能很荒谬,但是我会像以下特殊字符一样嵌套替换()呼叫,例如:

UPDATE YourTable SET YourColumn = REPLACE(
                                  REPLACE(
                                  REPLACE(YourColumn,'Ç','C')
                                  ,'Æ','AE')
                              ,'À','A')

如果大多数行具有特殊字符,我会跳过任何WHERE。如果只有几行具有特殊字符,我会使用CTE来识别它们:

;WITH AllSpecialRows AS
(
SELECT PrimaryKey FROM YourTable WHERE YourColumn LIKE '%À%'
UNION 
SELECT PrimaryKey FROM YourTable WHERE YourColumn LIKE '%Æ%'
UNION 
SELECT PrimaryKey FROM YourTable WHERE YourColumn LIKE '%Ç%'
)
UPDATE y
    SET YourColumn = REPLACE(
                     REPLACE(
                     REPLACE(YourColumn,'Ç','C')
                     ,'Æ','AE')
                     ,'À','A')
    FROM YourTable                  y
        INNER JOIN AllSpecialRows   s ON y.PrimaryKey =s.PrimaryKey
update table  
set column = REPLACE(column,'À','A') 
where column like ('%À%') 
update table  
set column = REPLACE(column,'Æ','AE') 
where column like ('%Æ%') 

我将把第三留给你

或这可能更有效

update table  
set column = REPLACE(REPLACE(column,'À','A'),'Æ','AE')
where column like ('%À%') 
   or column like ('%Æ%')

如果您真的想处理映射的字符列表,那么这不是一个正确的答案

@t-clausen.dk带有表变量和临时表的答案,只是为了避免人们用其他表搞砸他们的开发数据库。

表变量:

-- Create test table variable @CharacterMapping
DECLARE @CharacterMapping TABLE (SpecialCharacter char(1), MappedCharacter varchar(2))
INSERT @CharacterMapping VALUES('À', 'A'), ('Æ', 'AE'), ('Ç', 'C')
--Build the varchar for updating
DECLARE @x varchar(max) = 'StringTest'
SELECT @x = 'replace('+@x+', ''' + SpecialCharacter + ''',''' + MappedCharacter + ''')'  
FROM @CharacterMapping
SET @x = 'DECLARE @vc TABLE(StringTest varchar(20));'
        + ' insert @vc values(''StringÀÆ''), (''ÆStringÆ'');'
        + 'update @vc set StringTest=' + @x +' from @vc;' 
        + 'SELECT * FROM @vc;'
Exec (@x)
GO

带有临时表:

-- Create test temp table #vc
CREATE TABLE #vc(StringTest varchar(20))
INSERT #vc VALUES('StringÀÆ'), ('ÆStringÆ')
-- Create test table CharacterMapping
DECLARE @CharacterMapping TABLE (SpecialCharacter char(1), MappedCharacter varchar(2))
INSERT @CharacterMapping VALUES('À', 'A'), ('Æ', 'AE'), ('Ç', 'C')
--Build the varchar for updating
DECLARE @x varchar(max) = 'StringTest'
SELECT @x = 'replace('+@x+', ''' + SpecialCharacter + ''',''' + MappedCharacter + ''')'  
FROM @CharacterMapping
SET @x = 'update #vc set StringTest=' + @x +' from #vc'
-- Execute
EXEC (@x)
-- Select the results 
SELECT * FROM #vc;
-- Drop temp table
DROP TABLE #vc;
GO

最新更新