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/