我有一个替换语句,它做了类似的事情:
SELECT Distinct Forenames, Surname, dbUSNs.DateOfBirth, Datasetname,
dbUSNs.MoPIGrade, SourceAddress, VRM, URNs
FROM Person
WHERE ( Replace(Replace(Replace(Replace(Replace(Replace(Replace
(Replace(Replace(Replace(Replace(Replace(Replace(Replace
(Replace(Replace(Replace(Replace(Replace(Replace(Replace
(Replace(Replace(Replace(Replace
(Surname,'/',''''),'?',''''),'',''''),'^',''''),'{',''''),'}',''''),
'[',''''),']',''''),';',''''),'$',''''),'=',''''),'*',''''),
'#',''''),'|',''''),'&',''''),'@',''''),'\',''''),'<',''''),
'>',''''),'(',''''),')',''''),'+',''''),',',''''),'.',''''),
' ','''') LIKE 'OREILLY%')
因此即使OReilly通过,也会找到O'Reilly。但是,这太慢了。是否有更好的方法来接近它?
答案 0 :(得分:3)
问题不在于REPLACE
&#34;太慢&#34;,但是根本使用它会使查询的一部分不可分析,这意味着它不能使用索引。
基本上,您从上到下强制执行tablescan / indexscan。最重要的是,你有REPLACE
的开销。
如果您希望此查询快速运行,我会执行以下操作之一:
答案 1 :(得分:2)
如果您只想删除所有特殊字符,则可以更轻松地指定有效字符并使用函数执行清理。
这将向您展示如何将字符串清除为字母数字字符和空格'%[^a-z0-9 ]%'
DECLARE @Temp nvarchar(max) ='O''Rielly la/.das.d,as/.d,a/.da.sdo23eu89038 !£$$'
SELECT @Temp
DECLARE @KeepValues AS VARCHAR(50) = '%[^a-z0-9 ]%'
WHILE PatIndex(@KeepValues, @Temp) > 0
SET @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')
SELECT @Temp
哪会返回:ORielly ladasdasdadasdo23eu89038
所以你可以写一个函数:
CREATE FUNCTION [dbo].[RemoveNonAlphaCharacters](@Temp VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @KeepValues AS VARCHAR(50) = '%[^a-z0-9 ]%'
WHILE PatIndex(@KeepValues, @Temp) > 0
SET @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')
RETURN @Temp
END
然后简单地称之为:
SELECT *
FROM Person
WHERE [dbo].[RemoveNonAlphaCharacters](Surname) LIKE 'OREILLY%'
如果您不想要空格,只需将其更改为:'%[^a-z0-9]%'
答案 2 :(得分:0)
试试这个:
创建要拆分的功能:
create function [dbo].[Split](@String varchar(8000), @Delimiter char(1))
returns @temptable TABLE (items varchar(8000))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end
在where where子句中使用:
WHERE ((REPLACE(Surname, items, '') FROM dbo.Split('/,?,^,{,},[,],;,$,=,*,#,|,&,@,\,<,>,(,),+,.')) LIKE 'OREILLY%')
答案 3 :(得分:0)
一般方法 - 是的。
基本上整个替换狂欢使整个事物不可索引,所以更好的方法是存储规范化的值并允许快速查找。
哦,并评估是否需要明确的 - 这是另一个缓慢的减速。
答案 4 :(得分:0)
SELECT Distinct Forenames, Surname, dbUSNs.DateOfBirth, Datasetname,
dbUSNs.MoPIGrade, SourceAddress, VRM, URNs
FROM Person
WHERE Surname LIKE 'O[/?^{}[];$=*#|@\<>()+.]R[/?^{}[];$=*#|@\<>()+.]E[/?^{}[];$=*#|@\<>()+.]I[/?^{}[];$=*#|@\<>()+.]L[/?^{}[];$=*#|@\<>()+.]L[/?^{}[];$=*#|@\<>()+.]Y%')
答案 5 :(得分:0)
如果您想使用SUB STRING和While
删除所有特殊字符DECLARE @str VARCHAR(100),@Len INT,@Pos INT = 1,@char char(1),@results varchar(100)
SET @str = 'O''Rielly la/.das.d,as/.d,a/.da.sdo23eu89038 !£$$'
SET @Len = LEN(@str)
Set @results = ''
WHILE @Pos < @Len
BEGIN
SET @char = SUBSTRING(@str,@Pos,1)
IF @char like '[a-z0-9]' or @char = ' '
BEGIN
SET @results = @results + @char
END
SET @Pos = @Pos + 1
END
select @results