How to select all parameter values in SSRS? - sql

I have a parameters #Year and #Month in my report, where month has assigned values like January(label): 1(values), February: 2, ...
My datased is feeded by stored procedure which has a filter
WHERE (cal.CalendarYear = #Year) AND (cal.MonthId = #Month)
When I check 'Allow multiply values' in parameter settings, it returns an error
Error converting data type nvarchar into int.
How can I select all values (by default)?

If you don't need to use a Stored Proc you can easily solve the problem.
Copy the SQL from your stored proc (excluding the PROC definition, just the main code) and paste it in as your dataset query.
Change your = #Year and = #Month to IN(#Year) and IN(#Month)
That's all there is to it, no joining, splitting or anything else.
SSRS will inject the parameter values as comma separated values correctly for you.

When you select multiple values, you pass the parameter to the procedure as an expression with Join().
Then in your procedure change your month parameter to be of type nvarchar(max).
Create a temp table and use a t-sql split string function (Google this, there are so many varieties but if you're stuck we can find one) to split the string into a table. Then inner join to your table in your procedure to filter on the selections.

Your error message about "nvarchar into int" suggests a data type mismatch between your SSRS parameter and your MonthId column. Check the Report Parameter Properties -> General -> Data type for the former and your table schema for the latter, and make sure they're either both text/varchar or both integers.
Allowing your query to handle multiple parameter values should be much simpler than needing to use joins and splits. Just use IN instead of =, and put your parameter name inside a set of brackets.
AND (cal.MonthId IN (#Month))
To set the defaults for your parameter, go to the Report Parameter Properties -> Default Values. Select the Specify values option, and add your numbers 1-12 as separate Value records.

Related

Passing muliple values ssrs sql

I have the following sql:
--DECLARE #absent nvarchar(20)
--SET #absent = 'Y' -- Not needed in sql as we are setting this in ssrs
SELECT *
FROM Employee
WHERE Absent in #Absent
Here is the employees table.
Employee
Name Absent
Dan Y
Laura N
Ross N
James Y
I want to be able to filter between Y and N and both.
This is working fine for me in SSRS when I pass #absent both Y and N. However, when i convert to a stored procedure and run in SSRS, I now get an issue. I longer get any results.
ALTER PROCEDURE usp_GetEmployees
#Absent nvarchar(20)
SELECT *
FROM Employee
WHERE Absent in #Absent
I've tried the line =join(parameters!Absent.value,",") in the parameter properties but no luck. I believe the issue is with the data type that is being passed in. It is just odd that it works before i converted to a usp.
Any help is much appreciated :)
Assuming you had a typo in your question and you meant to write
SELECT *
FROM Employee
WHERE Absent in (#Absent)
The reason that this WILL work when used directly in a dataset query is that SSRS will take your multi-valued parameter's selected options, convert them into a comma separated list and inject them into the SQL. So what will actually be executed will be, for example,
SELECT *
FROM Employee
WHERE Absent in ('Y', 'N')
This process is not the same when calling a stored procedure as SSRS cannot change the code inside your SP.
When passing multi-value parameters to a Stored Proc you would typically pass in an expression such as =JOIN(Parameters!myParam.Value, ",") . This passes in a string containing a comma separated list of your selected parameter values.
Inside the Stored Proc you would typically call a function to split this string back out into a table that you can join to.
There are plenty or articles describing this and providing a usable split function in case you don't have one. Check out the answers here https://social.msdn.microsoft.com/Forums/sqlserver/en-US/0ead7ceb-3fdd-4625-aa82-1d4195f984b1/passing-multivalue-parameter-in-stored-procedure-ssrs?forum=sqlreportingservices
Your original code wouldn't work directly in SQL. You can fix it using parentheses:
WHERE Absent in (#Absent)
This is exactly equivalent to:
WHERE Absent = #Absent
which is probably not what you intend. In the more recent versions of SQL Server, you can use:
WHERE Absent IN (SELECT value FROM string_split(#Absent, ','))
The ',' is my guess at the separator you are using. You can also use:
WHERE ',' + #Absent + ',' LIKE '%,' + Absent + ',%'
With SSRS, if using a Stored Procedure, the format Column IN (#Variable) doesn't work. That type of query only works if the SQL in directly in the SSRS Data Set's definition. Then SSRS will replace the value of #Variable and (apparently) securely inject the values in a delimited and quoted list.
For something as simple this, you are, in truth, better off likely just putting the below statement in the dataset in SSRS:
SELECT *
FROM Employee
WHERE Absent in (#Absent);
If not, and you need to use a Stored Procedure, then SSRS passes a delimited string as the parameter. In such cases you need to use a splitter. Considering you tag BIDS (visual-studio-2008) then you need to use a really old way of doing this. I also strongly recommend you look at upgrade paths ASAP.
For 2008, then I recommend delimitedsplit8K (or delimitedsplitN4K if using an nvarchar). Then your Procedure will look like this:
ALTER PROCEDURE usp_GetEmployees #Absent nvarchar(4000) AS
BEGIN
SELECT E.* --YOu should replace this with your actual columns
FROM Employee E
JOIN dbo.delimitedsplitN4K(#Absent,',') DS ON E.Absent = DS.item;
END;

How to create a SQL view with variable where clause

I have a table with 37 columns. The table is populated from daily csv files. I need to create a view that filters only the previous month data set. The posting date column is a string variable in the form 20131219. I have a function that uses date functions to determine the current month, then returns a string with the year and month prior. This query returns the data set I need, but I can't figure out how to create a view that allows the variables and function call. **the paramater '2013' doesn't do anything. I couldn't get the function to work without one, so added something.
declare #newstring varchar(6)
set #newstring = [dbo].[GetPrevYearMonth]('2013')
select * from dbo.SAE_EDATA_LV
where [GTR-POSTING-DATE] like #newstring+'%'
I know I could create a function with a table return type, but that's very tedious for the number of columns.
Any help would be greatly appreciated.
Change your View to an inline Table-Valued Function (iTVF). An iTVF is really just a parametized View anyway.
You use it the exactly the same, except that you have to also specify parameters.
Alternatively, you can create an iTVF wrapper for your View:
CREATE FUNCTION dbo.fnSAE_EDATA_LV(#newstring varchar(6))
RETURNS TABLE As
select *
from dbo.SAE_EDATA_LV
where [GTR-POSTING-DATE] like #newstring+'%'
You should also know that long column lists can just be dragged from a Table/View/Table-Valued function's icon/column folder on the SSMS explorer pane and dropped into a SQL session pane.

Multi-value parameter truncation

On my SSRS report I have a multi-value parameter which contains 250+ uniqueidentifier data type values. This works fine with a small selection of values in the parameter dropdown, but when user chooses (select all), they get this error:
An error occurred during local report processing.
String or binary data would be truncated.
Each uniqueidentifier field is 36 characters long, which means 250 of them added together result in a 9000 character string. This is what causes the truncation to occur.
What approach should I take to handle this situation?
Edit:
Couple snapshots of the stored procedure:
ALTER PROCEDURE [dbo].[spReport]
#StartDate as datetime
,#EndDate as datetime
,#LocationId uniqueidentifier
,#UserIds uniqueidentifier
#UserIds is the multi-value parameter. It is used in the where clause of the query:
WHERE (U.UserId IN (#UserIds) OR #UserIds IS NULL)
You can't use an SSRS multi-value parameter with a stored procedure like that. You'll need to join the values in the report, pass them as a varchar(max), and then split them in the stored procedure:
https://stackoverflow.com/a/9862901/124386
http://www.codeulike.com/2012/03/ssrs-multi-value-parameters-with-less.html
SSRS does have a limit on the size of multi-value parameters. I can't remember what it is off the top of my head, but I think you are well beyond it. (SSRS converts the multi-value parameter to a comma separated string and replaces the occurances of the variable name in the query with the string.)
So as mentioned in the comments, you've got two problems:
SP's can't take multi-value parameters directly from SSRS. You'll need to do some manipulation.
Your overall parameter length. This may require a little bit of creativity to solve. Some options:
Can you supply either a separate parameter or a special value in your existing parameter for <All Users> and then check for this in the SP, returning all values in that case. If the query is directly in SSRS (instead of a SP) something like this would work:
...WHERE ( U.UserId in ( #UserIds) OR '<All Users>' in ( #UserIds ) )
...
Can you filter the number of items in your parameter, based on earlier parameters? Such as have the user select a date range and/or department, and only return UIDs that match that range?
Another approach is to create a user defined table type and use that instead of a varchar to pass in the selected values.

Array parameter for TADOQuery in Delphi 2010

I need to execute a simple query:
SELECT * FROM MyTable WHERE Id IN (:ids)
Obviously, it returns the set of records which have their primary key 'Id' in the given list. How can I pass an array of integer IDs into ADOQuery.Parameters for parameter 'ids'? I have tried VarArray - it does not work. Parameter 'ids' has FieldType = ftInteger by default, if it matters.
There is no parameter type that can be used to pass a list of values to in. Unfortunately, this is one of the shortcomings of parameterized SQL.
You'll have to build the query from code to either generate the list of values, or generate a list of parameters which can then be filled from code. That's because you can pass each value as a different parameter, like this:
SELECT * FROM MyTable WHERE Id IN (:id1, :id2, :id3)
But since the list will probably have a variable size, you'll have to alter the SQL to add parameters. In that case it is just as easy to generate the list of values, although parametereized queries may be cached better, depending on which DB you use.
The IN param just takes a comma separated string of values like (1,2,3,4,5) so I assume you set the datatype to ftstring and just build the string and pass that...? Not tried it but it's what I would try...

For SSRS in Visual Studio 2008, how can I make a variable accept multiple values as well as a single value?

I'm making a report with Visual Studio 2008, pulling the info from a table in a database. Let's say I just want to show the Type of employee (which is represented by an int, say 1-10) and their Name. Then my dataset would be this query:
SELECT Type, Name
FROM Employees
WHERE Type = #Type
This is SSRS, so I do not need to declare or set the variable (correct me if I'm wrong). When I run the report, it will give me an option to type in an int for the Type and it will create the corresponding report. My question is how can I set it so that I can type 1,2,3 in for the Type so that I get a report with those types of employees? So having the int variable be able to accept a list of ints or just one int. Essentially the "resulting query" from that example would look like this:
SELECT Type, Name
FROM Employees
WHERE Type = 1 AND Type = 2 AND Type = 3
On the left side in the Report Data window under the Parameters folder, right click the variable, hit Parameter Properties, then check 'Allow Multiple Values' and select the correct datatype in the dropdown. I'm not sure why it decides to make a dropdown when you run the report, and you have to enter the values each on their own line instead of separated by commas, but it seems to work fine. Then just change the WHERE clause in your dataset from WHERE Type = #Type to WHERE Type IN (#Type). I don't know if the parentheses are necessary.
Also if you create a separate dataset that will present certain values you can have those show up instead of having to type them out. For example, create a dataset that contains this query
SELECT DISTINCT Type
FROM Employees
ORDER BY Type
This will create a list of distinct values for type that you can check/uncheck. You can make it more complex obviously as well.