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

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.

Related

Report Builder - 3 Parameters all in one Query. Forward dependencies are not valid

I have an issue with building my report, I have 3 params and all 3 are in a query, they are supposed to get their values from the "drop down menus" before running the reports and are used in a where cluase to get specific stuff from the database. However I can seem to get it to work.
Example Query
Select * from [Table]
Where ID = #ID and DateFrom = #DateFrom and DateTo = #DateTo
order by ID
This is the query, I tried changing the orders of the params but it doesnt work.
Error:
The report parameter 'ID' has a DefaultValue or a ValidValue that depends on the report parameter "ID". Forward dependencies are not valid.
Based on the error you reported...
"Error: The report parameter 'ID' has a DefaultValue or a ValidValue that depends on the report parameter "ID". Forward dependencies are not valid."
I suspect your ID parameter's valid values are taken from a dataset query. The dataset query uses a parameter called #ID . You cannot populate values for a parameter if the parameter you are trying to populate is required by the query.
If you are trying to get a list of available ID's to populate the ID parameter drop down then you need to create a separate dataset for this. The dataset query would be something simple like.
SELECT DISTINCT ID FROM [Table] ORDER BY ID
You can then change your ID parameter's "Available Values" dataset to point to this new dataset.
If this does not help, show you report design (the parameters at least), the parameters properties and the dataset queries for each one. Your issue should be clear once all that is visible.

How to Pass Report Parameter as if it were a Query Parameter?

I am trying to make a report that allows a user to input an ID and then check this ID against several payee tables to see if the value already exists. The code requires an input and then displays a value of 1 if the code already exists and a 0 if the code is available for use. This works in the SQL code when setting the ID as a query parameter, but does not appear to work when creating an SSRS report and passing a report parameter through; the report displays no data.
I have tried adding a tablix column to display the parameter for validation. This field remains blank when attempting to pass a report parameter, but does properly display when hardcoding the query parameter.
DECLARE #id varchar(8)
SELECT #id,
CASE
WHEN #id IN (
SELECT id
FROM payee_1
)
THEN 1
WHEN #id IN (
SELECT id
FROM payee_2
)
THEN 1
WHEN #id IN (
SELECT id
FROM payee_3
)
THEN 1
ELSE 0
END as validation
The SQL query produces the results I would like to see in the SSRS report. It simply shows the input ID and a 1 if not available (or a 0 if available). When input into SSRS, the report parameter never passes through as if it were a query parameter and my report ends up being blank.
When your report is open for edit (Visual Studio), in the "Report Data" panel (docked on the left, by default), expand "Datasets". Right-click your Dataset and choose "Dataset Properties".
In the "Dataset Properties" window, on the left, click "Parameters". The parameters shown are populated from your query. If you have a parameterized query, then this will give you the option to bind your query parameters ("Parameter Value") to your report parameters, or set up other defaults or formulas, etc.

SSRS Dropdown for column items

