简体   繁体   English

SQL-替换字符串中的所有“ ASCII /特殊字符”

[英]SQL - Replacing all “ASCII/special characters” in a string

Edit: I have about 80 characters that are causing problems in my application so I don't want to hard code a REPLACE for every single character. 编辑:我大约有80个字符会在我的应用程序中引起问题,所以我不想为每个字符硬编码一个REPLACE。 I think it would be easier to create a separate table with two columns,"special characters" and "replacement characters", and I will remove those columns from the original table which contains the column "StringTest". 我认为用两列“特殊字符”和“替换字符”创建一个单独的表会更容易,并且我将从包含“ StringTest”列的原始表中删除这些列。 My goal will be figuring out how to use the characters table to replace characters in the string table. 我的目标是弄清楚如何使用字符表替换字符串表中的字符。

I am trying to replace all "special characters" (ie À, Æ, Ç) with "MappedCharacters" (A, AE, C) in SQL Server. 我正在尝试在SQL Server中将所有“特殊字符”(即À,Æ,Ç)替换为“ MappedCharacters”(A,AE,C)。 I have tried two different techniques, one using a cursor, one without a cursor, to search through a string and replace all special characters with mapped characters. 我尝试了两种不同的技术,一种使用游标,一种不使用游标,以搜索字符串并将所有特殊字符替换为映射字符。 Each of my methods only replaces characters they are in the same row as the string. 我的每个方法仅替换与字符串在同一行中的字符。 Example before: 之前的示例:

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

Example after: 以下示例:

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

Preferred Output: 首选输出:

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

So you can see that I want to replace all "special characters" in StringTest but only characters that are in the same row are getting replaced. 因此,您可以看到我想替换StringTest中的所有“特殊字符”,但是仅替换同一行中的字符。

I haven't quite figured out how to do that just yet. 我还不太清楚该怎么做。

Here are the two SQL code that I have been trying to modify (I only need one to work) 这是我一直试图修改的两个SQL代码(我只需要一个即可工作)

First Method: 第一种方法:

              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;

Second Method: 第二种方法:

            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

Try this, it works better than looping because there is only 1 update: 试试这个,它比循环更好,因为只有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

Result: 结果:

StringAAE
AEStringAE

I would make a separate mapping table which contains the bad character and its corresponding good character, one set per row. 我将创建一个单独的映射表,其中包含坏字符及其对应的好字符,每行一组。 Then loop over that table and do a replace for each character set. 然后遍历该表并为每个字符集进行替换。

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
update table  
set column = REPLACE(column,'À','A') 
where column like ('%À%') 
update table  
set column = REPLACE(column,'Æ','AE') 
where column like ('%Æ%') 

I will leave the 3rd to you 我将第三件事留给你

Or this might be more efficient 或者这可能更有效

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

If you really want to process a list of mapped characters then this is not a proper answer 如果您确实要处理映射的字符列表,那么这不是正确的答案

It would be helpful to know how many rows are in your table and how many you estimate to have "special characters". 了解表中有多少行以及估计有“特殊字符”的行将很有帮助。 Also, are there only 3 special characters? 另外,只有3个特殊字符吗? if you have 40 or less special characters, it may look ridiculous, but I'd just nest as many REPLACE() calls as you have special characters, like: 如果您有40个或更少的特殊字符,则看起来可能很荒谬,但我会嵌套许多REPLACE()调用,因为您有特殊字符,例如:

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

if most rows have special characters, I'd skip any WHERE . 如果大多数行都有特殊字符,我将跳过任何WHERE if only a few rows have special characters, I'd use a CTE to identify them: 如果只有几行具有特殊字符,我将使用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

@t-clausen.dk answer with Table variables and temp tables, just to avoid people mess up their dev databases with additional tables. @ t-clausen.dk回答表变量和临时表,只是为了避免人们用其他表弄乱他们的开发数据库。

TABLE Variables: 表格变量:

-- 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

With Temp table: 带温度表:

-- 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM