【问题标题】:Temp table inside a Procedure in PostgresPostgres过程中的临时表
【发布时间】:2021-11-04 14:40:11
【问题描述】:

我正在尝试在过程中创建和填充临时表,以保存我正在处理的数据的一些中间状态。

我创建了一个示例代码来解释我想要做什么:

CREATE OR REPLACE PROCEDURE etl.my_test_procedure()
LANGUAGE sql
AS 
$$
   CREATE TEMP TABLE IF NOT EXISTS my_temp(
       var1 VARCHAR(255),
       var2 VARCHAR(255)
   ) ON COMMIT DROP;
    
   INSERT INTO my_temp (
       var1,
       var2
   )
   SELECT 
       table_schema,
       column_name
   FROM information_schema.columns;

   SELECT 
        *
   FROM my_temp
$$

当试图创建这个存储过程时,数据库返回这个错误信息: 错误:关系“my_temp”不存在 第 10 行:插入 my_temp ( ^ SQL 状态:42P01 人物:171

PD:我的 Postgres 版本是 13.3

【问题讨论】:

  • 临时表完全没用。只返回选择的结果

标签: postgresql stored-procedures temp-tables postgresql-13


【解决方案1】:

您必须使用plpgsql 而不是sql

CREATE OR REPLACE FUNCTION my_test_procedure()
RETURNS TABLE(var1 VARCHAR(255), var2 VARCHAR(255))
AS 
$$
 DECLARE

  BEGIN

   CREATE TEMP TABLE IF NOT EXISTS my_temp(
       var1 VARCHAR(255),
       var2 VARCHAR(255)
   ) ON COMMIT DROP;
    
   INSERT INTO my_temp (
       var1,
       var2
   )
   SELECT 
       table_schema,
       column_name
   FROM information_schema.columns;

   RETURN QUERY SELECT *
   FROM my_temp;

  END;
$$ LANGUAGE plpgsql;

【讨论】:

  • 非常感谢!只是一点点跟进。我实际上对将该表作为过程(函数?)的输出并不感兴趣,但它将用作输入以获取另一个中间结果,直到在行尾,一些行将被插入到最终表中。所以,我猜,RETURNS 应该是无效的(RETURNS void),不是吗?另外,您为什么使用 FUNCTION 而不是 PROCEDURE?任何文件都可以帮助我理解这一点吗? PD:我的背景是 SqlServer,这在那个环境中要简单得多......
【解决方案2】:

错误的原因是SQL函数在创建时被解析。您可以通过将参数check_function_bodies 设置为off 来避免这种情况。

但这对你没有多大帮助:它允许你创建函数,但是当你执行这个过程时你最终会遇到同样的错误,因为所有的语句在函数启动时都会被解析,my_temp 会当时不存在。

解决方案是使用 PL/pgSQL,就像 JGH 的回答建议的那样。

【讨论】:

    猜你喜欢
    • 2013-06-07
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多