RETURN QUERY 语句中的 IF NOT EXISTS

IF NOT EXISTS within a RETURN QUERY statement

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

这是函数的工作版本。

CREATE OR REPLACE FUNCTION equals_words(words Text[]) RETURNS SETOF "Word" AS $BODY$
DECLARE
  w Text;
BEGIN
  FOREACH w IN ARRAY 
  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 
  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 语句中使用,但我不太确定。如果可以,有人可以建议替代方案吗?

您可以使用 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);

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;
...