I've built a SSRS report using a SQL query for the Dataset1. I'm trying to build a parameter that gives the users a dropdown list. I ended up creating a Dataset2 to get distinct values for the parameter Label and then use Dataset1 for the actual value (allowing for multiple values).
EDITING PER Request:
Dataset1 query:
SELECT vu_SOPWork_HistoryUnion.Type
,vu_SOPWork_HistoryUnion.SOPTYPE
,vu_SOPWork_HistoryUnion.SOPNUMBE
,vu_SOPWork_HistoryUnion.Date_Document
,vu_SOPWork_HistoryUnion.ExtendedPrice
,IV00101.ITEMNMBR
,IV00101.USCATVLS_2 AS Family
,IV00101.USCATVLS_3 AS Product
,vu_SOPWork_HistoryUnion.VoidStatus
,RM00101.CUSTCLAS
,GL00100.MNACSGMT
,vu_SOPWork_HistoryUnion.BillTo_CustNum
,vu_SOPWork_HistoryUnion.BillTo_CustName
,vu_SOPWork_HistoryUnion.sales_territory
,vu_SOPWork_HistoryUnion.ITEMDESC
FROM (
(
test.dbo.vu_SOPWork_HistoryUnion vu_SOPWork_HistoryUnion INNER JOIN test.dbo.IV00101 IV00101 ON vu_SOPWork_HistoryUnion.ITEMNMBR = IV00101.ITEMNMBR
) INNER JOIN test.dbo.RM00101 RM00101 ON vu_SOPWork_HistoryUnion.BillTo_CustNum = RM00101.CUSTNMBR
)
INNER JOIN test.dbo.GL00100 GL00100 ON IV00101.IVSLSIDX = GL00100.ACTINDX
Dataset2 Query:
SELECT DISTINCT IV00101.USCATVLS_2 AS FamilyNames
FROM test.dbo.IV00101
I would like to use the Dataset2 "FamilyNames" as the label options against Dataset1 "Family" values. Dataset2 gets the distinct values that I want to put in the drop down for the user to choose and then receive all rows that has that value in Dataset1 "Family". I'm an expert on not giving enough information. Hope this helps you help me. Thanks.
OK, do the following..
Create DataSet1 with the query as you have it now but append the following to the end of the query
WHERE USCATVLS_2 IN(#Family)
When you do this, the #Family parameter will be created automatically in your report, we'll get back to this later.
Create another dataset called Dataset2 (or a more sensible name like 'families' in this case) with the following simple query.
SELECT DISTINCT USCATVLS_2 FROM test.dbo.IV00101 ORDER BY USCATVLS_2
Edit the #Family parameter:
Set it to multi-value
Change the available values to be a query
Select your 2nd dataset as the datasource
Choose USCATVLS_2 as both the labels and values.
Create your report as normal with the tablix/matrix based on Dataset1.
Notes:
A few other things you might want to consider, but not required.
If a list of family names with some kind of ID is available in your database then I suggest you use that for your parameter list, you would also then have to edit the query in dataset1 to match. Remember that the parameter will contain whatever is in the column of the query that you chose as the value column in the dataset that populates the parameter list
Consider using aliases for table names in your queries rather than the full table names all the time, it makes the code more concise and easier to read.
Name your datasets according to what they contain or do, e.g. I would call Dataset2 'Families' or something similar as that is what it contains. When your reports get more complex it will make them easier to understand.

How to select all parameter values in SSRS?

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.

.NET Convert the contents of a DataTable to another DataTable with a different schema

I have a program where the user will have the option to map a variety of data source with an unpredictable column schema. So they might have a SQL Server database with 10 fields or an excel file with 20 - the names can be anything and data types of the fields can be a mixture of text and numeric, dates, etc.
The user then has to provide a mapping of what each field means. So column 4 is a "LocName", column 2 is a "LocX", column 1 is a "LocDate", etc. The names and data types that the user is presented as options to map to is well defined by a DataSet DataTable (XSD xchema file).
For example, if the source contains data formatted like this:
User Column 1: "LocationDate" of type string
User Column 2: "XCoord" of type string
User Column 3: "YCoord" of type string
User Column 4: "LocationName" of type int
and the user provides a mapping that would require that translates to this for the Application required DataTable:
Application Column "LocName" of type string = Column **4** of user table
Application Column "LocX" of type double = Column **2** of user table
Application Column "LocY" of type double = Column **3** of user table
Application Column "LocDate" of type datetime = Column **1** of user table
I have routines that connect to the source and pull out the data for a user query in "raw" format as a DataTable - so it takes the schema of the source.
My question is, what is the best way to then "transform" the data from the raw DataTable to the required application DataTable bearing in mine that this projection has to account for type conversions?
A foreach would obviously work but that seems like brute force since it will have to account for the data types with every loop on each row. Is the a "slick" way to do it with LINQ or ADO.NET?
I would normally do in select that "looks like" the destination table, but with data from the source table. You would apply the data conversions also as required.
Select
Cast (LocationNameLocationName As varChar(...) As LocName
, LocX As XCoord
, ...
From SourceTable
Hard to describe in a simple answer. what I've done in the past is issue an "empty" query like "Select * From sourcetable Where 1=0" which returns no rows but makes all the columns and their types available in the result set. You can cycle through the column ADO objects to get the type of each. You can then use that info to dynamically build a real SQL statement with the conversions.
You still have a lot of logic to decide the conversion, but they all happen as you're building the statement, not as the table is being read. You still have to say in code "if the source column is Integer and the destination column is character, then I want to generate into the select ', Cast ( as Varchar) '"
When you finish building the text of the select, you have a select you can run in ADO to get the rows and the actual move becomes as simple as read/write with the field coming in just as you want them. You can also use that select for an "Insert into Select ...".
Hope this makes sense. The concept is easier to do than to describe.