Oracle或运营商无法运行

时间:2018-02-17 13:34:19

标签: oracle

我正在尝试搜索记录中有一个匹配或更多形式的查询中的已发送值我有此表

+----+------+
| ID | NAME |
+----+------+
|  1 | Joe  |
|  2 | noe  |
+----+------+

这是我正在使用的查询

SELECT
*
FROM
members
WHERE
(
    UPPER( NAME ) LIKE(
        '%' || UPPER(:NAME )|| '%'
    )
    OR :NAME IS NULL
)
AND(
    ID = :ID
    OR :ID IS NULL
)

如果我将'NAME替换为'joe'而且:ID替换为'0'则不会返回任何记录,而我需要获取第一行

如果我用''替换:NAME,用'1'替换:ID,则返回第1行

什么是正确的查询或者什么是正确的替换?

2 个答案:

答案 0 :(得分:1)

您的查询有两个过滤器和一个布尔AND运算符。这意味着当有一个匹配两个条件的记录时,它会返回一条记录。

您的第一对参数不匹配任何记录,因为(因为@jurgend指出)0不是空的,因此0 is null为false。第二对返回一条记录,因为您传递的是null(Oracle将空字符串视为null,从而捕获新的数据)。所以它匹配ID = 1上的第二条记录。

如果你想匹配:NAME,你需要传递null:ID。

如果你需要根据任一参数匹配记录,那么你可能需要像这样重写你的查询:

SELECT
*
FROM
members
WHERE
(
    :NAME IS NOT NULL
    AND   
    UPPER( NAME ) LIKE
        '%' || UPPER(:NAME )|| '%'
)
OR
(
    :ID IS NOT NULL
    AND ID = :ID
)

答案 1 :(得分:0)

这个非常聪明,但也许可能会有所帮助。我们的想法是"替代" (使用NVL函数)缺少值,表中不存在某些东西。对于ID,我选择" -1"和" x"对于NAME。

SQL> with test (id, name) as
  2  (select 1, 'joe' from dual union
  3   select 2, 'noe' from dual
  4  )
  5  select *
  6  from test
  7  where nvl(id, -1) = nvl(&id, -1)
  8     or nvl(name, 'x') = nvl('&name', 'x');
Enter value for id: 1
Enter value for name:

        ID NAM
---------- ---
         1 joe

SQL> /
Enter value for id: ''
Enter value for name: noe

        ID NAM
---------- ---
         2 noe

SQL> /
Enter value for id: 1
Enter value for name: noe

        ID NAM
---------- ---
         1 joe
         2 noe

SQL> /
Enter value for id: 0
Enter value for name: joe

        ID NAM
---------- ---
         1 joe

SQL>