Reputation: 245
The application passes 5 different filter conditions from the UI to the query. ie,--STORE CODE DESC NOTES QTY.
When I add these conditions with different possibilities it is coming very long, ie
--1 0 0 0 0
IF @Store<>'0' AND @code='' AND @DESC='' AND @Notes='' AND @QTY=0
--1 1 0 0 0
--1 1 0 0 1
--1 1 1 0 0
--1 1 1 1 0
etc..........
is there any way to simplify this to pass as single query. Hope the question is understandable.
Sample code I have done as below,
SET @sql = 'Select * from tbl_store Where Inactive=0 ';
--10000
IF @Store<>'0' AND @Code='' AND @Description='' AND @Notes='' --AND @Qty<>''
SET @sql += ' AND Store=@Store AND Quantity = @Qty';
--11000
ELSE IF @Store<>'0' AND @Code<>'' AND @Description='' AND @Notes='' --AND @Qty<>''
SET @sql += ' AND Store=@Store AND Code=@Code AND Quantity = @Qty';
........................
Upvotes: 1
Views: 1529
Reputation: 6604
I would do away with the dynamic query if possible and do something like this:
select *
from tbl_store ts
where ts.Inactive = 0
and (
( @Store <> '0' and @Description = '' and @Notes = '' and Store = @Store and Quantity = @Qty)
or
(@Store <> '0' and @Code <> '' and @Notes <> '' and Code = @Code and Store = @Store and Quantity = @Qty)
);
Using dynamic queries, such as yours, can lead to security holes, and general confusion about how things are being done. In my opinion, it should be one of last resorts.
Upvotes: 1
Reputation: 15175
I would place any validation outside of the query and simply filter your query as follows.
SET @IsValidFilter=<YOUR VALIDATION LOGIC HERE>--IF YOU CAN'T TRUST INCOMING VALUES
SELECT
*
FROM
MyTable
WHERE
(@IsValidFilter=1)
AND
(@Store IS NULL OR MyTable.StoreID=@Store)
AND
(@code= IS NULL OR MyTable.CodeID=@Code)
AND
(@DESC IS NULL OR MyTable.Description=@Desc)
AND
(@Notes IS NULL OR MyTable.Notes=@Notes)
If you can't trust the values being passed in and need some logic based on a combination of parameters values then it would be more readable to create a @ValidFilter flag and simply add a final AND @ValidFilter=1
and not do too much in the WHERE
.
Upvotes: 7
Reputation: 1269753
Do them one at a time:
SET @sql = 'Select * from tbl_store Where Inactive = 0 ';
IF @Store <> '0'
SET @sql += ' and Store = @Store';
IF @Qty <> ''
SET @sql += ' and Quantity = @Qty';
. . . .
For performance reasons, what you are doing is a good idea. If an appropriate index is available, the ultimate where
clause should be able to take advantage of appropriate indexes. A single where
condition such as this won't:
where (@store = '0' or start = @store) and
(@qty = '' or quantity = @qty) and
. . .
Upvotes: 1