繁体   English   中英

通过正则表达式确定SQL命令是否为UPDATE命令

[英]Determine Whether SQL Command is an UPDATE command by regular expressions

我有很多来自实体框架的拦截器的SQL命令,如下所示:

UPDATE [dbo].[Products]
SET [Name] = @0
WHERE ([Id] = @1)

如何确定此命令是UPDATE命令?

我写了以下正则表达式:

(update)? [a-z0-9-]+ (set)

但是它不支持多行命令,命令文本应该在一行中,并且不支持名称中带有模式和[]字符的表名。

它仅支持简单的SQL命令,如下所示:

UPDATE Products SET [Name] = @0 WHERE ([Id] = @1)

注意:我正在使用此正则表达式和Entity Framework的IDbCommandInterceptor功能向SQL Server提供UPDATE命令的WITH (ROWLOCK)表提示,因此我需要一个从UPDATE关键字到SET关键字的正则表达式,因为应该插入WITH (ROWLOCK)SET关键字之前。

考虑以下代码:

String updateCommandRegularExpression = "(update)? [a-z0-9-]+ (set)";

Boolean isUpdateCommand = Regex.IsMatch(commandText, updateCommandRegularExpression, RegexOptions.IgnoreCase | RegexOptions.Multiline); // You may use better regular expression pattern here.

if (isUpdateCommand)
{
    Boolean isSnapshotIsolationTransaction = sqlCommand.Transaction != null && sqlCommand.Transaction.IsolationLevel == IsolationLevel.Snapshot;
    // Transactions with Snapshot isolation level have more complicated table hints to enable rowlock.

    String tableHintToAdd = isSnapshotIsolationTransaction ? " with (rowlock , updlock) set " : " with (rowlock) set ";

    commandText = Regex.Replace(commandText, updateCommandRegularExpression, (match) =>
    {
        return Regex.Replace(match.Value, " SET ", tableHintToAdd, RegexOptions.IgnoreCase); // You may use better regular expression here.
    }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

    command.CommandText = commandText;
}

这样的事情怎么样?

'[; \t]*[Uu][Pp][Dd][Aa][Tt][Ee][ \t]'

基本上,更新命令是第一个单词被update命令-至少对于简单命令而言。 如果允许公用表表达式( with语句),则逻辑更具挑战性。

编辑:

我建议采用以下方法。 使用上面的表达式确定命令是否为更新。 然后,将“ set”替换为“(ROWLOCK)set”。 这将处理表可能具有特殊字符或使用别名的情况。 缺点是,如果表中包含“ set”,将无济于事。

因为您是在C#中执行此操作,所以可以测试一下集合前后的字符是否为空格字符,而不是字母数字。

注意:如果update已包含提示,则此操作将无法正常工作。 您可以通过在“设置”之前寻找“ with”来查找。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM