Регулярное выражение для обнаружения скрытых операторов DML(вставка, обновление, удаление) в сценарии DDL(создание, изменение, удаление) .sql

ОБНОВЛЕНИЕ: чтобы облегчить этот вопрос. Я изменил строку, и теперь вам не нужно беспокоиться о BEGIN END. Вместо этого у меня теперь есть только операторы GO в качестве терминаторов. Я надеюсь, что я получу некоторые ответы от других людей сейчас

Мне нужно написать регулярное выражение, которое может обнаружить скрытые операторы DML, такие как INSERT, UPDATE, DELETE в сценарии DDL (CREATE, ALTER, DROP).

Пример. В приведенном ниже скрипте он должен поймать 2 оператора таблицы table5 и последнюю вставку в оператор таблицы3. Но он должен игнорировать операторы вставки, которые на самом деле находятся в теле самого хранимого процесса.

Если вы запустите этот RegEx здесь: http://regexr.com/?33rf3, вы увидите, что я выполнил 90% этого. Единственная часть, которая не работает, это то, что она делает жадный матч до последнего GO. Мне нужно, чтобы остановиться на первом GO. Я пытался использовать +? оператор, чтобы сделать его нежадным, но он не хочет работать.

delete table5 /*Regex should find this*/

GO

create proc abc
begin
    insert into table1  /*Regex should IGNORE this*/
    begin
        fake nesting here
        insert into table2 /*Regex should IGNORE this*/
    end
end

GO

delete table5 /*Regex should find this*/

GO

alter proc abc2
begin
  --no statements in this proc
end

GO

insert into table3 /*Regex should find this*/

1 ответ

Решение

GO заявления не нужны.

        var regex1 = new Regex(@"
          (?s)
          (create|alter|drop).+?
          begin
            (?:
               (?> (?! begin | end ) .
                  | begin (?<counter>)
                  | end  (?<-counter>)
                )*
            )
            (?(counter)(?!))
          end
          "
        , RegexOptions.IgnorePatternWhitespace
        );

        var regex2 = new Regex(@"(?:insert|update|delete).+");

        var result = regex2.Matches(regex1.Replace(your_input, ""))
            .Cast<Match>()
            .Select(m => m.Value);

Этот код удаляет все операторы create/alter/drop и затем ищет delete/alter/drop. Я думаю, что это можно сделать, используя только одно регулярное выражение, но это все, что я могу предложить сейчас, извините:)

Другие вопросы по тегам