用于过滤的SQL PATINDEX模式

时间:2014-03-07 14:17:01

标签: sql sql-server sql-server-2008 tsql patindex

我正在尝试过滤一个字符串,用作Outlook邮件的主题行。我使用过滤器b / c一些具有特殊字符的字符串会将主题行转换为我想要阻止的Unicode。我正在尝试使用PATINDEX,但不能在模式中得到括号,有没有人知道如何做到这一点和/或有一个好的网站分享创建PATINDEX模式的指南。这就是我所拥有的:

-- First replaces special characters with similar safe ones.
-- Finally excludes all other characters not specified in the pattern.
-- =============================================

ALTER Function [dbo].[RemoveSpecialCharacters](@Temp VarChar(1000))
Returns VarChar(1000)
AS
BEGIN
    DECLARE @KeepValues as varchar(50)

    SET @Temp = Replace(Replace(Replace(Replace(Replace(Replace(Replace(@Temp,'”','"'),'“','"'),'‘','`'),'’','`'),'–','-'),'[','('),']',')')
    SET @KeepValues = '%[^a-z0-9()."`:;,#&+*\/-]%'

    WHILE PatIndex(@KeepValues, @Temp) > 0
        SET @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')

    RETURN @Temp
END

正如你所看到的,因为我无法弄清楚如何在模式中得到括号,现在我用括号替换它们。

2 个答案:

答案 0 :(得分:0)

SET @KeepValues = '%[^a-z0-9()."`:;,#&+*\/-[]][[]]%'

左括号= [[] 右括号= []]

编辑:

以下内容完全避免PATINDEX完成同样的事情。让我知道它是否适合你。

DECLARE @input VARCHAR(1000) = 'th,is i[s @a] [[.[ te[  st '
        , @Temp VARCHAR(1000) = ''
        , @index INT = 1
        , @char CHAR(1);

WHILE @index <= LEN(@input)
BEGIN
    SET @char = SUBSTRING(@input, @index, 1);
    IF @char LIKE '[a-z0-9()."`:;,#&+*\/-]' OR @char = '[' OR @char = ']'
        SET @temp += @char;
    SET @index += 1;
END;
PRINT @Temp;

答案 1 :(得分:0)

  

- 首先用类似的安全字符替换特殊字符。

看起来好像你想用常规报价替换开放报价,用常规报价替代报价等等......有一个技巧可以用来做这个,而不必乱用一堆替换。我不会假装知道关于校对的所有知识,但我知道他们可以做一些你不期望的非常奇怪的事情,有时你可以利用它来为你带来优势。

例如:

Declare @Temp VarChar(100)
SET @Temp = '”“‘’–'
Select @Temp,
        @Temp Collate SQL_Latin1_General_Cp850_CI_AS

当您运行上面的代码时,您将看到数据类型是varchar。我们设置一个带有开放引号,关闭引号等的字符串......如果你没有指定一个排序规则,sql将使用默认的数据库排序规则返回数据。如果确实指定了排序规则,SQL将使用排序规则返回数据。

正如您所看到的,您要用“安全”特殊字符替换的所有特殊字符实际上都已被替换。

将这一切拉到一起:

Alter Function [dbo].[RemoveSpecialCharacters](@Temp VarChar(1000))
Returns VarChar(1000) 
AS
BEGIN
    DECLARE @KeepValues as varchar(50)

    SET @Temp = @Temp Collate SQL_Latin1_General_Cp850_CI_AS
    SET @KeepValues = '%[^a-z0-9()."`'':;,#&+*\/-[[][]]]%'

    WHILE PatIndex(@KeepValues, @Temp) > 0
        SET @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')

    RETURN @Temp Collate Database_Default
END

请注意,在函数内部,数据将转换为其他排序规则,返回值会将其转换回数据库的默认排序规则。

我还把开放的方括号和关闭的方形放入KeepValues。

使用替换功能并不一定是坏事,但转换归类将更快地执行并产生相同的结果。标量函数因性能杀手而臭名昭着,因此尽可能快地使它们符合您的最佳利益(您应该对此函数的性能感到满意)。

现在......我之前说过,我不知道关于校对的一切,所以可能会有一些意外。大多数角色都是一样的,但也有一些区别:

€    ?
    ?
‚    '
ƒ    ƒ
„    "
…    .
†    ┼
‡    ╬
ˆ    ^
‰    %
Š    S
‹    <
Π   O
    ?
Ž    Z
    ?
    ?
‘    '
’    '
“    "
”    "
•    
–    -
—    -
˜    ~
™    T
š    s
›    >
œ    o
    ?
ž    z
Ÿ    Y

使用上面显示的数据,您可以将其解释为:当您转换我在上面的代码中显示的排序规则时,第一个字符将替换为第二个字符。