【问题标题】:Oracle - using is not null inside Case when.... then.... inside WhereOracle - 在 Case when.... then.... 里面 using is not null
【发布时间】:2018-07-24 03:36:40
【问题描述】:

我又来问了 我对 Oracle 感到困惑,似乎当我在函数的情况下使用为 null 时,它不起作用,我的代码是这样的: 它出了问题 "CASE WHEN :idSalesman is not null then enabled = null and deleted=0 else enabled =1 and deleted =0"条件

SELECT a.id_outlet as idOutlet , a.name , a.plant as plant, a.segment, a.street1 as alamat, a.nota_retur  
 FROM (SELECT id_outlet, name, plant, segment, street1, nota_retur FROM outlet WHERE plant = :idPlant  
 AND (id_outlet || ' ' || name || ' ' || street1) like :request  
 AND enabled = 1 AND deleted = 0 and rownum = :limits ) a  
 INNER JOIN wilayah_kerja b ON b.id_salesman = nvl(:idSalesman, b.id_salesman) AND  b.id_outlet = a.id_outlet 
 AND b.enabled = 1 AND b.deleted = 0  
 GROUP BY a.id_outlet  
 UNION  
 SELECT
    A.Id_Outlet AS Idoutlet,A.Name,A.Plant AS Plant,A.Segment,A.Street1 AS Alamat,A.Nota_Retur
FROM ( SELECT Id_Outlet,Name,Plant,Segment,Street1,Nota_Retur 
        FROM Outlet
    WHERE Plant =:Idplant 
    AND (CASE WHEN :idSalesman is not null then enabled = null and deleted=0 else enabled =1 and deleted =0 )
    AND rownum >=:limits 
    AND (Id_Outlet || ' ' || Name || ' ' || Street1) LIKE :Request
    )a
 LEFT JOIN wilayah_kerja b ON b.id_outlet = a.id_outlet 
 and rownum = :limits
 AND b.enabled = 1 
 AND b.deleted = 0  
 WHERE B.Id_Outlet Is NULL Group By A.Id_Outlet Order By Name Limit 10;

我试图将联合更改为:

 SELECT a.id_outlet as idOutlet , a.name , a.plant as plant, a.segment, a.street1 as alamat, a.nota_retur  
 FROM (SELECT id_outlet, name, plant, segment, street1, nota_retur FROM outlet WHERE plant = :idPlant  
 AND (id_outlet || ' ' ||  name || ' ' || street1 ) like :request  
 AND rownum = :limits
 AND enabled = 1 AND deleted = 0 AND NVL(:idSalesman , enabled = null AND deleted = 0))a  
 LEFT JOIN wilayah_kerja b ON b.id_outlet = a.id_outlet AND b.enabled = 1 AND b.deleted = 0  
 WHERE B.Id_Outlet Is NULL Group By A.Id_Outlet Order By Name Limit 10

使用 NVL2 ,但它在“a”附近给我错误

NVL(:idSalesman , enabled = null AND deleted = 0))a  

【问题讨论】:

  • 让我们简化一下。你认为case when :param is not null then id = 300 是什么意思? (即:你想要它是什么意思?)在 SQL 中是 100% 错误的。 CASE 表达式的 THEN 部分必须是 expression(返回值的东西)——而不是布尔条件。那么-您尝试使用该代码实现什么目标?您尝试使用NVL(或NVL2,尚不清楚)修复它遇到了完全相同的问题;由于同样的原因它失败了。
  • CMIIW,但后来我把 {case when :idSalesman is null } 我希望表达式在启用的列上分配 null 并在已删除的列上分配 0,我认为表达式没有错
  • 如果您想有条件地将值分配给两个不同的列,您必须为每个列使用不同的CASE 表达式(即使WHEN 部分相同)。 CASE 表达式是一个表达式,它不是一个语句。 (CASE 语句确实存在 - 在 PL/SQL 中,而不是在 SQL 中)。您不能在 SQL 中同时“分配”两个不同的列。无论如何,分配不会在WHERE 子句中完成。
  • 这是否意味着我需要将查询移至程序?
  • 将这种情况更改为 CASE WHEN :idSalesman 不为空且启用为空且已删除=0 然后 1 WHEN :idSalesman 为空且已启用 =1 且已删除 =0 然后 1 else 0 end = 1

标签: sql oracle plsql oracle11g


【解决方案1】:

Oracle 不支持在 SQL 语句中使用单独的布尔类型。一个问题(至少)是:

WHERE Plant = :Idplant AND
      (CASE WHEN :idSalesman is not null then enabled = null and deleted = 0 else enabled = 1 and deleted = 0 ) AND
      rownum >= :limits AND
      . . .

解决方案就是将其表述为布尔逻辑:

WHERE Plant = :Idplant AND
      deleted = 0 AND
      (:idSalesman is not null and enabled is null OR 
       :idSalesman is null and enabled = 1
      ) AND
      rownum >= :limits AND
      . . .

另请注意,= null 不是有效的比较(除非您永远不希望某些东西评估为真)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 2011-06-07
    • 2013-10-20
    • 1970-01-01
    相关资源
    最近更新 更多