[英]PostgreSQL EXISTS in user-defined function always returning true
我写了一个简单的用户定义的 function 来检查是否存在匹配某些条件的行:
CREATE OR REPLACE FUNCTION is_instructor_specialized_in(eid INT, course_area VARCHAR(50))
RETURNS BOOLEAN AS $$
SELECT EXISTS(SELECT 1 FROM Specializes s WHERE s.eid = eid AND s.name = course_area);
$$ LANGUAGE sql;
我使用以下查询对其进行了测试:
SELECT is_instructor_specialized_in(2, 'Artificial Intelligence') as function_output,
EXISTS(SELECT 1 FROM Specializes s WHERE s.eid = 2 AND s.name = 'Artificial Intelligence') as ground_truth;
并且 function 在应该评估为false
时给出了错误的true
值( Specializes
表中没有这样的行):图片
事实上,它总是给出true
的值。 我超级困惑。 发生这种情况有什么原因吗?
版本:x86_64-apple-darwin19.6.0 上的 PostgreSQL 13.2,Apple 编译 clang 版本 11.0.3 (clang-1103.0.32.62),64 位
就像@wildplasser 暗示的那样,您的 function 参数eid
与表列同名,这绝不是一个好主意。 在这种情况下,它默默地破坏了您的 function。
WHERE s.eid = eid
中的不合格eid
解析为表列,而不是 function 参数,就像您所期望的那样。 因此,对于任何非空输入,此谓词的计算结果为true
。 偷偷摸摸的错误。
如果参数名称与 function 中的当前 SQL 命令中的任何列名称相同,则列名称将优先。 要覆盖它,请使用 function 本身的名称限定参数名称,即
function_name.argument_name
。 (如果这会与限定的列名冲突,则列名再次获胜。您可以通过在 SQL 命令中为表选择不同的别名来避免歧义。)
大胆强调我的。
使用 function 名称进行资格认证是不得已而为之的尴尬措施。 避免以明确的参数名称开头的问题。 一种约定是使用下划线 ( _
) 为参数添加前缀 - 并且永远不要对表列做同样的事情:
CREATE OR REPLACE FUNCTION func_proper(_eid int, _course_area text)
RETURNS boolean
LANGUAGE sql STABLE PARALLEL SAFE AS
$func$
SELECT EXISTS(SELECT FROM specializes s WHERE s.eid = _eid AND s.name = _course_area);
$func$;
或者对像你这样的简单案例使用位置$n
参数引用。 您仍然可以为文档和命名的 function 调用提供参数名称:
CREATE OR REPLACE FUNCTION func_proper(_eid int, _course_area text)
RETURNS boolean
LANGUAGE sql STABLE PARALLEL SAFE AS
$func$
SELECT EXISTS(SELECT FROM specializes s WHERE s.eid = $1 AND s.name = $2);
$func$;
db<> 在这里摆弄
PL/pgSQL function 中相同命名冲突的默认行为是引发异常,顺便说一句。 看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.