Извлечение зависимостей объектов БД из набора данных SSRS с помощью встроенного запроса (Тип запроса: Текст)
Я имею дело с конкретной проблемой идентификации зависимых объектов БД для любого SSRS RDL.
Я хорошо понимаю, если какой-либо набор данных имеет хранимую процедуру в качестве запроса в RDL, тогда я могу ссылаться на связанную хранимую процедуру и получать все зависимые объекты (подробности можно найти здесь: Различные способы найти зависимости объекта SQL Server).)
Но я специально искал наборы данных с текстовым или встроенным запросом для любого rdl. Я могу извлечь CommandText из XML-кода rdl, но я не уверен, как извлечь объекты db, такие как столбцы sp, table, views, формировать текст команды, который является встроенным запросом в rdl.
Например, если я извлеку приведенный ниже запрос из XML commandText (это гипотетический запрос, имена не стандартизированы в базе данных, например vw_ для представлений, udf_ для функций):
-----This query serves Report ABC
SELECT DATE
,[amount]
,teamID = (SELECT TeamID FROM Sales.[getSalesPerson](r.date) as s WHERE R.[SalesPersonName] = S.[SalesPersonName])
,[channel]
,[product]
,[Item]
,r.[M_ID]
,Amount
,M.[Type]
FROM dbo.FactTable AS R
LEFT JOIN sp_Channel C ON R.[Channel_ID] = C.[Channel_ID]
LEFT JOIN Marketing.vw_M M ON R.[M_ID] = M.[M_ID]
Есть ли способ определить, что у этого запроса есть зависимый объект, как показано ниже:
ObjectName ObjectType
------------------------------------------
dbo.FactTable Table
sp_Channel Stored Procedure
Marketing.vw_M View
Sales.[getSalesPerson] Function
Ответы
Ответ 1
Нелегко извлечь имена объектов из команды SQL, поскольку они могут быть написаны по-разному (со схемами или без них, включая имена баз данных...)
Но есть много вариантов извлечения объектов из SQL-запроса, которые вы можете попробовать:
Используя регулярные выражения, например: вам нужно искать слова, расположенные после следующих ключевых слов:
- СТОЛ TRUNCATE
- ОТ
- UPDATE
- РЕГИСТРИРУЙТЕСЬ
Следующий код является примером С#:
Regex regex = new Regex(@"\bJOIN\s+(?<Retrieve>[a-zA-Z\._\d\[\]]+)\b|\bFROM\s+(?<Retrieve>[a-zA-Z\._\d\[\]]+)\b|\bUPDATE\s+(?<Update>[a-zA-Z\._\d]+)\b|\bINSERT\s+(?:\bINTO\b)?\s+(?<Insert>[a-zA-Z\._\d]+)\b|\bTRUNCATE\s+TABLE\s+(?<Delete>[a-zA-Z\._\d]+)\b|\bDELETE\s+(?:\bFROM\b)?\s+(?<Delete>[a-zA-Z\._\d]+)\b");
var obj = regex.Matches(sql);
foreach(Match m in obj)
{
Console.WriteLine(m.ToString().Substring(m.ToString().IndexOf(" ")).Trim());
}
Выход
Затем необходимо очистить и объединить результат с таблицами sys.objects из базы данных SQL Server.
Используя синтаксический анализатор SQL, например:
Вы можете обратиться к следующим очень полезным ссылкам для получения дополнительной информации:
Ответ 2
Если ваши отчеты подключаются к SQLServer и у вас есть доступ, вы можете попытаться получить план выполнения с помощью SET SHOWPLAN_XML ON
и проанализировать его.
Соответствующий поток для анализа:extract-data-from-sql-servers-xml-execute-plan