sql - 如何在其他过程中使用存储过程中创建的查询

标签 sql postgresql plpgsql

sql 过程创建应在其他 sql 过程中使用的临时表。 我试过了

CREATE or replace FUNCTION f_createquery()
  RETURNS TABLE ( kuupaev date
   ) AS $f_createquery$

-- actually this is big and time consuming select statement which should evaluated only once:
select current_date as kuupaev
$f_createquery$ LANGUAGE sql STABLE;


CREATE or replace FUNCTION f_usequery()
  RETURNS TABLE ( kuupaev date
  ) AS $f_usequery$

-- big query tehing is used several times in query:
select kuupaev from tehing
union all
select kuupaev+1 from tehing
union all
select kuupaev+2 from tehing
$f_usequery$ LANGUAGE sql STABLE;


with tehing as (
 select * from f_createquery() _
 )

 select * from f_usequery() _

但出现错误

ERROR:  relation "tehing" does not exist

tehin包含由存储过程创建的临时数据,并且它不存在于数据库中。如何允许其他存储过程使用它? 如何修复 Postgres 9.1+ 的问题?

有没有类似的东西

external table (kuupaev date)

哪个允许定义外部表? 在实际应用程序中,f_createquery 中的 select 语句很大且耗时,应该只评估一次。

select * from tehin 替换为 f_usequery() 中的动态 sql 可能有效,但这会阻止在运行时编译过程。是否有更好的解决方案或者可以以更好的方式传递给其他存储过程,例如像参数?

或者 f_createquery 应该创建具有固定名称的临时表?

最佳答案

如果f_createquery()生成临时表tehin那么它不应该返回任何内容。您的函数应如下所示:

CREATE FUNCTION f_createquery() RETURNS void AS $f_createquery$
  CREATE TEMPORARY TABLE tehing AS
    SELECT current_date AS kuupaev;  -- complex query here
$f_createquery$ LANGUAGE sql STABLE;

然后,您可以像任何其他表一样在当前 session 中使用tehin表:

CREATE FUNCTION f_usequery() RETURNS TABLE (kuupaev date) AS $f_usequery$
  SELECT kuupaev FROM tehing
  UNION ALL
  SELECT kuupaev+1 FROM tehing
  UNION ALL
  SELECT kuupaev+2 FROM tehing;
$f_usequery$ LANGUAGE sql STABLE;

请注意,临时表将在 session 结束时删除。

您还可以集成这两个函数,这样您就可以调用 f_usequery() 而不必担心先调用另一个函数:

CREATE FUNCTION f_usequery() RETURNS TABLE (kuupaev date) AS $f_usequery$
BEGIN
  PERFORM 1 FROM information_schema.tables WHERE table_name = 'tehing';
  IF NOT FOUND THEN  -- temp table tehing does not exist
    CREATE TEMPORARY TABLE tehing AS
      SELECT current_date AS kuupaev; -- etc, etc
  END IF;

  RETURN QUERY
    SELECT kuupaev FROM tehing
    UNION ALL
    SELECT kuupaev+1 FROM tehing
    UNION ALL
    SELECT kuupaev+2 FROM tehing;
END; $f_usequery$ LANGUAGE plpgsql STABLE;

请注意,这现在是一个 plpgsql 函数,因此语法略有不同。

结构

with tehing as (
 select * from f_createquery() _
)
select * from f_usequery() _

不起作用,因为您将 tehin 重新声明为 CTE 的结果。相反,f_usequery() 使用 tehin 临时表,您可以从中进行选择或使用 f_usequery() 的结果进行进一步分析:

SELECT f_createquery(); -- this creates the tehing temporary table

SELECT * FROM f_usequery(); -- this operates on the tehing table and returns some results

SELECT *
FROM tableX
JOIN f_usequery() USING (kuupaev)
WHERE kuupaev < '2015-09-19';

关于sql - 如何在其他过程中使用存储过程中创建的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32665939/

相关文章:

javascript - Node.js API 与 express 和 mysql - WHERE IN 和带有多个逗号分隔值的绑定(bind)参数

SQLiteDatabase 从 3 个表中选择

sql - 是否可以在 PostgreSQL 中创建一个带有变量名的表?

postgresql - 在 PL/pgSQL 中更新整行

java - 如何在java jdbc应用程序的属性文件中编写复杂的sql查询

sql - SQL Server 中区分大小写的变量名称?

sql - 左连接和右表中的数据

sql - Postgresql 应用程序插入和触发器性能

Postgresql join_collapse_limit 和查询计划的时间

postgresql - 在函数空白结果中选择语句