![](/img/trans.png)
[英]Extracting column names from CREATE SQL command with Regular Expressions
[英]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.