编辑:我的应用程序中有大约80个字符导致问题,因此我不想为每个字符硬编码REPLACE。我认为用两列“特殊字符”和“替换字符”创建一个单独的表会更容易,我将从包含“StringTest”列的原始表中删除这些列。我的目标是找出如何使用字符表替换字符串表中的字符。
我试图用SQL Server中的“MappedCharacters”(A,AE,C)替换所有“特殊字符”(即À,Æ,Ç)。我尝试了两种不同的技术,一种使用光标,一种没有光标,搜索字符串并用映射的字符替换所有特殊字符。我的每个方法只替换它们与字符串在同一行中的字符。 以前的例子:
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
因此,您可以看到我想要替换StringTest中的所有“特殊字符”,但只有同一行中的字符才会被替换。
我还没有想出如何做到这一点。
以下是我一直试图修改的两个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
答案 0 :(得分:5)
试试这个,它比循环更好,因为只有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
答案 1 :(得分:1)
我会创建一个单独的映射表,其中包含坏字符及其对应的好字符,每行一组。然后遍历该表并为每个字符集执行替换。
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
答案 2 :(得分:0)
update table
set column = REPLACE(column,'À','A')
where column like ('%À%')
update table
set column = REPLACE(column,'Æ','AE')
where column like ('%Æ%')
我会把第3个留给你
或者这可能更有效
update table
set column = REPLACE(REPLACE(column,'À','A'),'Æ','AE')
where column like ('%À%')
or column like ('%Æ%')
如果你真的想处理一个映射字符列表,那么这不是一个正确的答案
答案 3 :(得分:0)
知道表中有多少行以及估计有多少行具有“特殊字符”会很有帮助。还有,只有3个特殊字符吗?如果你有40个或更少的特殊字符,它可能看起来很荒谬,但我只是嵌套尽可能多的REPLACE()调用,因为你有特殊字符,如:
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
答案 4 :(得分:0)
@ t-clausen.dk回答Table变量和临时表,只是为了避免人们用其他表来搞乱他们的dev数据库。
表变量:
-- 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
使用Temp表:
-- 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