I'm working on a query for SQL Server (2008 R2 at the moment) - my goal is to produce a result set that lists every report defined in SSRS under a specific path along with a grid that has a column for each uniquely named report parameter on the server, with the contents of the grid being a "checkmark" (e.g. non-null value) for each Report + Parameter combination for which the corresponding report has a parameter with the corresponding name. The query needs to be case sensitive on report parameter names - one purpose of the query is to identify reports that have parameters spelled with inconsistent casing.
I was able to write that query using a number of techniques (that some might call ugly hacks):
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 function from Erland Sommarskog/Itzik Ben-Gan, dynamic pivot technique from Aaron Bertrand). This query does work, but it's slow and ugly - which is actually OK for my use case. What I'm wondering though, is if there's any better way to get the pivot to work with case sensitive column names than what I've done here: Actually creating a database with a case-sensitive collation, switching to that context and executing the pivot query. The database serves no purpose other than providing the collation for the database meta-data - i.e. column names in the result of the pivot query.
SQL Server is, by default case insensitive; however, it is possible to create a case sensitive SQL Server database and even to make specific table columns case sensitive. The way to determine a database or database object is by checking its “COLLATION” property and look for “CI” or “CS” in the result.
The design of the PIVOT and UNPIVOT operators sometimes leads to bugs and pitfalls in your code. The PIVOT operator's syntax doesn't let you explicitly indicate the grouping element. If you don't realize this, you can end up with undesired grouping elements.
You can also create a dynamic pivot query, which uses a dynamic columns for pivot table, means you do not need to pass hard coded column names that you want to display in your pivot table. Dynamic pivot query will fetch a value for column names from table and creates a dynamic columns name list for pivot table.
Column, index, stored routine, and event names are not case-sensitive on any platform, nor are column aliases. However, names of logfile groups are case-sensitive. This differs from standard SQL. By default, table aliases are case-sensitive on Unix, but not so on Windows or macOS.
To use the PIVOT command you need to have a case sensitive collation to have case sensitive columns, as you've found. I like the cunningness of a new temporary CS db BUT there's a couple of other approaches I can think of that don't require it:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With