【发布时间】: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