像'%'一样使用,并将 NULL 值与 NUMBER 列匹配



这个问题几乎和我的问题一模一样,但没有一个答案适用于我的情况。

如果这是我的问题,我会稍微编辑一下,让它成为一个不同的问题。因此,这个问题与链接的问题不同。

问题是:我想要一种方法来匹配任何非空值('%'(和空值。

问题是:

  • 我正在使用预言机,所以我不能使用IsNull

  • 有些列是NUMBERs,这意味着我不能使用COALESCE(column, ' ').(ORA-00932:数据类型不一致:预期的编号得到字符(。但是,like '%'like '2118'确实适用于 NUMBER 列。

没有任何答案适用于此问题,因为当列为 NUMBER 时,您无法将 null 转换为空字符串。

我该怎么做才能实现这一目标?


一些背景:

我的程序需要很多参数,并对所有这些参数进行选择。它们都可以有一个值或为 null,因此如果它们为 null,则替换为'%'

这样,该过程将执行以下操作:

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

大多数情况下,只有一个或两个参数不为 null。对于其他参数,该过程需要在每一行上匹配。

但是,当值为 null 时,like '%'与行不匹配。我正在寻找一种在参数 x 为空时匹配任何内容的方法(所以paramx = '%'

(

我的程序需要很多参数,并对所有这些参数进行选择。它们都可以有一个值或为 null,因此如果它们为 null,则替换为"%"。

这似乎让你的生活变得艰难。将它们保留为空,然后执行以下操作:

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

如果param1(过程参数;当您的参数/变量名称和列名不同时,生活会更简单...所以我更改了列名以使其更清晰(为 null,它基本上被忽略*,并且所有行都通过过滤器的该部分,无论列值是否为 null。如果param2不为null,则is null检查失败,只有具有与值匹配的(非 null(列值param2行才能满足筛选器的该部分。

*or中的条件可以按任何顺序进行评估;将is null检查放在首位并不一定意味着不会评估like- 但优化器在这种事情上非常聪明

如果要匹配特定值和NULL,可以使用OR

where col = <specific value> or col is null

在 Oracle 中可以使用 NVL 代替 ISNULL

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

Oracle 会自动将NUMBER转换为类似条件的VARCHAR2。所以你要做的是自己做,这样你就可以使用合并:

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

基于ORNVL/COALESCE的其他答案的建议是"优雅"和简单的,但通常它们会抑制索引访问,这是最重要的事情。

您可以逐步使用动态 SQL来解决可选参数问题 - 这是您的情况。如果未传递参数(为 NULL( - 只需忽略它。

例如,对于两个参数,如果两个参数都传递,则生成以下 SQL

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

如果只给出参数 1,则生成此 SQL:

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

没有参数,您将以

select * from tab t

从技术上讲,最好在所有 SQL 语句中具有相同数量的绑定变量,而上述建议并非如此。有关 Tom Kyte 推广的保留带有可选参数的绑定变量数量的技巧的详细说明,请参阅此答案。

例如,只有参数 1的第二条语句将产生以下 SQL

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

1=1的快捷方式 logik(即 TRUE(消除了谓词的第二部分,但仍使用绑定变量,因此绑定变量的数量保持不变。

最大的优势是此查询的精细索引范围访问

最新更新