IF NOT EXISTS 在 RETURN QUERY 语句中

Posted

技术标签:

【中文标题】IF NOT EXISTS 在 RETURN QUERY 语句中【英文标题】:IF NOT EXISTS within a RETURN QUERY statement 【发布时间】:2021-03-16 13:35:38 【问题描述】:

我有一个 PostgreSQL 函数,它接收一个字符串列表,在 Word 表中匹配这些字符串并相应地返回它们。 Word 是一个表,由一个字符串 word 作为主 ID 和该字符串的属性特征组成。

这是函数的工作版本。

CREATE OR REPLACE FUNCTION equals_words(words Text[]) RETURNS SETOF "Word" AS $BODY$
DECLARE
  w Text;
BEGIN
  FOREACH w IN ARRAY $1
  LOOP
    RETURN QUERY SELECT * FROM "Word" WHERE word = w
  END LOOP;
  RETURN;
END; $BODY$ LANGUAGE plpgsql STABLE STRICT;

我希望循环中的语句检查查询是否没有返回任何内容,如果是,则调用另一个函数 longest_prefix(w TEXT) 尝试将 w 与其最长前缀匹配。这是我目前所拥有的。

CREATE OR REPLACE FUNCTION equals_words(words Text[]) RETURNS SETOF "Word" AS $BODY$
DECLARE
  w Text;
BEGIN
  FOREACH w IN ARRAY $1
  LOOP
    RETURN QUERY 
        IF NOT EXISTS(SELECT * FROM "Word" WHERE word = w)
        BEGIN
        SELECT * FROM longest_prefix(w); 
        END
  END LOOP;
  RETURN;
END; $BODY$ LANGUAGE plpgsql STABLE STRICT;

这不起作用,给我以下错误:

ERROR:  syntax error at or near "IF"
LINE 8:   IF NOT EXISTS(SELECT * FROM "Word" WHERE word = w)

我怀疑 NOT EXISTS 不能在 RETURN QUERY 语句中使用,但我不太确定。如果是这样,有人可以提出替代方案吗?

【问题讨论】:

无需遍历数组即可开始 【参考方案1】:

您可以使用 CTE 和 UNION ALL 将所有内容放在一个查询中:

WITH cte AS (
      SELECT *
      FROM "Word" w
      WHERE w.word = w
     )
SELECT cte.*
FROM cte
UNION ALL
SELECT *
FROM longest_prefix(w)
WHERE NOT EXISTS (SELECT 1 FROM cte);

【讨论】:

【参考方案2】:

IF 语句不允许在 SQL 中使用。但是你当然可以在 PL/pgSQL 中使用IF 在不同的分支中执行不同的查询。

...
IF NOT EXISTS (SELECT * FROM "Word" WHERE word = w) THEN
  RETURN QUERY SELECT * FROM longest_prefix(w);
ELSE
  RETURN QUERY SELECT * FROM "Word" WHERE word = w;
END IF;
...

【讨论】:

感谢您的回答。在可以找到完全匹配的情况下,这是否会执行两次SELECT * FROM "Word" WHERE word = w @drew181:嗯,我不知道 PL/pgSQL 的优化效果如何(如果有的话)(很可能并非如此)。但是由于EXISTS 的子查询不需要也不会获取所有结果,所以一行就足以知道,我认为这两种方式都没有太多的开销。

以上是关于IF NOT EXISTS 在 RETURN QUERY 语句中的主要内容,如果未能解决你的问题,请参考以下文章

错题记录

对于互斥条件,多个“if”语句和“if-else-if”语句是不是相同?

if-if 和 if-elif 是不是定义为链式条件?

html 基本IF,IF - ELSE和IF - ELSE IF - ELSE语句。

shell if else if

java,if else和if else if else区别?