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.