passing parameter in mdx query - reporting-services

What I am trying to do is; User would select value of region from the dropdown(Region1, Region2, Region3).
#Region should take that value in the mdx query.
for eg. if user selects Region2, it should look like: [Region].[Region2].children. The query that I have written shows that there's a syntax error.
WITH
MEMBER [measures].[region] AS
StrToMember("[Region].[" + #Region + "]").CurrentMember.Name
MEMBER [measures].[product] AS
[Product Line].[product Line L2].CurrentMember.Name
SELECT
NonEmpty
(
StrToMember("[Region].[" + #Region + "]").Children
*
[Product Line].[Product Line L2].Children
,[Measures].[Total Clients]
) ON ROWS
,{
[measures].[region]
,[measures].[product]
,[Measures].[Total Clients]
} ON COLUMNS
FROM [EQ Coverage];

You also have available the function strToSet so this:
StrToMember("[Region].[" + #Region + "]").Children
Could be written as:
StrToSet("[Region].[" + #Region + "].Children", CONSTRAINED)
BUT I'm unsure of the purpose of this part of your code?
MEMBER [measures].[region] AS
StrToMember("[Region].[" + #Region + "]").CurrentMember.Name
I don't see the purpose of using the parameter - you could do something like this?
MEMBER [measures].[region] AS
[Region].[Region].CurrentMember.member_caption

Related

SSRS Report Parameters passed out

I am currently building a number of logging and analysis tools to keep tabs on our SQL environment. We are currently using SQL Server 2014.
What I want to do is keep check of all the parameters that are passed to our reports during the day. All of the reports are currently using stored procedures so in my table or a select statement based on a table is output the stored procedure with the parameters for every time the report was run.
At the end of the day I would then like to be able to take the outputted statement and run it in SSMS without having to use the report. I have been looking at the ExceutionLogStorage table and the ExecutionLog view's and though it has most of the information that I need, the parameters are not in an easily usable state.
Has anyone done something similar to what I have described?
You need to add logging part in your original SP, for example:
Alter procedure a
(#parameter)
As
Begin
..
..
Insert into loggingTable(col)
Values(#parameter)
..
..
End
Then query directly against that loggingTable for getting the history of used parameters
A Google search around this topic quickly brought up the following blog post already identified by the OP as useful and shown below (this query itself is actually an expansion of work linked to by LONG's answer below)
SELECT TOP 1 ParValue
FROM (
SELECT els.TimeEnd
, IIF(CHARINDEX('&' + 'ParameterName' + '=', ParsString) = 0, 'ParameterName',
SUBSTRING(ParsString
, StartIndex
, CHARINDEX('&', ParsString, StartIndex) - StartIndex)) AS ParValue
FROM (SELECT ReportID, TimeEnd
, '&' + CONVERT(VARCHAR(MAX), Parameters) + '&' AS ParsString
, CHARINDEX('&' + 'ParameterName' + '=', '&' + CONVERT(VARCHAR(MAX), Parameters) + '&')
+ LEN('&' + 'ParameterName' + '=') AS StartIndex
FROM ExecutionLogStorage
WHERE UserName='UserName' -- e.g. DOMAIN\Joe_Smith
) AS els
INNER JOIN [Catalog] AS c ON c.ItemID = els.ReportID
WHERE c.Name = 'ReportName'
UNION ALL
SELECT CAST('2000-01-01' AS DateTime), 'ParameterName'
) i
ORDER BY TimeEnd DESC;
Both these approaches though really only give us a starting point since they (variously) rely upon us knowing in advance the report name and parameter names. Whilst we can quickly make a couple of changes to Ken Bowman's work to get it to run against all executions of all reports, we still have the problem that the query hardcodes the parameter name.
The parameters required to execute a report are stored on the Catalog table in the Parameter column. Although the column has a datatype ntext, it is actually storing an XML string. Meaning we can use an XPath query to get at the parameter names
with
CatalogData as (
select ItemID, [Path], [Name], cast(Parameter as xml) 'ParameterXml'
from Catalog
where [Type] = 2),
ReportParameters as (
select ItemID, [Path], [Name], ParameterXml, p.value('Name[1]', 'nvarchar(256)') 'ParameterName'
from CatalogData
cross apply ParameterXml.nodes('/Parameters/Parameter') as Parameters(p))
select *
from ReportParameters;
Executing this query will list all reports on the server and their parameters. Now we just need to combine this with Ken Bowman's query. I've gone with a CTE approach
with
CatalogData as (
select ItemID, [Path], [Name], cast(Parameter as xml) 'ParameterXml'
from Catalog
where [Type] = 2),
ReportParameters as (
select ItemID, [Path], [Name], p.value('Name[1]', 'nvarchar(256)') 'ParameterName'
from CatalogData
cross apply ParameterXml.nodes('/Parameters/Parameter') as Parameters(p))
select
els.TimeEnd
, c.[Name]
, rp.ParameterName
, iif(
charindex(
'&' + rp.ParameterName + '=', ParametersString) = 0
, rp.ParameterName, substring(ParametersString
, StartIndex, charindex('&', ParametersString, StartIndex) - StartIndex
)) 'ParameterValue'
from (
select
ReportID
, TimeEnd
, rp.ParameterName
, '&' + convert(varchar(max), Parameters) + '&' 'ParametersString'
, charindex(
'&' + rp.ParameterName + '=',
'&' + convert(varchar(max), Parameters) + '&'
) + len('&' + rp.ParameterName + '=') 'StartIndex'
from
ExecutionLogStorage
inner join ReportParameters rp on rp.ItemID = ReportID) AS els
inner join [Catalog] c on c.ItemID = els.ReportID
inner join ReportParameters rp on rp.ItemID = c.ItemID and rp.ParameterName = els.ParameterName;
Note that the parameter values are passed to the report as part of a URL, so you'll still need get rid the literal space encoding and so on. Also, this doesn't (yet...) work for multi-value parameters.

Hierarchy Level to display from than level down on SSRS Report

So I have a report with 4 parameters;
#LevelParameterCheat; Hierarchy Level, this is the level inside the cube
#DimOrganizationCustomerHierarchy; Organizational Level
#FromDimDateDateSK/#ToDimDateDateSK; used for filtering
Here is the DataSet MDX Query;
SELECT NON EMPTY { [Measures].[Count] } ON COLUMNS, NON EMPTY
{ (DESCENDANTS([Dim Organization].[Customer Hierarchy].Levels(#LevelParameterCheat).ALLMEMBERS) ) }
DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME, PARENT_UNIQUE_NAME, LEVEL_NUMBER ON ROWS FROM ( SELECT (
STRTOSET("[Dim Organization].[Customer Hierarchy].&[" + #DimOrganizationCustomerHierarchy + "]", CONSTRAINED) ) ON COLUMNS FROM ( SELECT ( STRTOMEMBER("[Dim Date].[Date SK].&[" + Format(#FromDimDateDateSK,"yyyyMMdd") + "]", CONSTRAINED) :
STRTOMEMBER("[Dim Date].[Date SK].&[" + Format(#ToDimDateDateSK,"yyyyMMdd") + "]", CONSTRAINED) )
ON COLUMNS FROM [Portal Data Mart])) CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS
What I need: At time of execution the user knows his Org Level and dates to filter. The report needs to display all data from the selected Org Level down.
What I’m looking for; I need to somehow use the Org Level to query the cube and look for the specific level of the selected Org and plug it in the DECENDANTS Function so it displays only from that level on.
What I’ve done; ….ahhhhgggg to many trials and errors . The latest was to try and get the level doing something like this…
WITH MEMBER MEASURES.LevelNumber AS [Dim Organization].[Customer Hierarchy].&[#DimOrganizationCustomerHierarchy].Level.Ordinal
And if that worked I assumed it would bring a numeric value of the level that I then have to concatenate with the DECENDANTS command, something like this…
{ (DESCENDANTS(STRTOSET("[Dim Organization].[Customer Hierarchy].Levels(“level “" + LevelNumber + ").ALLMEMBERS)"))}
Well, something is not right because it doesn’t work. I’m very new to MDX and lacking on the syntax so if someone can point me in the right direction I would appreciate it very much. So far the query above works on the report because I manually enter the Org/Level combination but the user would not know what their Level is. I’ve been at it for almost two weeks and need to fix this. I feel I’m close but not there yet. Please help
well here is the answer to the problem;
`SELECT NON EMPTY { [Measures].[Count] } ON COLUMNS, NON EMPTY
{ (DESCENDANTS(StrToMember( "[Dim Organization].[Customer Hierarchy].&[" + #DimOrganizationCustomerHierarchy + "]",CONSTRAINED).Level.ALLMEMBERS) ) }
DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME, PARENT_UNIQUE_NAME, LEVEL_NUMBER ON ROWS FROM ( SELECT (
STRTOSET("[Dim Organization].[Customer Hierarchy].&[" + #DimOrganizationCustomerHierarchy + "]", CONSTRAINED) ) ON COLUMNS FROM ( SELECT (
STRTOMEMBER("[Dim Date].[Date SK].&[" + Format(#FromDimDateDateSK,"yyyyMMdd") + "]", CONSTRAINED) :
STRTOMEMBER("[Dim Date].[Date SK].&[" + Format(#ToDimDateDateSK,"yyyyMMdd") + "]", CONSTRAINED) )
ON COLUMNS FROM [Portal Data Mart])) CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS`

Passing multiple values to SSRS using MDX

I am running the following command for getting a multi value report
StrToSet
("[Dim Branch].[HierarchyB-T-C].[Trading Code].&[" +
Replace(
Join(
Parameters!TradingName.Value,"],"
) +"]",",",",[Dim Branch].[HierarchyB-T-C].[Trading Code].&["),",")
But I'm getting an error
'The Syntax for 'Join' is incorrect'.
I don't know what I am doing wrong. Can anyone correct me please?
If I change it to StrToSet(#TradingName, Constrained) it works for single value, but I'd like to pass multiple values.
Do you need curly braces to form a set? I have added one at the start of the below ... a little unsure where the end of your string is - does it end like this .&["?!
StrToSet(
"{[Dim Branch].[HierarchyB-T-C].[Trading Code].&["
+
Replace(
Join(Parameters!TradingName.Value,"],") + "]"
, ","
, ",[Dim Branch].[HierarchyB-T-C].[Trading Code].&["
)
,","
)
If Parameters!TradingName.Value is equal to a string of this format MEC,RSA then maybe join is not required:
StrToSet(
"{"
+
Replace(
"[Dim Branch].[HierarchyB-T-C].[Trading Code].&["
+
Parameters!TradingName.Value
, ","
,"],[Dim Branch].[HierarchyB-T-C].[Trading Code].&["
)
+
"]}"
,constrained)
To pass multiple value from parameter, i just followed the steps
1 Add parameters and name it like
Under dataset properties (shared dataset properties as well) , the Parameters tab write an expression like this way
=Split(Parameters!TradingName.Value,",")
in Shared dataset, write the MDX with WHERE (StrToSet(#TradingName))
SELECT
{[Total]} ON COLUMNS
,
{
[Dim Account].[Account Type].&[Income]
}
*
STRTOMEMBER("[Dim Fiscal Year].[HierarchyFiscal].[E Month].&[" + #FiscalYear +"]&[" + FORMAT(Now(),"MMMM") +"].PREVMEMBER")
*
ORDER
(
{
[Dim Branch].[Branch Name].[Branch Name]
},[Total], BDESC
)
ON ROWS
from [CubeProfitLoss]
WHERE (StrToSet(#TradingName))
when you want to preview the multiple value, make sure you are using , to separate trading name likewise

How to replace the characters by * in a specified column dynamically in ssis package?

I have an Excel source with one of the column name Emailid.
I want the output like below example:
'mahesh123#gmail.com'
The output should be
'ma*****23#gmail.com'
As a beginner i am searching for the replacement for function STUFF, in SSIS package...
select
substring(studentEMAILIDid,1,2)
+ replicate('*',len(substring(studentEMAILIDid,1,
charindex(studentEMAILIDid,'#')
-1‌​)-4)
+ substring(studentEMAILIDid,charindex(studentEMAILIDid,'#')-2,2)
+ substring(studentEMAILIDid,charindex(studentEMAILIDid,'#')+1,
len(studentEMAILIDi‌​d)
from <tablename>
I tried the above code in SSMS,i am expecting the result through SSIS package without using "Execute SQL Task".
This is the expression I tried:
emailid==
substring(
StudentEMailID,
3,
LEN(right(StudentEMailID,
findstring('#',Stud‌​entEMailID + '#')-1
)
)-4,
REPLICATE('*',LEN(LEFT(StudentEMailID,
findstring('#',StudentEMailID + '#')-1))-4))
–
Data:
select N'mahesh123#gmail.com' as email
union all
select N'EmpireAgain#gmail.com'
Derived Column Code:
SUBSTRING(email,1,2) +
REPLICATE("*",LEN(email) - FINDSTRING(email,"#",1) - 4) +
SUBSTRING(email,FINDSTRING(email,"#",1)-2,LEN(email)-(FINDSTRING(email,"#",1)-2) + 1)
Result:
email NewEmail
mahesh123#gmail.com ma*****23#gmail.com
EmpireAgain#gmail.com Em*****in#gmail.com

How to write the select statement in this condition?

I have a query which i am using to filter the grid
SELECT * FROM Resources
WHERE ResourceName ='" + ResourceName + "'
AND Status = '" + status + "' "
and my grid looks like this
ResourceID|ResourceName|Status
I had added the ResorceName and Status in a dropdown for filtering the grid now my problem is that in this select statement if any of the paramaters is null the data is not Binded to the grid but if I pass both the parameters it filters the grid and gives the required row or filtered row from the grid... Can anyone tell me how do I write select statement if any of the parameter is null.
Have a look it the below post on catch all queries
Catch All Examples
In terms of fixing your problem quickly, something like this would work...
Select * From Resources Where (ResourceName = '"+ ResourceName + "' OR ResourceName IS NULL) AND (Status = '" + Status +"' OR Status IS NULL)
That however is NOT an acceptable piece of code, as it is vulnerable to SQL injection. In essence, suppose the ResourceName that is passed in is
'; Drop Table Resources; --
You probably don't need me to tell you what that does.
My advice is to ALWAYS make use of SQLCommand objects in .Net - also known as "Prepared Statements" in other languages. It prevents these kind of tricks...
SELECT * FROM Resources
WHERE (ResourceName = CASE WHEN '" + ResourceName + "' IS NULL THEN ResourceName ELSE '" + ResourceName + "' END) //do same for other parameter