【问题标题】:How to create a function which return a boolean depending on a select statement result如何创建一个根据选择语句结果返回布尔值的函数
【发布时间】:2017-04-22 22:23:02
【问题描述】:

我有一个表(Id,FK,Date1,Date2),我需要创建一个返回布尔值的函数。一般来说,我想选择与给定 FK 匹配的记录并检查一些附加语句。如果选择语句返回 0 行,我想返回 true,否则返回 false。我已经写了这段代码:

CREATE FUNCTION isAlreadyTaken(FK INT4, Date1 DATE, Date2 DATE)
  RETURNS BOOLEAN
AS $$
BEGIN
  CREATE TEMP TABLE helper ON COMMIT DROP AS SELECT COUNT(table.FK) AS quant 
    FROM table
    WHERE table.FK = FK AND table.Date2 IS NULL;
  SELECT CASE
    WHEN helper.quant > 0
    THEN FALSE
    ELSE TRUE 
  END;
END
$$ LANGUAGE plpgsql;

代码正在编译,可以执行。但是当我在 CHECK 语句中调用该函数时,它返回一个错误 [42P01]。解决方案是否接近实际可行的解决方案,还是我完全迷失了方向?

【问题讨论】:

    标签: sql postgresql function plpgsql select-case


    【解决方案1】:

    COUNT(...) > 0 WHERE ... 等价于 EXISTS(select ... where ...) ,并且 EXISTS(table expression) 已经产生一个布尔值:

    EXISTS (
     SELECT *
     FROM table t
     WHERE t.FK = FK AND t.Date2 IS NULL
     )
    

    将其放入您的查询中(注意 Date1 和 Date2 参数似乎未使用...)

    CREATE FUNCTION isAlreadyTaken1(FK INT4, Date1 DATE, Date2 DATE)
      RETURNS BOOLEAN
    AS $$
    BEGIN
      RETURN EXISTS (
        SELECT 1
        FROM table t
        WHERE t.FK = FK 
             AND t.Date2 IS NULL    -- <<-- this looks nonsensical
            );
    END
    $$ LANGUAGE plpgsql;
    

    而且,正如@a_horse_with_no_name 所评论的:您甚至不需要 plpgsql,只需简单的 SQL 即可:

    CREATE FUNCTION isAlreadyTaken1a(FK INT4, Date1 DATE, Date2 DATE)
      RETURNS BOOLEAN
    AS $func$
      SELECT EXISTS (
        SELECT 1
        FROM table t
        WHERE t.FK = FK
             AND t.Date2 IS NULL    -- <<-- this looks nonsensical
            );
    $func$ LANGUAGE sql;
    

    顺便说一句:我颠倒了逻辑。 IMO allreadyTaken 表示count() &gt; 0

    【讨论】:

    • 你甚至不需要 PL/pgSQL,一个普通的 sql 函数就可以了
    • 没错。 或者甚至可能是 while 子句中的子查询项
    • return true if the select statement returns 0 rows and false otherwise. 听起来像NOT EXISTS (...)
    • isAlreadyTaken1a() 似乎暗示了EXISTS() 我不知道 OP 的意图,但添加一个 NOT 似乎在他的能力范围内。顺便说一句:感谢您的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-12-30
    • 1970-01-01
    • 2012-04-02
    相关资源
    最近更新 更多