【问题标题】:Postgres: Temporary table in function is persistent. Why?Postgres:函数中的临时表是持久的。为什么?
【发布时间】:2015-11-20 13:53:09
【问题描述】:

我的 postgresql 数据库中有以下函数:

CREATE OR REPLACE FUNCTION get_unused_part_ids()
  RETURNS integer[] AS
$BODY$
DECLARE
  part_ids integer ARRAY;
BEGIN
  create temporary table tmp_parts
      as
  select vendor_id, part_number, max(price) as max_price
    from refinery_akouo_parts
   where retired = false
   group by vendor_id, part_number
  having min(price) < max(price);

  -- do some work etc etc

  -- simulate ids being returned
  part_ids = '{1,2,3,4}';
  return part_ids;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION get_unused_part_ids()
  OWNER TO postgres;

这会编译,但是当我运行时:

select get_unused_part_ids();

临时表tmp_parts 仍然存在。之后我可以对其进行选择。请原谅我,因为我已经习惯了 t-sql/MSSQL 的特定功能。 MSSQL 不会出现这种情况。我做错了什么?

【问题讨论】:

    标签: sql postgresql postgresql-9.3 temp-tables sql-function


    【解决方案1】:

    临时表在两个数据库中的处理方式不同。在 SQL Server 中,它们将在创建它们的存储过程结束时被自动删除。

    在 Postgres 中,临时表被分配给会话(或事务),如 documentation 中所述:

    如果指定,则将该表创建为临时表。暂时的 表在会话结束时自动删除,或者 可选地在当前事务结束时(参见 ON COMMIT 以下)。现有的同名永久表不可见 临时表存在时到当前会话,除非他们 用模式限定的名称引用。上创建的任何索引 临时表也自动成为临时表。

    这个概念介于 SQL Server 中的常规临时表和全局临时表之间(全局临时表以 ## 开头)。

    【讨论】:

      【解决方案2】:

      该表只会在会话结束时被删除。您需要指定 ON COMMIT 选项才能删除,它会在事务结束时删除表。

        create temporary table tmp_parts 
        on commit drop
            as
        select vendor_id, part_number, max(price) as max_price
          from refinery_akouo_parts
         where retired = false
         group by vendor_id, part_number
        having min(price) < max(price);
      

      【讨论】:

        【解决方案3】:

        manual之后

        临时表在会话结束时自动删除,或者在当前事务结束时自动删除(请参阅下面的 ON COMMIT)

        断开连接后会话结束。不是在事务提交之后。所以默认行为是保留临时表,直到您的连接仍然打开。您必须添加 ON COMMIT DROP; 才能实现您想要的行为:

        create temporary table tmp_parts on commit drop
              as
          select vendor_id, part_number, max(price) as max_price
            from refinery_akouo_parts
           where retired = false
           group by vendor_id, part_number
          having min(price) < max(price)
        on commit drop;
        

        【讨论】:

        • 语句末尾的 on commit drop 会导致语法错误。如果您查看@JonathanG 的答案,他的作品。请编辑您的帖子以获得 +1。
        猜你喜欢
        • 2010-10-25
        • 2011-09-29
        • 2013-06-04
        • 2019-12-09
        • 2013-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-17
        相关资源
        最近更新 更多