How to deal with (maybe) null values in a PreparedStatement?

后端 未结 5 1905
不知归路
不知归路 2020-12-12 20:36

The statement is

SELECT * FROM tableA WHERE x = ?

and the parameter is inserted via java.sql.PreparedStatement \'stmt\'

stm         


        
相关标签:
5条回答
  • 2020-12-12 21:09

    would just use 2 different statements:

    Statement 1:

    SELECT * FROM tableA WHERE x is NULL
    

    Statement 2:

    SELECT * FROM tableA WHERE x = ?
    

    You can check your variable and build the proper statement depending on the condition. I think this makes the code much clearer and easier to understand.

    EDIT By the way, why not use stored procedures? Then you can handle all this NULL logic in the SP and you can simplify things on the front end call.

    0 讨论(0)
  • 2020-12-12 21:10

    There is a quite unknown ANSI-SQL operator IS DISTINCT FROM that handles NULL values. It can be used like that:

    SELECT * FROM tableA WHERE x NOT IS DISTINCT FROM ?
    

    So only one parameter has to be set. Unfortunately, this is not supported by MS SQL Server (2008).

    Another solution could be, if there is a value that is and will be never used ('XXX'):

    SELECT * FROM tableA WHERE COALESCE(x, 'XXX') = COALESCE(?, 'XXX')
    
    0 讨论(0)
  • 2020-12-12 21:15

    In Oracle 11g, I do it this way because x = null technically evaluates to UNKNOWN:

    WHERE (x IS NULL AND ? IS NULL)
        OR NOT LNNVL(x = ?)
    

    The expression before the OR takes care of equating NULL with NULL, then the expression after takes care of all other possibilities. LNNVL changes UNKNOWN to TRUE, TRUE to FALSE and FALSE to TRUE, which is the exact opposite of what we want, hence the NOT.

    The accepted solution didn't work for me in Oracle in some cases, when it was part of a larger expression, involving a NOT.

    0 讨论(0)
  • 2020-12-12 21:21

    I've always done it the way you show in your question. Setting the same parameter twice is not such a huge hardship, is it?

    SELECT * FROM tableA WHERE x = ? OR (x IS NULL AND ? IS NULL);
    
    0 讨论(0)
  • 2020-12-12 21:24

    If you use for instance mysql you could probably do something like:

    select * from mytable where ifnull(mycolumn,'') = ?;
    

    Then yo could do:

    stmt.setString(1, foo == null ? "" : foo);
    

    You would have to check your explain plan to see if it improves your performance. It though would mean that the empty string is equal to null, so it is not granted it would fit your needs.

    0 讨论(0)
提交回复
热议问题