简体   繁体   中英

SQL If parameter is null search all

I have a JSF page where users can search by five options, and can choose how many of those options they search by (0-5). The database has no NULL values.

Currently I have a horrendous piece of code that builds that SQL statement, but I would like to just have one parameterized statement.

  SELECT * 
    FROM table1 
   WHERE col1 = 'dave' 
     AND col2 = 'Smith' 
     AND col3 = '3/2/2014' 
     AND col4 = '12345' 
     AND col5 = '67890' 
ORDER BY col5 DESC

Is there a way to detect an empty/null value in the search criteria eg col5='' And just return all results for that column?

So that if the search criteria was just col1='dave' then the statment would act as if the input was

  SELECT * 
    FROM table1 
   WHERE col1 = 'dave' 
ORDER BY col5 DESC

You can do this in SQL:

SELECT * 
FROM table1 
WHERE (col1 = @col1 or @col1 is null) and
      (col2 = @col2 or @col2 is null) and
      . . .
ORDER BY col5 DESC;

But, you may not want to. If you are using indexes to speed your searches, then the use of or can impede the use of the indexes in many databases (but apparently not in Oracle). This is also true of coalesce() , which could be used as:

WHERE col1 = coalesce(@col1, col1) and
      col2 = coalesce(@col2, col2) and
      . . .

If you are constructing the query anyway, then do it in the statement. The logic is like:

if @col1 is not null then
    @where = concat(@where, " and col1 = '", @col1, "'")
end if;
if @col2 is not null then
    @where = concat(@where, " and col2 = '", @col2, "'")
end if;

This will construct the correct where clause that can use available indexes.

There is one downside to this approach. You cannot pre-compile the statement for all parameter values. The statement would need to be recreated every time new values are input (this would normally be an acceptable amount of overhead because you are dealing with user input).

Try to use trim to change empty value '' to null and then use coalesce to replace null with value from col5 as below

SELECT * 
FROM table1 
WHERE col1 = 'dave' 
AND col2 = 'Smith' 
AND col3 = '3/2/2014' 
AND col4 = '12345' 
AND col5 = coalesce(trim('67890'),col5)
ORDER BY col5 DESC
SELECT * 
    FROM table1 
    WHERE (col1 = :col1 OR :col1 IS NULL)
    AND (col2 = :col2 OR :col2 IS NULL)
    AND (col3 = :col3 OR :col3 IS NULL)
    AND (col4 = :col4 OR :col4 IS NULL)
    AND (col5 = :col5 OR :col5 IS NULL)
    ORDER BY col5 DESC

It is more convenient to use named parameter instead of "?" in JAVA

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM