Я работаю над запросом SQL Server (2008 R2 на данный момент) - моя цель - создать набор результатов, в котором перечислены все отчеты, определенные в SSRS, по определенному пути вместе с сеткой, в которой есть столбец для каждого однозначно названный параметр отчета на сервере, при этом содержимое сетки является "галочкой" (например, ненулевое значение) для каждой комбинации "Отчет + Параметр", для которой соответствующий отчет имеет параметр с соответствующим именем. Запрос должен быть чувствительным к регистру для имен параметров отчета - одна из целей запроса - идентифицировать отчеты с параметрами, записанными с непоследовательным корпусом.
Я смог написать этот запрос, используя ряд методов (которые некоторые могли бы назвать уродливыми хаками):
use ReportServer
go
declare @path nvarchar(255);
set @path = N'SSRS Path To Folder'
-- return a table with two columns: ReportName, ParameterName with one row for each
-- distinct ReportName + ParameterName combination
select
t.Name as ReportName,
pn.value collate Latin1_General_CS_AI as ParameterName
into
#rp
from
(
-- return a table with two columns: ReportName and ParameterNames (comma-separated list of
-- parameters in declaration order)
select
[Name],
(select STUFF((select ', ' + p.n.value('.', 'varchar(255)')
from ParameterXml.nodes('/Parameters/Parameter/Name') p(n)
for xml path('')), 1, 2, '')
) as ParameterNames
from
(
select
*,
CAST(Parameter as xml) as ParameterXml
from
[Catalog]
) c
where
[Path] like '/' + @path + '/%'
and [Type] = 2
) t
cross apply dbo.SplitString(t.ParameterNames) pn
-- Pivot the above result into a table with one row per report and one column for each
-- distinct report parameter name. Parameter-named columns contain a flag - 1 or null -
-- that indicates whether the report corresponding to that row defines the parameter
-- corresponding to that column.
create database CS_Temp collate Latin1_General_CS_AI;
go
use CS_Temp
go
declare @cols nvarchar(MAX), @query nvarchar(MAX);
set @cols = STUFF(
(
select
distinct ','+QUOTENAME(rp.ParameterName)
from
#rp rp
for xml path(''), type).value('.', 'nvarchar(max)'
),1,1,''
);
set @query = 'SELECT ReportName, ' + @cols + ' from
(
select ReportName, 1 as Used, ParameterName from #rp
) x
pivot
(
max(Used) for ParameterName in (' + @cols + ')
) p
';
execute(@query)
go
drop table #rp
use ReportServer;
go
drop database CS_Temp;
go
(функция SplitString от Erland Sommarskog/Itzik Ben-Gan, динамическая сводная техника от Aaron Bertrand). Этот запрос действительно работает, но он медленный и уродливый - на самом деле это нормально для моего варианта использования. Однако мне интересно, есть ли лучший способ заставить стержень работать с именами столбцов, чувствительными к регистру, чем то, что я здесь сделал: на самом деле создавая базу данных с сортировкой по регистру, переключаясь на этот контекст и выполняя сводный запрос. База данных не имеет никакой цели, кроме предоставления сопоставления метаданных базы данных - то есть имен столбцов в результате сводного запроса.