在 Postgresql 的非易失性函数中不允许 CREATE TABLE AS

say*_*bir 2 postgresql postgresql-10

我在 postgresql 10 上写了这个方法:

create or replace function get_users()
  returns TABLE(user_idd uuid, device_idd text, shapee text , datee timestamp) AS
$$
begin
  create temp table lines as
    SELECT DISTINCT user_id, device_id from olocations;
  select uuid_generate_v4(),
         o1.user_id,
         o1.device_id,
         st_astext(ST_Collect(o1.shape)),
         date(o1.creation_date_time) as date
  from olocations o1
      inner join lines on o1. device_id = lines.device_id and o1.user_id = lines.user_id
    where o1.user_id = 'd0edfc59-9923-44c3-9c34-ef5aad3cb810'
    and o1.device_id = '89984320001811791540'
group by o1.user_id, o1.device_id, date
order by date ASC ;
DROP TABLE lines;
end
$$
LANGUAGE 'plpgsql'
IMMUTABLE
SECURITY DEFINER
COST 100;
Run Code Online (Sandbox Code Playgroud)

在没有任何问题的情况下创建方法后,当我调用我的方法时: select * from get_users(); 我收到此错误:

sql> select  from get_users()
[2018-09-30 17:23:23] [0A000] ERROR: CREATE TABLE AS is not allowed in a non-volatile function
[2018-09-30 17:23:23] Where: SQL statement "create temp table lines as
[2018-09-30 17:23:23] SELECT DISTINCT user_id, device_id from olocations"
[2018-09-30 17:23:23] PL/pgSQL function get_users() line 3 at SQL statement
Run Code Online (Sandbox Code Playgroud)

我想我不能在方法中创建表?对?

kli*_*lin 6

函数不能为IMMUTABLE,定义为VOLATILE

根据文档:

任何具有副作用的函数都必须标记为 VOLATILE,这样对其的调用就不能被优化掉。

在这种情况下,此副作用是表创建。


更新。

使用return query返回查询生成的行:

  ...
  return query  
  select uuid_generate_v4(),
         o1.user_id,
         o1.device_id,
         st_astext(ST_Collect(o1.shape)),
         date(o1.creation_date_time) as date
  ...
Run Code Online (Sandbox Code Playgroud)