【问题标题】:SQL Server: Replace a list of ASCII characters from a VARCHAR(MAX) fieldSQL Server:替换 VARCHAR(MAX) 字段中的 ASCII 字符列表
【发布时间】:2015-02-17 14:55:11
【问题描述】:

我有一个包含大约 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) 进行几笔较小的交易。 2) 不要更新不包含那些不需要的字符的行。 (即添加 where 子句。)
  • 因为它在数据库中并不意味着数据库是完成任务的最佳工具。我会在.NET 之类的应用程序中执行此操作。或者写一个 CLR 来做。
  • 你试过这个吗:WHERE data LIKE '%['+CHAR(0)+','+CHAR(1)+','+CHAR(2)+','+CHAR(3)+','+CHAR(4)+']%'
  • 感谢@MWillemse 的建议。谢谢 jarlh,Balm 的 cmets。

标签: sql tsql sql-server-2012


【解决方案1】:

根据@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 为您提供宝贵的 cmets。

编辑:请注意,这仅适用于SQL SERVER 2012 及更高版本。请关注此 stackoverflow link,讨论在旧版 SQL Server 中与 REPLACE 函数一起使用时 LOB 数据类型和某些排序规则的问题。

【讨论】:

    猜你喜欢
    • 2015-04-06
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多