是否可以匹配PATINDEX中不是']'的任何字符?

时间:2015-05-30 19:53:16

标签: tsql

我需要找到不是]的第一个字符的索引。通常,要匹配除X以外的任何字符,请使用模式[^X]。问题是[^]]过早地关闭了第一个括号。第一部分[^]将匹配任何字符。

LIKE operator的文档中,如果向下滚动到“使用通配符作为文字”部分,则会显示一个表示文字字符的方法表,如[]在一个模式内。它没有提到在双括号内使用[]。如果模式与LIKE运算符一起使用,则可以使用ESCAPE子句。 LIKE不返回索引,PATINDEX似乎没有转义子句的参数。

有没有办法做到这一点?

(这看起来似乎是随意的。要围绕它设置一些上下文,我需要立即匹配]后跟一个非]的字符,以便找到带引号的标识符的结尾。{ {1}}是带引号的标识符中唯一的字符转义符。)

1 个答案:

答案 0 :(得分:4)

这是不可能的。连接项PATINDEX Missing ESCAPE Clause已关闭,因为无法修复。

我可能会使用CLR和正则表达式。

一个简单的实现可能是

using System.Data.SqlTypes;
using System.Text.RegularExpressions;

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlInt32 PatIndexCLR(SqlString pattern, SqlString expression)
    {
        if (pattern.IsNull || expression.IsNull)
            return new SqlInt32();

        Match match = Regex.Match(expression.ToString(), pattern.ToString());
        if (match.Success)
        {
            return new SqlInt32(match.Index + 1);
        }
        else
        {
            return new SqlInt32(0);
        }
    }
}

使用示例

SELECT  [dbo].[PatIndexCLR] ( N'[^]]', N']]]]]]]]ABC[DEF');

如果这不是一个选项,可能的片状解决方法可能是替换一个不太可能存在于数据中的字符而没有语法中的这种特殊意义。

WITH T(Value) AS
(
SELECT ']]]]]]]]ABC[DEF'
)
SELECT PATINDEX('%[^' + char(7) + ']%', REPLACE(Value,']', char(7)))
FROM T

(返回9