通过正则表达式判断 SQL 命令是不是为 UPDATE 命令

Posted

技术标签:

【中文标题】通过正则表达式判断 SQL 命令是不是为 UPDATE 命令【英文标题】:Determine Whether SQL Command is an UPDATE command by regular expressions通过正则表达式判断 SQL 命令是否为 UPDATE 命令 【发布时间】:2014-09-09 22:51:29 【问题描述】:

我有很多来自实体框架拦截器的 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)

注意: 我正在使用实体框架的这个正则表达式和IDbCommandInterceptor 功能为UPDATE 命令向SQL 服务器提供WITH (ROWLOCK) 表提示,所以我需要一个从UPDATE 关键字到SET 关键字的正则表达式,因为@987654331 @ 应该插入到 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;

【问题讨论】:

为什么需要这样做? 锁定行而不是锁定整个表,当您只更新几条记录时,有几个性能优势,因为其他事务将继续在同一个表的其他记录上工作没有更新,所以我们等待的交易会更少。 【参考方案1】:

这样的事情怎么样?

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

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

编辑:

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

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

注意:如果update 已经有提示,这将无法正常工作。您可以通过在“set”之前查找“with”来查找。

【讨论】:

我已经为我的问题添加了额外的注释,您能再看一下吗?非常感谢。不,我的更新中没有 with 声明。

以上是关于通过正则表达式判断 SQL 命令是不是为 UPDATE 命令的主要内容,如果未能解决你的问题,请参考以下文章

java正则表达式判断是不是为银行卡卡号

java 正则匹配字符是不是为纯数字

js正则表达式 判断输入框是不是为正整数或者正整数保留两位小数

正则表达式 判断是不是是字母和数字

shell中怎么判断输入的是不是是数字?

如何用正则表达式判断时间输入是不是正确?格式为00:00,小时是00-23,分钟是00-60,秒钟00-60