SSRS: Change SQL Statement Dynamically
Asked Answered
C

8

5

I have a report in SSRS 2005 that's based on a query that's similar to this one:

SELECT * FROM MyTable (NOLOCK) 
WHERE col1 = 'ABC'
AND col2 LIKE '%XYZ%'

I need to be able to dynamically include the AND part of the WHERE clause in the query based on whether the user has checked a checkbox. Basically, this is a dynamic SQL statement and that's the problem. I tried several approaches to no avail. Is this possible? Does SSRS 2005 supports dynamic SQL? Thanks!

Colitis answered 26/9, 2008 at 4:33 Comment(0)
P
15

Charles almost had the correct answer.

It should be:

SELECT * FROM MyTable (NOLOCK) 
WHERE col1 = 'ABC'
   AND (@checked = 0 OR col2 LIKE '%XYZ%')

This is a classic "pattern" in SQL for conditional predicates. If @checked = 0, then it will return all rows matching the remainder of the predicate (col1 = 'ABC'). SQL Server won't even process the second half of the OR.

If @checked = 1 then it will evaluate the second part of the OR and return rows matching col1 = 'ABC' AND col2 LIKE '%XYZ%'

If you have multiple conditional predicates they can be chained together using this method (while the IF and CASE methods would quickly become unmanageable).

For example:

SELECT * FROM MyTable (NOLOCK) 
WHERE col1 = 'ABC'
    AND (@checked1 = 0 OR col2 LIKE '%XYZ%')
    AND (@checked2 = 0 OR col3 LIKE '%MNO%')

Don't use dynamic SQL, don't use IF or CASE.

Pahl answered 26/9, 2008 at 7:46 Comment(3)
Yep, I can't abide dynamic SQL, impossibly hard to debug, maintain or upgrade. Some minor performance improvements if you have large numbers of optional parameters, but even with up to 30 parameters I got good performace without resorting to it.Hydrostatic
Not to mention how dangerous it is, from a security PoVThermostatics
Excellent answerAudit
S
3

How about this. @checked is your bit variable.

SELECT * FROM MyTable (NOLOCK) 
WHERE col1 = 'ABC'
AND (@checked <> 0 and col2 LIKE '%XYZ%')

Edit: Also, if you aren't using a stored proc, then use one.

Stilla answered 26/9, 2008 at 5:35 Comment(2)
It doesn't work in the case where checked is false (0). It will not return any matches in this case, even though some may exist.Crossbred
Your answer is great but in the case where we can't execute on the data source and we have read-only access to data the strored procedure approach won't work.Hyperextension
W
1

Perhaps this would work for you:

if @checked = 1
    select * from mytable (nolock) where col = 'ABC'
else
    select * from mytable (nolock) where col = 'ABC' AND colw Like '%XYZ%'

I'm sorry I don't use SSRS much, but if you can get the value of the checkbox into the @checked parameter this should work.

Alternately you could use a CASE WHEN statement.

Wimple answered 26/9, 2008 at 5:0 Comment(1)
In SQL Server this can cause query plan recompilation, which can hurt performance. If you use this pattern in your own procedures, consider splitting so that you have the master procedure, which chooses which child procedure to call based on parameters - One procedure one query.Hydrostatic
S
1
SELECT * FROM MyTable (NOLOCK) 
WHERE col1 = 'ABC'
AND col2 LIKE CASE @checked WHEN 1 THEN '%XYZ%' ELSE col2 END
Sclerotic answered 26/9, 2008 at 5:56 Comment(0)
E
1

This would work in SSRS 2000 but used as a last resort.

(bad) PSEUDOCODE

="SELECT * FROM MyTable (NOLOCK)
WHERE col1 = 'ABC'"+
iff(condition,true,"AND col2 LIKE '%XYZ%'","")

Check out Executing "Dynamic" SQL Queries. from the Hitchhiker's Guide to SQL Server 2000 Reporting Services

Eft answered 26/9, 2008 at 6:12 Comment(0)
S
1

One way to do this is by generating the SSRS query as an expression. In the BIDS report designer, set your query up like so:

="SELECT * FROM MyTable WITH (NOLOCK) WHERE col1 = 'ABC'" +
 Iif(Parameters!Checked.Value = true," AND col2 LIKE '%XYZ%'","")
Spillman answered 26/9, 2008 at 7:38 Comment(0)
C
0

You can also take another approach and use the Exec function:

DECLARE @CommonSelectText varchar(2000)  
DECLARE @CompleteSelectText varchar(2000)  
SELECT @CommonSelectText = 'SELECT * FROM MyTable (nolock) Where Col = ''ABC'' '  

IF @checked = 1   
    SELECT @CompleteSelectText = @CommonSelectText + ' AND ColW LIKE ''%XYZ%'' '  
ELSE  
    SELECT @CompleteSelectText = @CommonSelectText  

EXEC (@CompleteSelectText)  

GO  

Note the use of two apostrophes ' to mark the quoted text.

Crossbred answered 26/9, 2008 at 5:29 Comment(0)
Z
0

if you can use stored procedures, its probably easier to do it there. pass in your params. Create a SQL String based on your conditions and do an EXEC on the sql string, your stored proc will return the results you need.

Zingg answered 26/9, 2008 at 16:35 Comment(1)
Your answer is great but in the case where we can't execute on the data source and we have read-only access to data the strored procedure approach won't work.Hyperextension

© 2022 - 2024 — McMap. All rights reserved.