Oracle在WHERE子句中使用CASE语句

时间:2017-05-16 07:18:25

标签: oracle

以下是我尝试在CASE STATEMENT条款中加入WHERE,但它不起作用。任何人都知道如何纠正这个问题?

PROCEDURE GetBatchTotals(pEntityName VARCHAR DEFAULT NULL) IS

BEGIN

  -- Sample Query
  SELECT
    e.ColumnName
  FROM
    Schema.TableName e
  WHERE
  (
    CASE
      WHEN pEntityName IS NULL THEN
        e.ColumnName != '' -- Just to select everything in the table
      ELSE
        e.ColumnName = pEntityName
    END
  );

END GetBatchTotals;

我似乎无法理解我已经发布的示例。这是另一次没有使用CASE STATEMENT但没有返回结果的尝试:

SELECT
  e.ColumnName
FROM
  Schema.TableName e
WHERE
  (pEntityName IS NULL AND e.ColumnName != '') OR
  (pEntityName IS NOT NULL AND e.ColumnName = pEntityName);

无论如何,这是真正的示例查询,它不返回任何结果: enter image description here

然后这是包含数据的表格: enter image description here 提前谢谢。

3 个答案:

答案 0 :(得分:6)

永远不要忘记在Oracle SQL中''文字(空字符串)与NULL相同,因此您的谓词e.ColumnName != ''等同于e.ColumnName != null,它总是评估为NULL

第二个问题是您正在尝试从CASE输出一个布尔值。不,Oracle不能使用布尔表达式作为函数的结果。 (我们认为CASE是一个函数,因为我现在不记得这些语言结构的更合适的名称。)

以这种方式尝试:

PROCEDURE GetBatchTotals(pEntityName VARCHAR DEFAULT NULL) IS
BEGIN
  -- Sample Query
  SELECT ColumnName
  FROM TableName e
  WHERE
    (pEntityName IS NULL AND e.ColumnName is not null) OR
    (pEntityName IS NOT NULL AND e.ColumnName = pEntityName);
END GetBatchTotals;

您的代码还有一些问题,让我们修复它们:

(1) 请勿使用varchar,而是使用varchar2。一个奇怪的"增强"甲骨文,不要问。

(2) 对于具有非NULL值的等式谓词,您可以从其中一个pEntityName is not null - s中取消谓词AND,这将隐含。

(3) 谓词e.ColumnName is not null实际上会滤除e.ColumnNameNULL的行,这与您最初的想法不同,无论其e.ColumnName值是什么,都会查询所有行。

(4) 循环查询结果或批量获取它们到集合或将它们作为引用游标返回。在PL / SQL中,您必须将查询结果放入某个内容中!让我们遍历查询结果并将ColumnName内容假脱机到服务器输出...

PROCEDURE GetBatchTotals(pEntityName VARCHAR2 DEFAULT NULL) IS
BEGIN
  for rec in (
    SELECT ColumnName
    FROM TableName e
    WHERE pEntityName IS NULL -- Just to select everything in the table
      OR e.ColumnName = pEntityName
  ) loop
    dbms_output.put_line(rec.ColumnName);
  end loop;
END GetBatchTotals;

答案 1 :(得分:4)

我喜欢nop77svk的答案,但是,他从未真正澄清CASE的问题(即如何正确地使用CASE编写逻辑)。 因此,为了完整起见,以下是使用CASE处理该逻辑的方法。

  PROCEDURE GetBatchTotals(pEntityName VARCHAR2 DEFAULT NULL) IS

  BEGIN

    -- Sample Query
    SELECT
      e.ColumnName
    FROM
      Schema.TableName e
    WHERE
     1 = CASE
           WHEN pEntityName IS NULL AND e.ColumnName IS NOT NULL
              THEN 1
           WHEN e.ColumName = pEntityName 
              THEN 1
              ELSE 0
         END
    );

  END GetBatchTotals;

在这种特殊情况下,nop77svk解决方案可能是稍微更简单/更清晰的代码:)

答案 2 :(得分:-2)

在您的sql工作表中使用您的元数据尝试此结构:

declare
  l_object_name varchar2(20) := null;-- your objects name
begin

  for l_rec in (
    select
      e.object_name
    from
      all_objects e
    where
      (l_object_name is null and 
      1=1) or
      (l_object_name is not null and 
      e.object_name = l_object_name))
  loop
    dbms_output.put_line('Object found: '||l_rec.object_name);
  end loop;
end;

测试它。