Pl/pgSQL 匿名代码块在 [42601] 错误上失败:查询没有结果数据的目的地

Posted

技术标签:

【中文标题】Pl/pgSQL 匿名代码块在 [42601] 错误上失败:查询没有结果数据的目的地【英文标题】:Pl/pgSQL anonymous code block fails on [42601] ERROR: query has no destination for result data 【发布时间】:2021-06-20 11:38:39 【问题描述】:

假设我在应用程序启动时导入的sql 脚本中的简化DO 匿名代码块:

-- table definitions omitted
-- assume I want to use anonymous code because of looping

DO
$$
DECLARE
    parentId BIGINT;
    inputArray VARCHAR[][] := ARRAY [['a', 'A'], ['b', 'B'], ['c', 'C']];
    input VARCHAR[];
BEGIN
    FOREACH input SLICE 1 IN ARRAY inputArray
    LOOP
        INSERT INTO myParent (name) VALUES (input[1]) RETURNING id AS parentId;
        INSERT INTO myTable (id, name) VALUES (parentId, input[2]);
    END LOOP;
END;
$$ LANGUAGE plpgsql;

在导入和执行脚本时,由于以下错误而失败:

[42601] ERROR: query has no destination for result data 
Where: PL/pgSQL function inline_code_block line 13 at SQL statement

我在https://www.postgresql.org/docs/current/sql-do.html 阅读了 PostgreSQL DO 语句文档,它说:

DO 执行一个匿名代码块,或者换句话说,一个过程语言中的瞬态匿名函数。

代码块被视为没有参数的函数体,返回 void。它被解析并执行一次。

我希望DO 匿名代码中的INSERT 语句能够毫不费力地继续执行。如前所述,它是一个没有参数并返回 void 的函数。为什么它是预期的结果数据和存储它们的东西?

【问题讨论】:

【参考方案1】:

我发现RETURNING 会导致问题并混淆整个块的返回类型。 AS 应替换为 INTO,然后该块开始完美运行。

错误:
INSERT INTO myParent (name) VALUES (input[1]) RETURNING id AS parentId;
正确:
INSERT INTO myParent (name) VALUES (input[1]) RETURNING id INTO parentId;

【讨论】:

以上是关于Pl/pgSQL 匿名代码块在 [42601] 错误上失败:查询没有结果数据的目的地的主要内容,如果未能解决你的问题,请参考以下文章

在 PL/pgSQL 匿名块中引用 psql 参数

如何在 C# 中从 Npgsql 4.1.5.0 执行匿名块 PL/pgSQL (PostgreSQL 13)

Postgres PL/pgSQL,可以声明匿名自定义类型吗?

是否可以在 Spring Data JPA Repository 的 @Query 注释中使用 PostgreSQL 匿名块(PL/pgSQL)?

如何从 C++ 代码调用 PL/pgSQL 函数

PL/pgSQL 代码的问题