【问题标题】:Oracle PL/SQL seems to ignore WHERE clause of my FunctionOracle PL/SQL 似乎忽略了我的函数的 WHERE 子句
【发布时间】:2021-05-19 17:49:46
【问题描述】:

我有一张俱乐部成员表,其中有一列状态,我想在下面的函数中用作过滤器。但无论我作为函数参数传递什么数字,结果总是相同的。计数总是伴随着整个表的寄存器总数。

CREATE OR REPLACE FUNCTION fn_count_members
(id_status in club.members.id_status%TYPE)
RETURN NUMBER IS
total club.members.id%TYPE:=0;
BEGIN
    SELECT COUNT(id) INTO total 
    FROM club.members m
    WHERE m.id_status = id_status; 
    RETURN total; 
END;

还有查询:

select id_status, fn_count_members(1) as total from club.members;

我在这里缺少什么? 谢谢。

【问题讨论】:

  • fn_count_members(1) != fn_count_members(id_status) 。例如,只需将固定值1 转换为id_status
  • Littlefoot 为您提供了答案以及解决方法。要理解这个问题,您需要熟悉“名称解析”——如果同一个名称用于多个“事物”会发生什么。在您的where 子句中,一个id_status 是合格的(由m),因此不会造成混淆。另一个没有资格。在查询中,第一个选择是“表中的列”。有这样一列,所以 that 就是要使用的。它不会是传递给函数的参数。然后 - 还有其他修复(除了 Littlefoot 展示的),但这是最好的选择。

标签: oracle plsql oracle18c


【解决方案1】:

你有两个问题:

CREATE OR REPLACE FUNCTION fn_count_members(
  p_id_status in club.members.id_status%TYPE  -- change the parameter name to
                                              -- something different from the
                                              -- column name.
)
RETURN NUMBER IS
total club.members.id%TYPE:=0;
BEGIN
    SELECT COUNT(id) INTO total 
    FROM club.members m
    WHERE m.id_status = p_id_status;          -- and here
    RETURN total; 
END;
/

那你需要传入参数而不是使用1

select id_status,
       fn_count_members(id_status) as total
from   club.members;

db小提琴here

【讨论】:

  • 非常感谢!
【解决方案2】:

这是错误的:

(id_status in club.members.id_status%TYPE)
 ---------
 this

因为,在where子句中使用时

WHERE m.id_status = id_status

结果类似于where 1 = 1 并返回所有内容,根本没有过滤。

重命名参数为例如

(par_id_status in club.members.id_status%TYPE)

并将其用作

WHERE m.id_status = par_id_status

【讨论】:

  • 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多