postgres无法识别函数中的临时表

时间:2013-10-14 04:14:16

标签: sql postgresql user-defined-functions temp-tables

这可能是因为我累了,或者我是postgres的新手。但是,我正在尝试在函数中使用临时表,并且postgres抱怨“关系不存在”。然而,如果我采用我的函数的主体,并执行它,它的工作正常。下面是我正在尝试创建的函数类型的示例。请记住,我已经删除了所有有趣的内容,以便显示出我的问题。

CREATE OR REPLACE FUNCTION dbo.somefunc() RETURNS void AS
$BODY$ 

CREATE TEMPORARY TABLE work_list
(
    name text,
    level smallint
);

insert into work_list
    (name, level)
values
    ('someone', 25);

$BODY$
LANGUAGE sql VOLATILE;

我得到的投诉是在插入声明中。实际投诉是:

ERROR:  relation "work_list" does not exist

postgres不支持函数中的临时表吗?或者是否有一些语法的东西,我错过了这个东西窒息而且它给了我一个虚假的错误?

2 个答案:

答案 0 :(得分:3)

Postgres对您尝试创建的函数运行一些简单的检查,并且(正确地)找到表work_list尚未存在的表。我看到两个选择:

<击>

<击> 1。 “假装直到你做到了”

实际上在创建函数之前创建(临时)表。临时表将在会话结束时消失,但是一旦创建了该函数,您就已经通过了此测试 显然,在同一会话中运行该函数之前,必须删除该表以避免冲突。不过更好:在你的函数中使用CREATE TEMP TABLE IF NOT EXISTS(Postgres 9.1+)。如果表已经存在,您可能希望截断该表...

但是(参见下面的评论),引用手册

  

SQL函数的整个主体在任何它之前被解析   执行。虽然SQL函数可以包含改变命令的命令   系统目录(例如CREATE TABLE),这些命令的效果   在解析后来的命令时,将无法看到   功能。因此,例如,如果打包到单个SQL中,CREATE TABLE foo (...); INSERT INTO foo VALUES(...);将无法按预期工作   函数,因为在解析INSERT命令时foo将不存在。   建议在此使用PL / pgSQL而不是SQL函数   情况类型。

大胆强调我的。

2。改用PL / pgSQL

plpgsql中的检查不太彻底。如果Postgres仍然抱怨(在这种情况下不是这样),你也可以execute SQL dynamically with EXECUTE

除此之外:在许多情况下,有一个更高效的解决方案,没有临时表...

答案 1 :(得分:0)

结合这两个陈述。通过执行“select into”类型语法来创建临时表。这样你就可以做到。 CREATE TEMP TABLE SomeTable AS SELECT * FROM OtherTable ;