Поиск текста в хранимых процедурах SQL Server - PullRequest
0 голосов
/ 05 июня 2009

Я создал программу, которая позволяет мне искать ключевые слова в коде хранимых процедур, функций, таблиц и т. Д. В текстовых файлах, сгенерированных SQL Server. Я ищу способ узнать, где во всех файлах кода имеется ссылка на поисковый термин (например, "ADMIN.TABLE). Я использую LINQ для поиска ссылок. Например, когда я ищу ADMIN.TABLE, я перечислю список Имя текстовых файлов, которые содержат ссылку на поисковый термин "ADMIN.TABLE" где-то в тексте. Однако поиск не является абсолютным в этом, если вы не включите различные варианты ADMIN.TABLE, вы не найдете все ссылки. найти все ссылки, мне нужно сделать что-то вроде этого: 1) Поиск "ADMIN.TABLE" 2) Поиск "[ADMIN] .TABLE" 3) Поиск "ADMIN. [TABLE]" 4) Поиск "[ADMIN]. [TABLE]"

Я думаю об использовании шаблона регулярного выражения, но я не уверен, как создать шаблон, который будет охватывать различные комбинации, перечисленные выше. Любая помощь будет оценена.

С уважением,

Tor

Ответы [ 4 ]

2 голосов
/ 05 июня 2009

Я думаю, вы, возможно, немного изобретаете колесо. Вы смотрели на sp_depends? Я перечислю все объекты, которые зависят от указанной таблицы.

Я понимаю, что вы работаете с текстовыми файлами, но если бы вы могли генерировать результаты sp_depends вместе со сценариями, это могло бы решить вашу проблему.

1 голос
/ 05 июня 2009

Попробуйте, это будет циклически проходить по всем файлам в каталоге и сканировать их, используя регулярное выражение без учета регистра (вы можете изменить вызов Directory.GetFiles, чтобы он осуществлял поиск только в каталоге без проверки подкаталогов, изменив параметр поиска) :

        string pathWithSqlFiles = @"c:\sqlfiles\";
        string[] files = System.IO.Directory.GetFiles(pathWithSqlFiles, "*.sql", System.IO.SearchOption.AllDirectories);
        string regexToSearch = @"\[?admin\]?.\[?table\]?";
        foreach (string file in files)
        {
            string fileText = System.IO.File.ReadAllText(file);
            System.Text.RegularExpressions.Match match = System.Text.RegularExpressions.Regex.Match(fileText, regexToSearch, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            if (match.Success)
            {
                // do logic to handle the matched text
            }
        }
0 голосов
/ 05 июня 2009

Если вы не настроены, как это сделать, вы можете проанализировать сценарии sql, а затем использовать объектную модель, чтобы специально найти schema = admin && table = table.

Вариант 1: Сгенерируйте примерный план запроса и проанализируйте ссылки на таблицы. Если вы находитесь на SQLL 2005+, вы можете получить его в формате XML и запросить как:

;WITH XMLNAMESPACES (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
select
    t.n.value('./@Database', 'sysname') as DatabaseName,
    t.n.value('./@Schema', 'sysname') as SchemaName,
    t.n.value('./@Table', 'sysname') as TableName,
    t.n.value('./@Column', 'sysname') as ColName
from @x.nodes('//ColumnReference') as t(n)
go

Вариант 2:

Если вы хотите выполнить эту работу на стороне клиента и иметь sql2008, добавьте ссылку на C: \ Program Files \ Microsoft SQL Server \ 100 \ Tools \ Binn \ VSShell \ Common7 \ IDE \ Microsoft.SqlServer.SqlParser. длл и делать как

    SqlScript script = Parser.Parse(@"create proc sp1 as select 'abc' as abc1");

Затем вы можете обработать script.Xml и искать такой узел, как Я уверен, что вы можете найти его строго типизированным и в объектной модели, так как я вижу SqlTableRefExpression в сборке, но я не уверен, куда детализировать.

0 голосов
/ 05 июня 2009

Эх ...? означает совпадение с предыдущей группой 0 или 1 раз. Оба [и] имеют особое значение, поэтому вы должны избегать их. Итак:

new Regex(@"\[?ADMIN\]?.\[?TABLE\]?")

Сделал бы, если бы ты спросил.

...