我可以在同一个 SQL 函数中创建和访问 table 吗?

Can I create and access a table in the same SQL function?

我正在尝试创建一个 Postgres SQL 函数,它 运行 是我的数据库的一些例程。

SQL-函数调用了一个 plpgsql-函数,该函数创建了几个临时 tables,但 return 没有任何东西(RETURNS void ). 由 plpgsql-函数创建的 table 之一应该用在我的 sql-函数中。

CREATE OR REPLACE FUNCTION public.my_sql_function()
  RETURNS text AS
$BODY$

select public.my_plpsql_function(); -- this returns void, but has created a temp table "tmp_tbl"

DROP TABLE IF EXISTS mytable CASCADE;
CREATE TABLE mytable (
  skov_id int8 PRIMARY KEY,
  skov_stor int4,
  skov_areal_ha numeric,
  virkningfra timestamp(0) without time zone,
  plannoejagtighed float8,
  vertikalnoejagtighed float8,
  geom geometry(MultiPolygon,25832),
  orig_geom geometry(Polygon, 25832) 
);

INSERT INTO mytable
select * from tmp_tbl ....

$BODY$  LANGUAGE sql;

当我尝试 运行 行时,出现以下错误:

ERROR: relation "tmp_tbl" does not exist

pgAdmin 将 select * from tmp_tbl ... 行下划线作为有错误的部分。

因此 SQL-函数没有注意到 plpsql-函数创建了一个临时的 table.

有解决办法吗?

我认为这是不可能的 - 至少在未来的版本中应该是不可能的。 SQL 函数类似于视图,然后对数据库对象的引用应该在函数创建时有效。

没有任何解决方法 - 如果您需要临时 table,请使用 PLpgSQL,或者尝试在没有临时 table 的情况下编写您的代码(可能会好得多)。

在同一个 SQL 函数中创建 访问 table 通常是不可能的。直接在 SQL 函数中创建 table 还是在嵌套函数调用中创建都没有区别。所有对象都必须可见。

手册中 Query Language (SQL) Functions 章的顶部有一个又大又粗的注释指出:

Note

The entire body of a SQL function is parsed before any of it is executed. While a SQL function can contain commands that alter the system catalogs (e.g., CREATE TABLE), the effects of such commands will not be visible during parse analysis of later commands in the function. Thus, for example, CREATE TABLE foo (...); INSERT INTO foo VALUES(...); will not work as desired if packaged up into a single SQL function, since foo won't exist yet when the INSERT command is parsed. It's recommended to use PL/pgSQL instead of a SQL function in this type of situation.

相关:

  • Difference between language sql and language plpgsql in PostgreSQL functions