Use like '%' and match NULL values with NUMBER columns

感情迁移 提交于 2021-01-28 07:09:45

问题


This question is almost exactly like mine but none of the answers work with my case.

If it was my question I'd slightly edit it to make it a different question. This question is thus different from the linked one.

Here's the problem: I want a way to match any non-null value ('%') AND null values.

The thing is:

  • I'm using oracle so I can't use IsNull

  • Some columns are NUMBERs, which means I can't use COALESCE(column, ' '). (ORA-00932: inconsistent datatypes: expected NUMBER got CHAR). However, like '%' and like '2118' do work on NUMBER columns.

None of the answers apply to this problem because you can't make a null into an empty string when the column is a NUMBER.

How could I do to achieve this?


Some context:

My procedure takes a lot of parameters, and does a select with all of them. They can all have a value or be null, so if they're null they're replaced with '%'.

That way, the procedure does :

where t.col1 like param1
and t.col2 like param2
...

Most of the times, only one or two parameters is not null. For the others parameters, the procedure needs to match on every row.

But when the value is null, like '%' doesn't match the row. I'm looking for a way to match anything when param x is empty (so paramx = '%')


回答1:


My procedure takes a lot of parameters, and does a select with all of them. They can all have a value or be null, so if they're null they're replaced with '%'.

That seems like you're making life hard for yourself. Leave them null, then do:

where (param1 is null or t.col1 like param1)
and (param2 is null or t.col2 like param2)

If param1 (the procedure argument; life is simpler when your parameter/variable names and column names are different... so I've changed the column names to make it a bit clearer) is null it is basically ignored* and all rows pass that part of the filter, whether the column value is null or not null. If param2 is not null then the is null check for that fails and only rows with (not-null) column values that match param2 value meet that part of the filter.

* Conditions in an or can be evaluated in any order; putting the is null check first doesn't necessarily mean the like won't be evaluated - but the optimiser is pretty smart about that sort of thing




回答2:


If you want to match a specific value and NULL, you can use OR:

where col = <specific value> or col is null



回答3:


In Oracle NVL can be used instead of ISNULL

IF NVL(aNumberColumn,-1) = -1 THEN
    ---whatever
END IF;



回答4:


Oracle automatically converts NUMBER to VARCHAR2 for like-conditions. So what you have todo is do that yourself so you can use coalesce:

COALESCE(TO_CHAR(column), ' ') like '%'



回答5:


The proposals from other answers based on OR or NVL/ COALESCE are "elegant" and simple, but as a rule they inhibit the index access, which is the most important thing.

You may step down to use dynamic SQL to address the optional parameter problem - which is your case. If a parameter is not passed (it is NULL) - simple ignore it.

So for example with two parameters, if both parameters are passed, generate following SQL

select * from tab t
where t.col1 like :param1
and t.col2 like :param2

If only parameter 1 is given, generate this SQL:

select * from tab t
where t.col1 like :param1

With no parameter you will end with

select * from tab t

Technically it is preferable to have in all SQL statements the same number of bind variables, which is not the case in the above proposal. See this answer for detailed explanation of the trick popularized by Tom Kyte to preserve the number of bind variable with optional parameters.

For example the second statement with only parameter 1 would yield following SQL

select * from tab t
where t.col1 like :param1
and (1=1 or t.col2 like :param2)

The shortcut logik of 1=1(which is TRUE) eliminates the second part of the predicate, but the bind variable is still used, so the number of the bind variables remains constant.

The big advantage is a fine index range access of this query



来源:https://stackoverflow.com/questions/57890930/use-like-and-match-null-values-with-number-columns

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!