Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building dynamic where condition in SQL statement

I want to build custom Where condition based on stored procedure inputs, if not null then I will use them in the statement, else I will not use them.

if @Vendor_Name is not null
    begin 

    set @where += 'Upper(vendors.VENDOR_NAME) LIKE "%"+ UPPER(@Vendor_Name) +"%"'

    end
    else if @Entity is not null
    begin
    set @where += 'AND headers.ORG_ID = @Entity'
    end
select * from table_name where @where

But I get this error

An expression of non-boolean type specified in a context where a condition is expected, near 'set'.
like image 861
Mohamed T Avatar asked Sep 30 '13 09:09

Mohamed T


People also ask

What is dynamic WHERE clause?

You can see in example 2.3 that WHERE -clause is built dynamically using the CASE function. It evaluates the expression and checks whether the parameter values are NULL or not. When this boolean expression returns true , it uses the parameter value in the comparison operation.

Can we put case in WHERE condition in SQL?

CASE can be used in any statement or clause that allows a valid expression. For example, you can use CASE in statements such as SELECT, UPDATE, DELETE and SET, and in clauses such as select_list, IN, WHERE, ORDER BY, and HAVING.

Which is used to build dynamic SQL?

The DBMS_SQL package is a PL/SQL library that offers an API to execute SQL statements dynamically. The DBMS_SQL package has procedures to open a cursor, parse a cursor, supply binds, and so on. Programs that use the DBMS_SQL package make calls to this package to perform dynamic SQL operations.


2 Answers

old question but want to add that i just found using

where CASE WHEN @id = 0 THEN 1 ELSE id END = CASE WHEN @id = 0 THEN 1 ELSE @id END

this is from these steps:

where id = @id

check if @id is null (or invalid) or have valid value so replace @id using case:

where id = 
CASE WHEN @id is null
    THEN 0
    ELSE @id
END

this is will end up as

where id = 0 -- if @id is null, still affected your query
where id = @id -- if @id have valid value

because we want use this "where" clause only if have valid data then we change id too

where 
CASE WHEN @id is null
    THEN 0
    ELSE id
END 
= 
CASE WHEN @id is null
    THEN 0
    ELSE @id
END

then will end up as

where 0 = 0 -- if @id is null and it doesn't affect your query
where id = @id -- if @id have valid value

don't forget if id is varchar, use 0 as '0'

CASE WHEN @id is null
    THEN '0'
    ELSE id
END 

i use this in my project and working well, even i use more than 1 of this in one query. please let me know if this query costing time at larger data

like image 187
gondai yosuke Avatar answered Oct 27 '22 06:10

gondai yosuke


You cannot simply put your variable in normal SQL as you have in this line:

select * from table_name where @where;

You need to use dynamic SQL. So you might have something like:

DECLARE @SQL NVARCHAR(MAX) = 'SELECT * FROM Table_Name WHERE 1 = 1 ';
DECLARE @Params NVARCHAR(MAX) = '';

IF @Vendor_Name IS NOT NULL
    BEGIN
        SET @SQL += ' AND UPPER(vendors.VENDOR_NAME) LIKE ''%'' + UPPER(@VendorNameParam) + ''%''';
    END
ELSE IF @Entity IS NOT NULL
    BEGIN
        SET @SQL += ' AND headers.ORG_ID = @EntityParam';
    END;

EXECUTE SP_EXECUTESQL @SQL, N'@VendorNameParam VARCHAR(50), @EntityParam INT', 
                    @VendorNameParam = @Vendor_Name, @EntityParam = @Entity;

I assume your actual problem is more complex and you have simplified it for this, but if all your predicates are added using IF .. ELSE IF.. ELSE IF, then you don't need dynamic SQL at all, you could just use:

IF @Vendor_Name IS NOT NULL
    BEGIN
        SELECT  * 
        FROM    Table_Name
        WHERE   UPPER(vendors.VENDOR_NAME) LIKE '%' + UPPER(@Vendor_Name) + '%';
    END
ELSE IF @Entity IS NOT NULL
    BEGIN
        SELECT  * 
        FROM    Table_Name
        WHERE   headers.ORG_ID = @Entity;
    END
like image 27
GarethD Avatar answered Oct 27 '22 07:10

GarethD