I have some SQL reports that has very slow performance, so we converted all of them into FetchXML, but all the SQL reports has all the conditions optional, something like this:
SELECT
...
FROM ...
WHERE (#operator = 'All' OR Operator = #operator)
AND (#new_gen_comp_name = 'All' OR new_gen_comp_name = #new_gen_comp_name)
...
In the parameters values, there is a value All if the user select this value, the condition will be ignored and therefore it will get all the values from that field.
Now I want to do that in FetchXML, I tried to put two conditions with filter or between them, one for the value and another to include null values like this:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="incident">
...
...
<filter type="and">
<filter type="and">
<condition attribute="createdon" operator="on-or-after" value="#StartDate" />
<condition attribute="createdon" operator="on-or-before" value="#EndDate" />
</filter>
<filter type="or">
<condition attribute="new_gen_comp_type" operator="in" value="#new_gen_comp_type" />
<condition attribute="new_gen_comp_type" operator="null" />
</filter>
</filter>
...
...
</entity>
</fetch>
This worked fine only if the user select all the values for the parameter #new_gen_comp_type, but the problem is if the user select only specific values, it will include the null values too, and that is wrong.
So, is there any way to make these conditions optional in case if the user select select all for the values of the parameter like in SQL?
Since you're doing this in SSRS, you don't have an option to change the Fetch XML which is what you really need to do. (If the user selects "ALL", don't include a constraint on new_gen_comp_type)
The only option I can think of is kind of dumb but it should work. Create a new attribute on Incident new_all that is defaulted to "ALL", and run an update statement to populate all of your existing Incidents to "ALL". Then change your FetchXml filter to:
<filter type="or">
<condition attribute="new_gen_comp_type" operator="eq" value="#new_gen_comp_type" />
<condition attribute="new_all" operator="eq" value="#new_gen_comp_type" />
</filter>
If the user selects "ALL" the second statement will be true and everything will be returned. If the user selects something besides ALL, the second statement will always be false and the first statement will only return what matches.
Please note that attribute operator="in" will not work with multiple values. You need to make a value child tag with each value...
From the XSD:
The attribute "value" is used for all operators that compare to a
single value (for example, eq).
The element "value" is used for operators that compare to multiple values (for example, in).
Some operators require neither the attribute "value" or the element "value" (for example, null).
I found a solution for this using the dataset filters, I removed all the conditions from the fetchxml(I left only those conditions that aren't optional). Then I made all the parameters multi valued, if the user select more than one vale it will make the parameter optional, otherwise if he selects one value it will search with it.
I added a filter for each condition, for example if you have a condition in the fetch xml like this:
<condition attribute="attribute1" operator="in" value="#a1" />
...
...
Then I added a filter for each conditions like so:
Right click the data set that the table is reading from.
Click the properties.
Choose the filters tab.
Click the Add button.
In the expression choose the fild [attribute1].
For the operator choose in.
For the value, click the function button fx and enter the following expression =IIf(Parameters!a1.Count>1,Fields!attribute1.Value,Parameters!a1.Value).
So if the user selects only one value for the parameter values, the condition will be false then the field attribute1 will be compared to the parameters value, therefore the condition will be applied otherwise the field value will be compared to its value, which is always be true, so that the condition will be always true and ignored.
The problem with thi solution is that, the user can't select multi values and search with them, it will be treated as it selects all the values, I tried to overcome this by:
Checking if the selected values for the parameter values equal to the count of the total values of the dataset that the parameter is populated from or if it is not populated from a data set, compare the total values to the total count of all the values instead of checking if the count is greater than 1, but I couldn't be able to do that. I got an error that I couldn't use an aggregate in the filters expressions.
Trying to include a null value into the parameters values (I couldn't do that in my case because the parameter values was populated from a dataset), so that I can check if the selected value is null then ignore the condition, somthing like this: =IIf(Parameters!a1.value = nothing,Fields!attribute1.Value,Parameters!a1.Value).
If you could make one of these works, then this solution will work fine.
Note that, you might need to use Parameters!a1.Label instead of Parameters!a1.Value if that field has a label attribute1name and a value attribute1, this is the way fetchxml works. So use parameter label to get the name to compare it to attribute1name or use paramter value to compare it to attribute1.
Although an assumption, I see you are attempting a FetchXML based report in CRM.
It is suggested to use CRM default filters in this case.
The query requires no condition and just have select columns.
This would allow you to have optional parameters.
[Note: Filters/Parameters are applicable only of entity/related entities being queried]
Related
I am passing a unique ID as parameter in SSRS report. In the source table, unique id does not contain dashed. However, the user may insert Unique ID including dashes "-" and in some cases without dashes. Is there a way that we could remove dashes from the parameter.
For example, unique id 3120-20268-8 is stored in table as 3120202688. How I could retrieve if user pass multiple values with or without dashes in the SSRS Report.
When is used below query, it gives record against single value only. However, gives error when more than one values are provided.
select * from Table
where Unique_ID in (REPLACE(#Unique_ID,'-',''))
For more than 1 values, it gives errors mentioned below:
The replace function requires 3 argument(s).
Query execution failed for dataset 'ATL_List'.
Thanks
One of the simplest mechanisms for this is to create an expression based parameter to hold the sanitised input. This parameter would be hidden so the user is not aware of it, but the rest of the usage of the parameter is the same.
NOTE: You could do something similar with a query based default value, but this case is easier to do via a simple expression
Single Value Parameter
Create a new parameter:
set it to hidden
Set the default value expression:
=Str(Parameters!inputID.Value).Replace("-","")
Multi-Value Parameter
This is only slightly trickier, in the expression we can join the selected values together into a CSV string, then process that value and then split it back:
Set the parameter to multi-value, but still hidden:
Set the default value expression:
=Join(Parameters!inputID.Value,",").Replace("-","").Split(",")
Without going to detailed, if we made the sanitised parameter temporarily visible, just to demonstrate the conversion, it should look like this:
The parameter MUST be hidden!
NOTE: DO NOT make your sanitised parameter visible as in the above screenshot in your deployed report! Doing so will mean that it will not pickup changes made to the input value after it has rendered the first time.
remember that we have exploited the default value, we haven't arbitrarily defined en expression to always execute.
The output when the parameter is hidden is calculated when the report is rendered, it's just harder to visualise the behavior in this static post:
In your DataSet query you would just use the sanitised parameter:
SELECT * FROM Table WHERE Unique_ID IN (#sanitisedMultiValue)
You should be able to use the replace function in your report to format the parameter value after it has been entered, something like the below
replace(Fields!Paramater.Value,"-","")=FieldinYourTable
I am working on Microsoft Dynamics Reporting service. My requirement is to show records which is dated 3 years or earlier from a given date. The parameter I have is a date selection field. What I am trying to achieve is get records based on my condition from the date I have selected on the parameter.
To filter data based on the current date, I can use:
<condition attribute="modifiedon" operator="olderthan-x-months" value="36" />
But, to get the data filtered based on the parameter value is what I can't figure out.
Can someone help me with this?
You should use between operator, but in fetchxml you can achieve it this way.
<filter type="and">
<condition attribute="modifiedon" operator="on-or-after" value="2016-10-04" />
<condition attribute="modifiedon" operator="on-or-before" value="2019-10-03" />
</filter>
Also expression can help you to calculate and pass parameters.
We can add a dynamic date for the report. We can add another date which will have a custom code to have a date 3 years prior to the input date or current date. This date can be referenced to the FetchXML query to filter the records.
So I have a multiple value parameter than contains 3 options. >250K, <250K, >2M.
I also have a table that consists of multiple columns.
. Because the parameter is a multivalue, i am having difficulties filtering the dataset.
I need to filter the dataset by checking, (if > 250K is selected, filter the dataset accordingly), (if < 250K is selected, filter the dataset accordingly) and (if > 2M is selected, filter the dataset accordingly).
I was told to use a join and split on the parameter within the (>250K condition, then do a contains to see if it contains any of the parameter values) but I am not as advanced in my knowledge of coding to be able to do that.
Any Suggestion? Thanks in Advance
I previously tried the method below but then i came to realise that it wont work because the parameter is a multi value.
I know its been a while since you raised this, you were on the right track but all you should need to do is add a filter to the Tablix on the field you will be filtering, use the 'in' operator and in the Value type [#Yourparametername] the square brackets and case sensitivity are important. Also ensure the expression type is correct, in your case it looks like you are using Integer. The image should help.
If you want to use multi-parameters, In the dataset, you can read parameter value using JOIN.
Example:
If you want to read multiple values for #MyParamter in a dataset given in the following example:
Dataset Parameters
you need to use =JOIN(Parameters!myMultiParamter.Value,",") as an expression to read all selected values in CSV form.
Expression
Now the #ParameterValues param has all selected values as comma separated values and you can use them in your dataset code as per design requirements.
Note: It's not necessary to use a comma but u can use anything you want to separate values.
Your sql query where should look like
Where
(
(0 IN (#Parameter) AND ValueColumn<250000)
OR
(1 IN (#Parameter) AND ValueColumn>=250000)
OR
(2 IN (#Parameter) AND ValueColumn>=2000000)
)
One parameter
Two parameters
All parameters
Once you return the value you can also use charindex or patindex* and look for where the value in your where clause is a pattern where the index number is > 0 . For instance if the returned string from SSRS is '01,02,03' and then your where clause has something like this right(field, 2) which would result in value '03'. you change your where clause to be where patindex('%' + right(field, 2) + '%', #returnedstring) > 0 which will give you results. The keeps you from having to parse apart the #returnedstring parameter in your sql code.
I have a master that can be filtered using 4 different parameters. I used a iif statement to join all the parameters to filter the report.
The problem I am now having is when more than one paramater is selected, it tends to return values for the first parameter rather than for all
My paramter expression is as follows:
expression
iif(IsNothing(Parameters!Div.Value)=0,Parameters!Div.Value
,iif(isnothing(Parameters!St.Value)=0,Parameters!St.Value
,iif(isnothing(Parameters!Sp.Value)=0,Parameters!Sp.Value
,Parameters!Hc.Value)))
values
=iif(IsNothing(Parameters!Div.Value)=0,Parameters!Div.Value
,iif(isnothing(Parameters!St.Value)=0,Parameters!St.Value
,iif(isnothing(Parameters!Sp.Value)=0,Parameters!Sp.Value
,Parameters!Hc.Value)))
Any help will be helpful
I think what you are trying to do is something like this:
=IIF(NOT ISNOTHING(Parameters!Div.Value), Parameters!Div.Value,
IIF(NOT ISNOTHING(Parameters!St.Value), Parameters!St.Value,
IIF(NOT ISNOTHING(Parameters!Sp.Value), Parameters!Sp.Value,
Parameters!Hc.Value)))
Do you only want to check for one value?
I usually check each parameter separately so it uses all of them at once. Though there may be a situation where your theory is what you want.
If you want to evaluate all the parameters, just add them to the FILTER of the dataset, table, or group. Choose your field in the Expression and the Parameter in the Value.
I need to be able to set an SSRS parameter to contain multiple values.
In TSQL, I can have a where clause that states:
where Attribute in ('Value1', 'Value', 'Value3')
What I need is in SSRS to have:
where Attribute in (#Attribute)
Where I am getting hung up is how to format the parameter value expression so that SQL sees it as: 'Value1', 'Value', 'Value3'
I have had some luck making the where clause look at only the first value, but I need it to look at all 3. How would I format the expression to do that?
I would just allow it to accept multiple values, and check each value individually, but I need the drop down list to have groups. So, if the user selects GroupA, the where clause uses: IN ('Value1', Value2') and if the user selects GroupB, the where clause uses a different list for the IN.
Hopefully it's just a matter of formatting the expression correctly.
Well, if you didn't have the requirements about groups, this wouldn't be an issue since all you need is to make your parameter a multi-valued one, and on your dataset query do WHERE Attribute in (#Attribute). But taking that requirement into account, the only way I can think of, is to have two multi-valued parameters: #Group and #Attribute. You'll need to make #Attribute not visible and create a dataset to populate it. That dataset would be something like this:
SELECT Attribute
FROM Attributes
WHERE Group IN (#Group)
And create another dataset for your report data:
SELECT <all your data>
FROM YourTable
WHERE Attribute IN (#Attribute)