SQL用循环替换ASCII

时间:2011-02-14 10:15:52

标签: sql sql-server-2008 stored-procedures ascii

我目前正在尝试在SQL中创建存储过程。

但我仍然坚持要求。 我想从nvarchar值的几列中检索数据,但我想替换所有扩展的ASCII值(ASCII 128和更高的值)

我知道可以使用Replace函数来执行此操作,但也可以使用类似的循环或somenthing执行此操作,否则我必须为ASCII值126创建替换函数,直到255。 我认为可能有一种更容易的方法,任何人都有任何想法?

使用:Microsoft SQL Server 2008

5 个答案:

答案 0 :(得分:3)

我看到Cade Roux在处理实际代码时发布了一些一般性指示。

创建映射表。如果您不需要重音字符替换,则可以不使用此类表。根据需要填写,我已将200,228和131-134作为示例进行了映射。

select number,
 char(number) original,
 case
 when number < 128 then char(number)
 when number = 200 then 'E'
 when number = 228 or number in (131,132,133,134) then 'a'
 else ' '
 end replacement
into charmap
from master..spt_values
where type='p' and number between 0 and 255

测试表

create table tvc (id int identity, vc nvarchar(100))
insert tvc select 'abcdef'
insert tvc select 'abätest'
insert tvc select 'abÔÖÕüûýèend'

替换查询

update tvc
SET vc = (select cast
    ((select m.replacement+''
    from master..spt_values v
    inner join charmap m on m.original=substring(tvc.vc,v.number,1) collate French_BIN
    where v.type='P' and v.number between 1 and len(tvc.vc)
    order by v.number
    for xml path(''), type) as varchar(max)))

注意:

  • 对于最多nvarchar(2047)的列使用 spt_values 一次。您可以将它们链接在一起以获得更长的列(最大)
  • 整理French_BIN 是为了防止A匹配任何重音A等
  • xml 类型,并且用于转换为varchar(max)的复杂包装器用于防止空格变为&#x20;

<小时/> 不使用charmap而不需要对重音字符进行特殊处理:

update tvc
set vc = (select cast
    ((select case when ascii(substring(tvc.vc,v.number,1)) < 128
        then substring(tvc.vc,v.number,1)
        else ' ' end
    from master..spt_values v
    where v.type='P' and v.number between 1 and len(tvc.vc)
    order by v.number
    for xml path(''), type) as varchar(max))) r(new)

答案 1 :(得分:1)

答案 2 :(得分:0)

使用正则表达式:)

只需列出您实际需要在模式中提取的所有符号。

[a-zA-Z0-9]*

这样的东西

答案 3 :(得分:0)

  

否则我必须为ASCII值126创建替换函数,直到255

比这更糟糕。 nvarchar类型将其数据存储为UCS-2(Unicode格式),因此您需要替换数千个可能的字符:

更好的选择是将您想要的字符列入白名单,而不是将您不想要的字符列入黑名单。这是一个SQL脚本,它将返回属于标准ASCII集(modified from a Microsoft example)的Unicode字符串中的所有字符。它将用一个空格替换其他字符。对于'ö'字符,它将字符替换为'o'(作为示例)。

 DECLARE @position int, @nstring nvarchar(9), @nch nchar, @output nvarchar(9)
 SET @position = 1
 SET @nstring = N'København'
 SET @output = ''

 WHILE @position <= LEN(@nstring)
 BEGIN
     SELECT @nch = SUBSTRING(@nstring, @position, 1)

     IF UNICODE(@nch) < 128
         SELECT @output = @output + @nch
     ELSE IF @nch = 'ö'
         SELECT @output = @output + 'o'
     ELSE
         SELECT @output = @output + ' '

     SELECT @position = @position + 1
 END

 SELECT @output
 GO

要处理您的最新评论(用非重音的ASCII变体替换重音字符),您需要添加许多额外的条件:

 ELSE IF @nch = 'ö'
     SELECT @output = @output + 'o'

我认为MSSQL没有内置的功能。

答案 4 :(得分:0)

还有可能通过unpivot运行字符串来生成字符行,使用转换表(现在是每行操作)映射并重新转动以将行重新组合成列。

Jeff Modem使用计数表来实现这项技术:

http://www.sqlservercentral.com/articles/T-SQL/62867/

cyberkiwi在他的回答中几乎完全实现了它:

SQL Replace ASCII With Loop