SQL Server:从VARCHAR(MAX)字段替换ASCII字符列表

时间:2015-02-17 14:55:12

标签: sql tsql sql-server-2012

我有一个包含大约400万条记录的表格,我需要删除VARCHAR(MAX)列中以下范围内的任何ASCII字符实例。

  • 00 - 08
  • 11 - 12
  • 14 - 31
  • 127

请注意,上面代表每个字符的十进制标识符,要替换的实际ASCII字符可以与http://www.asciitable.com/进行交叉检查。

我尝试了以下方法并取得了预期的效果。

第一种方式:使用嵌套的REPLACE函数:

UPDATE [MyTable] 
SET replace_ascii_chars = REPLACE(REPLACE(replace_ascii_chars, char(0), '') 
,char(1), '')....

第二种方式:创建以下SQL函数并运行UPDATE语句:

CREATE FUNCTION [dbo].RemoveASCIICharactersInRange(@InputString VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
    IF @InputString IS NOT NULL
    BEGIN
      DECLARE @Counter INT, @TestString NVARCHAR(40)

      SET @TestString = '%[' + NCHAR(0) + NCHAR(1) + NCHAR(2) + NCHAR(3) + NCHAR(4) + NCHAR(5) + NCHAR(6) + NCHAR(7) + NCHAR(8) + NCHAR(11) + NCHAR(12) + NCHAR(14) + NCHAR(15) + NCHAR(16) + NCHAR(17) + NCHAR(18) + NCHAR(19) + NCHAR(20) + NCHAR(21) + NCHAR(22) + NCHAR(23) + NCHAR(24) + NCHAR(25) + NCHAR(26) + NCHAR(27) + NCHAR(28) + NCHAR(29) + NCHAR(30) + NCHAR(31) + NCHAR(127)+ ']%'

      SELECT @Counter = PATINDEX (@TestString, @InputString COLLATE Latin1_General_BIN)

      WHILE @Counter <> 0
      BEGIN
        SELECT @InputString = STUFF(@InputString, @Counter, 1, '')
        SELECT @Counter = PATINDEX (@TestString, @InputString COLLATE Latin1_General_BIN)
      END
    END
    RETURN(@InputString)
END

更新SQL:

UPDATE [MyTable] 
SET replace_ascii_chars = [dbo].RemoveASCIICharactersInRange(replace_ascii_chars)

上述两种方式都运行良好,但似乎有点慢(大约需要1.5小时)。有没有办法加快SQL Server的速度?我不想在应用程序层中进行替换,因为值已经以这种方式保存。

此外,并非所有400万条记录都没有这些字符,那么有没有办法加快速度呢?

编辑: 说WHERE子句花费更长时间是错误的(由于我之前使用where子句的方式,它的速度较慢)。我根据@MWillemse建议更新了where子句,现在看起来非常快。

1 个答案:

答案 0 :(得分:2)

根据@MWillemse建议添加WHERE子句后,查询现在运行得更快。

UPDATE [MyTable] 
SET replace_ascii_chars = REPLACE(REPLACE(replace_ascii_chars, char(0), '') 
,char(1), '')....
WHERE replace_ascii_chars LIKE '%[' + CHAR(0) + CHAR(1) + CHAR(2) + CHAR(3) + CHAR(4) + CHAR(5) + CHAR(6) + CHAR(7) + CHAR(8) + CHAR(11) + CHAR(12) + CHAR(14) + CHAR(15) + CHAR(16) + CHAR(17) + CHAR(18) + CHAR(19) + CHAR(20) + CHAR(21) + CHAR(22) + CHAR(23) + CHAR(24) + CHAR(25) + CHAR(26) + CHAR(27) + CHAR(28) + CHAR(29) + CHAR(30) + CHAR(31) + CHAR(127)+ ']%'

感谢@MWillemse,@ jarlh,@ Balm的宝贵意见。

编辑:请注意,此功能仅适用于SQL SERVER 2012及以上版本。有关LOB数据类型和某些归类问题的讨论,请参阅此stackoverflow link,以便在较早的REPLACE版本中与SQL Server函数一起使用。