dynamic queries in SSRS - reporting-services

I would like to write a query and allow for a grouping on different colums; for example the end user can group either on country, region, city, or no grouping.
The result is to be used in an ssrs report.
so I would write a query like this:
#value = CASE WHEN #dropdown=1 THEN ', foo.country' ELSE ', foo.region'
#sqlquery = 'select name '+#value+' from foo group by field1'+ #value + ';'
EXEC(#sqlquery);
This does work as expected in management studio (if i define variables and assign something to #dropdown);
I'm a bit at loss on how to implement this in an ssrs report: I want the user to be able to choose no grouping (leave the #value empty)
Visual studio will not be able to 'see' the field and therefore allow to add it in a tablix

Avoid users type the grouping (see the #NeilP recommendation), just create a parameter called Grouping, in Available Values tab you can specify the dropdown selector values.
In the Available Values tab use these settings:
Then in your dataset properties map the SSRS parameter to a T-SQL parameter.
Now you can use #Grouping in your dataset:
set #value = CASE WHEN #Grouping = 1 THEN ', foo.country'
WHEN #Grouping = 2 THEN ', foo.region'
WHEN #Grouping = 3 THEN ', foo.city'
ELSE ''
END
set #sqlquery = 'select name '+#value+' from foo group by field1'+ #value + ';'
The user will be prompt to select one value in the dropdown list:
You can define a default value used in the report, which lets users run the report without specify any value.
Go to Default Values tab in Parameter Properties and add =0 if you want to your report runs without any group by default.
Let me know if this helps.

Try this:
1. Create a parameter GroupBy
Create your data set. Don't directly write your query in to box, use expression instead.
Write your query like this:
I think you probably need to try and adjust your query expression for a while, but it should be the way to go. Good luck.

I would wrap this in a stored procedure and then call that from the dataset
create proc report_1
#value varchar(200)
as
#sqlquery = 'select name '+#value+' from foo group by field1'+ #value + ';'
EXEC(#sqlquery);
Be weary of SQL injection when using dynamic sql, it might be advisable to set a defined list of values for your drop down parameter, either statically or by querying the information schema for column names.

Related

Define MySQL field name as a variable

Is there a way to set a field name as a variable in MySQL?
For example:
set #gender = (table_name.gender_column);
select * from table_name
where find_in_set(table_name.gender_column, #gender);
This is exactly how i have tried it but i it returns "Unknown table in field list".
Thanks in advance,
Mike
EDIT: The aim is to use the variables in dynamic crystal report parameters. But what i dont want to do is have to add a new type of gender every time a new one comes along.
E.G. I have 'Male' and 'Female' and am adding 'Trans-gender'. I want the dynamic parameter in Crystal to present the 'Trans-gender' variable in the parameter when it is added to the gender_column. I dont want to have to revisit the multiple queries that use the variable to add 'Trans-gender' to it.
Is there a way to set a field name as a variable in MySQL?
No. SQL doesn't allow variables for schema, table, or column names.
There's a workaround in which you can use text-string processing to create a query, then run it. Something like this may help.
PREPARE query
FROM CONCAT ('select * from table_name',
'where find_in_set(table_name.gender_column, '
#variable,
');'
);
EXEC query;
DEALLOCATE PREPARE query;
This may be a roundabout way of doing what you want. The technical term is "big fat hairball."

In MS Access accdb VBA, how do I know in what order to suppy parameters for a query built on queries that require parameters

In my VBA subroutine I want to create a new table from a complex query
(qryA UNION ALL qryB UNION ALL qryC)
strSQL = "select * into tblNew from qryComplex"
The subsequent queries (more than the 3 initial) require parameters (assume 4) that are found in a form that is open.
By working through choices, it works for example,
Set qdf = db.CreateQueryDef("", strSQL)
qdf.Parameters(0) = Forms!frmMain.txtF1
qdf.Parameters(1) = Forms!frmMain.txtF2
qdf.Parameters(2) = Forms!frmMain.txtF3
qdf.Parameters(3) = Forms!frmMain.txtF1
qdf.Execute
How do I know the required order is deterministic?
How can I determine the order and content without having to dig into the subsequent queries and try combinations?
Access supports a PARAMETERS clause which lets you determine the order of parameters even if some/all of the parameters are only used in the underlying queries. You just have to ensure that you name all of the parameters and that you use the correct names and types. The PARAMETERS clause must be followed by a semi-colon.
You can use the Parameters Dialog in Access to help you:
Assuming all of your parameters need to be Short Text, your query would look like this:
PARAMETERS Param1 Text ( 255 ),Param2 Text ( 255 ), Param3 Text ( 255 );
SELECT * INTO tblNew
FROM qryComplex;
I use parameters from VBA and order in which they are placed was never an issue. You just have to state them all, from all queries involved.
Use the parameter names rather than their index numbers
qdf.Parameters("parameter example name 1") = Forms!frmMain.txtF1
qdf.Parameters("parameter example name 2") = Forms!frmMain.txtF2
qdf.Parameters("parameter example name 3") = Forms!frmMain.txtF3
qdf.Parameters("parameter example name 4") = Forms!frmMain.txtF1

how to escape single quotes in paramterised query

I have a problem. i am passing parameter in query using IN clause, but it is giving me error because instead of considering it as a two different values it is considering it as a one single value, so how can i handle this on sql level?
select * from table where name in ('abc','xyz'); this will work fine.
instead of this it is considering it as a
select * from table where name in ('abc,xyz'); this will give error
my parameter values are as below
basically i am checking conditional filtering. that why written this logic if values are there then consider this parameter in where clause or else ignore it.
case when '${thera}' <> '''' then
( ccp.name in ('${thera}') ) ELSE 1=1 END
Note : for avoiding conditional filtering any better approach is their then please suggest that to.
You can indeed pass a list of values as a parameter. But you need to use a Custom Parameter component.
For your example, you can create a Custom Parameter named parThera, and then for initial value you can use the expression as you would do in javascript:
['abc','xyz']
Another option is to use a function expression, like:
function (){
return "A list of words".split(" ");
}
Then, on the SQL query, add this parameter, using thera as argument name, and the parameter parThera as value.
Now you can use it inside the SQL like in your first example:
SELECT * FROM TABLE WHERE name IN (${thera})
The parameter will be expanded to 'abc','xyz', thus making it usable inside the IN (...) clause.
Note: on the SQL parameters setup, you need to specify that this parameter is of type StringArray. Otherwise it will not expand correctly.

Use CHARINDEX rather than IN clause to speed up SSRS report filters

In some cases, we are using IN clause in our filters of SSRS reports. A lots of them are causing issues with the performance by using hundreds of items inside of IN clauses.
such as:
WHERE TableA.School IN (#School)
sometimes, the multi-value parameters are really tricky to handle, you might need to do =Join(Mypara.Value,",") in the RDL and write a SQL function to convert them into a set of SQL data to be able to feed the SQL SP. (especially some older version of SSRS).
FYI: function to use to break a comma deliminator string into record set:
CREATE function [dbo].[fnSpark_BreakUpList] (
#List VARCHAR(MAX)
)
RETURNS #csvlist TABLE (Item VARCHAR(MAX))
AS
BEGIN
DECLARE #Item VARCHAR(MAX)
-- Loop through each item in the comma delimited list
WHILE (LEN(#List) > 0)
BEGIN
IF CHARINDEX(',',#list) > 0
BEGIN
SET #Item = SUBSTRING(#List,1,(CHARINDEX(',', #List)-1))
SET #List = SUBSTRING(#List,(CHARINDEX(',', #List) + DATALENGTH(',')),DATALENGTH(#List))
END
ELSE
BEGIN
SET #Item = #List
SET #List = NULL
END
-- Insert each item into the csvlist table
INSERT into #csvlist (Item) VALUES (#Item)
END
RETURN
END
GO
I will post answers shortly to show how to increase the performance by using CHARINDEX. (So you dont have to anything like above....)
If you are not actually want to retrieve the item from the LONG delimited string, but to only filtering it, CHARINDEX is a better way to go for.
Instead of using IN Clause, you could just use:
WHERE CHARINDEX(','+TableA.School+',',','​+#School+',') > 0
NOTE:
1. I pad an extra comma at the end of target string 'TableA.School' to avoid the satuation that if a big string contains a sub string same as the filtering item.
(Such as we have a school called 'AB' and another 'ABC' that we dont want the 'ABC' to be picked up when we are targeting for 'AB'.... )
I pad an extra comma at the end of resources string​ '#School' to ensure that the single item / the last item (they will end without a comma) to be picked up when we are targeting them.
I pad an extra comma at the begining of target string 'TableA.School' to avoid the satuation that if a big string contains a sub string same as the filtering item.
(Such as we have a school called 'AB' and another 'CAB' that we dont want the 'CAB' to be picked up when we are targeting for 'AB'.... )
Example:
I am using:
WHERE
CHARINDEX(','+CAST(DENTIST4.wStudentYear AS VARCHAR(10))+',',','+#StudentYear+',') > 0
TO replace:
WHERE
DENTIST4.wStudentYear IN (#StudentYear)
for one of the report i was doing, which makes 4000+ pages rendering improved from about 10 mins into under a min for a large database (11 G).
IMPORTANT NOTES:
Please make sure the filter report parameters you are passing into the dataset uses JOIN clause.
=Join(Parameters!MyParameter.Value,",")​
Hope this helps....
IMPORTANT: This approach ONLY improves performance if the filter has large set of items, for any filters with small set of items IN clause will do better jobs.

Parameters in SQL Server 2008

I have a stored procedure that pulls data for a report. I'm having a problem with the parameters. I have a couple temp tables and some joins that work so I have omitted them below. The problem is this line:
WHERE
SeminarDivision = #SeminarDivision AND SeminarType = #SeminarType
When I put this where clause in to use my seminar parameters the stored proc returns nothing But I need to generate a report based on those two parameters. So where do the parameters go? Can anyone help?
#StartDate DateTime,
#EndDate DateTime,
#SeminarDivision VARCHAR(50),
#SeminarType VARCHAR(50)
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
... OMITTED
SELECT
WL.PID,
CONVERT(varchar(20), upper(substring(FirstName,1,1))+
LOWER(substring(FirstName,2,19))) AS FirstName,
CONVERT(varchar(20), upper(substring(LastName,1,1))+
LOWER(substring(LastName,2,19))) AS LastName,
S.SeminarDivision,
S.SeminarType,
S.StartDate,
S.SeminarLocation
FROM
#tblWaitList WL
INNER JOIN #tblSeminar S ON WL.SeminarGuid=S.SeminarGuid
WHERE
SeminarDivision = #SeminarDivision AND SeminarType = #SeminarType
ORDER BY
LastName,FirstName,StartDate
First and foremost there is nothing wrong with your code, when asking where do these parameters go, they go exactly where you put them. The question is - is the data coming in for SeminarDivision and SeminarType the right type of data? For instance just as a test,
copy the code into a new sql code query inside the editor. Run the command without the where, if you get values great. Now change the where to
WHERE
SeminarDivision = "Possible_Value"
Where Possible_Value should be a possible value...If it returns rows, good...now add the second condition also hardcoding a value:
WHERE SeminarDivision = "Possble_Value" AND SeminarType="Possible_Value_2"
Getting any data? Is it possible you want OR rather then AND ?
There's nothing wrong with the 'location' of your params.
If you're getting no data back, it's either because you've not populated #tblWaiList or #tblSeminar or because the records simply don't match your WHERE clause.
Check your params have the value you think they do by executing print #SeminarDivision etc.
SELECT * FROM #tblSeminar may give you a clue too.
You are not setting parameters correctly for the call.
Try this in SSMS, change values accordingly
EXEC Proc '20110101', '20111101', 'PossibleDivision', 'PossibleType'
If this fails, then show us "OMITTED" code
if this works, show us how you are calling this from the client code