Oracle sql AND OR操作优先级问题

时间:2014-08-19 07:42:35

标签: sql oracle

我正在尝试编写一个查询,我在我的程序中使用AND和OR操作执行一个简单的SELECT查询..下面是查询..

问题出现在我的上一个AND块中,它没有按预期返回结果。似乎AND和OR组合在预期的优先级中不起作用。


FROM  TABLE_A
  WHERE project = p_project
  AND version = p_version
  AND logical_name= p_logical_name
  AND ((operation_name= p_operation_name) OR (((p_operation_name IS NULL OR  p_operation_name <> operation_name) AND default_operation = 'Y'))); 

如果我从我的过程调用中得到一个p_name,那么WHERE部分应该像

一样考虑
WHERE project = p_project
  AND version = p_version
   AND logical_name= p_logical_name
  AND ((operation_name= p_operation_name)

但是如果p_name与name不匹配,那么在那种情况下它应该转到下一个块,它检查p_name是否为空或p_name中是否不可用,并应检查default_operation ='Y'

WHERE project = p_project
  AND version = p_version
  AND logical_name= p_logical_name
  AND (((p_operation_name IS NULL OR  p_operation_name <> operation_name) AND default_operation = 'Y')))

但它没有按预期工作..它继续阻止并返回多个结果。

4 个答案:

答案 0 :(得分:0)

将OR添加到OR括号中没有意义。你最好提取它并简化它(KISS; - )

另一方面,你同时排除了条款

name = p_name OR p_name <> name

你应该选择你需要的那个,不能同时使用它们。

类似

FROM  TABLE_A
  WHERE project = p_project
  AND version = p_version
  AND name = p_name
  AND default_operation = 'Y'
  AND (name = p_name OR p_name IS NULL /*OR  p_name <> name*/);

答案 1 :(得分:0)

需要缩进才能理解这些我总觉得

SELECT
      *
FROM TABLE_A
WHERE project = p_project
      AND version = p_version
      AND (
            name = p_name
            OR (
                 (p_name IS NULL OR p_name <> name)
                AND
                 default_operation = 'Y'
               )
          )

答案 2 :(得分:0)

在上一个where语句中,请为NVL

尝试P_NAME

EX:

WHERE project = p_project
  AND version = p_version
  AND name = NVL(p_name, NAME)
  AND (((p_name IS NULL OR  p_name <> name) AND default_operation = 'Y')))

这是因为将null与等号进行比较将始终失败,因此如果您的P_NAME参数为null,则equal语句将返回false

答案 3 :(得分:0)

我认为以下内容适合您

WHERE project = p_project
  AND version = p_version
  AND
     (
        logical_name= p_logical_name
        OR
          (
            (SELECT COUNT(*) FROM TABLE_A WHERE logical_name = p_logical_name) = 0 
            AND ((p_operation_name IS NULL OR  p_operation_name <> operation_name) 
            AND default_operation = 'Y')
          )
     )

它做什么,它得到logical_name= p_logical_name,如果失败,它会获得谓词与另一个块匹配的记录。