There are many ways to do this, but I thought that I would write an article on how to load available values for a drop down list box parameter in reporting services. Let’s say that you wanted to provide a numerical value to represent status values. Perhaps your company has a status tracker for tasks and it could range from 0% - 100% complete. If you wanted to load the parameter to be in 5% increments the HARD WAY, you may add them all manually like I did in figure 1 below.
Figure 1: Manually Adding Available Values
Now maybe there is reason that you would want to do it the hard way, but just know that there is an easier way.
You may opt to do something a little quicker like generating the numbers via a script. I have a script that I am going to provide below, but let me tell you what it is doing so that you can implement it in your environment and make any changes that you need.
First, I am creating a table to hold a unique listing of values.
CREATE TABLE #Numbers (Value TINYINT)
Next, I am declaring some of my variable to hold the starting number, ending number, current number and what number you want to increment by.
DECLARE @StartNum TINYINT
, @EndNum TINYINT
, @CurrentNum TINYINT
, @IncrementBy TINYINT
Here, I am setting the default values. If you are using 2008, you should be able to set the values when you declare them.
SELECT @StartNum = 0, @EndNum = 100, @CurrentNum = 0, @IncrementBy = 5
Then, I am writing a while loop through from the starting number all the way to the ending number with inserting the current value into the temporary table created above.
BEGIN
WHILE @CurrentNum <= @EndNum
INSERT INTO #Numbers SELECT @CurrentNum
SELECT @CurrentNum = @CurrentNum + @IncrementBy
END
Finally, I am returning a list of the numbers that can be used by my parameter
SELECT * FROM #Numbers
Complete Script: Generate Numbers
--Temporary Table
--Declaring My Variables
--Setting the default values
--Loop Through from Beginning to End
--Now Return My Results Please
Results of executing the entire script above should give you results as shown in figure 2.
Figure 2: Results
Now all you’ll need to do is create a new dataset named StatusValues and load the parameter based off of the query results of the StatusValues dataset as shown in figure 3. Note that this will look different if you are using 2005.
Figure 3: Parameter Available Values
Now that we’ve got that all done, let me suggest yet another option! You could even create a stored procedure with parameters for all of the parameters that we declared. Then from the dataset properties, you could set the values you want to send into your stored procedure. Like I said, it is yet another way to achieve the desired results.
Until next time, “keep your ear to the grindstone” – Good Will Hunting
Brian K. McDonald, MCDBA, MCSDBusiness Intelligence Consultant – Pragmatic Works Consulting
Email: bmcdonald@pragmaticworks.com | Blog: BI Developer Network
Convert with DTS xChange | Develop with BI xPress | Process with TaskFactory | Document with BI Documenter
I have used table based functions in a very similar way. Adding the extra layer of abstraction of a stored procedure or function in this way also provides long term flexibility. In my case, my function is used in at least a dozen reports. If I need to make a change to the data I change the function, and poof all my reports are updated.
I think keying in values from 0 through 100 incrementing by 5 is a better option (though requires some patience to enter values manually and there is a risk of missing a value or keying in an incorrect value) since this is a one time task during the process of development. However, if we put this in a dataset using the query provided above or a function or a procedure or any other T-SQL, then it has to make a connection to the database everytime the report is invoked adding to the network traffic. Instead if these values are static / manually entered then time to make a connection to database is saved and also reduces the number of connections by 1 for every such dataset.
Your thoughts ?
That is a very good point. One should try to reduce the amount of network traffic as much as possible and opening up another connection wouldn't be a good thing. However, I don't think this would open up a new connection. I would hope that Microsoft would use connection polling and as such, one open connection would be used throughout the execution of the entire report. I will definitely dig deeper into the internals to research this, but I would guess that only one connection would be made. As far as the amount of data that would be pulled back by a query like this, it wouldn't be all that much. We are talking about integer values here and we all know how much space int's take. Also, let me point out, what if we wanted to make the number increment by 1's? ie.. 1, 2, 3, 4 ~ 100. Or possibly up to 500? I sure wouldn't be the one typing those numbers into the available values boxes. :)
Thank you brian for the article. I tend to lean towards stored proceudres since all the code can reside in one place, for example if the same parameter goes across reports, using a dataset calling the SP would be more efficient compared to typing it in each of the reports.
Another fun thing using this methodology is when you have a multi-select parameter and want to display values in addition to the selected set. For example, if you wanted to have a multi-select list of all of the states in the USA but only wanted to select states by some criteria ( say... ones that have universities in the top 100 for the world ). You'd create your dataset to populate the multi-select list with all of the states and then you can create another query to poll the dataset for the selected states. You'd then utilize the second query for the default values of the parameter.
Chris