简体   繁体   中英

Determine Whether SQL Command is an UPDATE command by regular expressions

I've lots of SQL commands from Entity framework's interceptors such as following:

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

How can I determine that this command is an UPDATE command ?

I've written following regular expression:

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

But it does not support commands in multiple lines and the command text should be in one line, and it does not support table names with schema and [] characters in their names.

It only supports simple SQL commands as following:

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

Note: I'm using this regular expression and IDbCommandInterceptor feature of Entity Framework to provide WITH (ROWLOCK) table hints to SQL server for UPDATE commands, so I need a regular expression from UPDATE keyword to SET keyword because WITH (ROWLOCK) should be inserted right before SET keyword.

Consider following code:

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;
}

How about something like this?

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

Basically, an update command is one where the first word is update -- at least for simple commands. If you allow common table expressions ( with statements), then the logic is more challenging.

EDIT:

I would suggest the following approach. Use the above expression to determine if the command is an update. Then, replace "set " with " with (ROWLOCK) set". This will handle the cases where the table might have special characters or use an alias. The one downside is it will not help if the table contains "set".

Because you are doing this in C#, you can test to see if the characters before and after the set are white space characters rather than alphanumeric.

Note: This will not work correctly if the update already has hints. You can look for that by looking for "with" before the "set".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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