How should I deal with null parameters in a PL/SQL stored procedure when I want to use them in comparisons?

前端 未结 6 1009
孤独总比滥情好
孤独总比滥情好 2021-01-05 14:31

I have a stored procedure with a parameter name which I want to use in a where clause to match the value of a column i.e. something like

         


        
相关标签:
6条回答
  • 2021-01-05 14:52

    You can use decode function in the following fashion:

    where decode(col1, name, 0) is not null
    

    Cite from SQL reference:

    In a DECODE function, Oracle considers two nulls to be equivalent.

    0 讨论(0)
  • 2021-01-05 14:52
    SELECT * FROM table
    WHERE paramater IS NULL OR column = parameter;
    
    0 讨论(0)
  • 2021-01-05 15:02

    Keep it the way you have it. It's more intuitive, less buggy, works in any database, and is faster. The concise way is not always the best. See (PLSQL) What is the simplest expression to test for a changed value in an Oracle on-update trigger?

    0 讨论(0)
  • I think your own suggestion is the best way to do it.

    0 讨论(0)
  • 2021-01-05 15:12

    If col1 is indexed, it would be best (performance-wise) to split the query in two:

    SELECT  *
    FROM    mytable
    WHERE   col1 = name
    UNION ALL
    SELECT  *
    FROM    mytable
    WHERE   name IS NULL AND col1 IS NULL
    

    This way, Oracle can optimize both queries independently, so the first or second part won't be actually executed depending on the name passed being NULL or not.

    Oracle, though, does not index NULL values of fields, so searching for a NULL value will always result in a full table scan.

    If your table is large, holds few NULL values and you search for them frequently, you can create a function-based index:

    CREATE INDEX ix_mytable_col1__null ON mytable (CASE WHEN col1 IS NULL THEN 1 END)
    

    and use it in a query:

    SELECT  *
    FROM    mytable
    WHERE   col1 = name 
    UNION ALL
    SELECT  *
    FROM    mytable
    WHERE   CASE WHEN col1 IS NULL THEN 1 END = CASE WHEN name IS NULL THEN 1 END
    
    0 讨论(0)
  • 2021-01-05 15:15

    What you have done is correct. There is a more concise way, but it isn't really better:

    where nvl(col1,'xx') = nvl(name,'xx')
    

    The trouble is, you have to make sure that the value you use for nulls ('xx' is my example) couldn't actually be a real value in the data.

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