2016-06-10 58 views
1

所以我有我需要每晚产生的表格。作为一个例子,我有如foo_01jan16,foo_02jan2016,foo_03jan2016等表格。此外,我在每天运行的其他查询中引用这些表格。但是,查找和替换似乎效率低下。我想要做的是自动化这个过程。我想要做的事,如:动态表名称按日期

CREATE OR REPLACE FUNCTION table_date() RETURNS text AS $$ 
      SELECT 'foo_'||to_char(current_timestamp, 'DDMONYY') AS result 
    $ LANGUAGE SQL; 

然后在查询我可以引用table_date()?即

CREATE TABLE table_date() AS 
    SELECT * FROM base_table WHERE date <= current_date; 

    SELECT * FROM table_date() LIMIT 10; 

就是这样的。我使用的是PostgreSQL 8.2。

感谢

+0

你从哪里得到8.2 .. –

+2

PG 8.2比旧的iPhone! 4.5年来一直没有支持它(比如bug和安全修复)。除非你自己在过去的一年内建立它,因此它具有“很好的功能”,如[Heartbleed](http://heartbleed.com)漏洞。升级! – Patrick

+0

可能重复的[变量引用postgreSQL](http://stackoverflow.com/questions/37738042/variable-reference-for-postgresql) – Nicarus

回答

1

不,你不能这样做,因为PG需要一个字符串表名,而不是一些表达。像往常一样,在PG中有一个解决方法,在PL/pgSQL函数中以动态查询的形式。

首先,你必须创建表,填充它:SELECT todays_data();

CREATE FUNCTION todays_data() RETURNS void AS $$ 
BEGIN 
    EXECUTE 'CREATE TABLE foo_' || to_char(CURRENT_DATE, 'DDMONYYYY') || 
      ' AS SELECT * FROM base_table WHERE date <= CURRENT_DATE'; 
END; 
$$ LANGUAGE plpgsql; 

你应该每天一次调用这个函数。

对于需要为其中的每个人制作功能的查询,请使用CURSOR。按照今天的标准,这是相当低效的,但PG 8.2不支持RETURN NEXT QUERY,它可以通过一个语句解决下面的功能。因此,硬盘的方式:

CREATE FUNCTION someday_query1(dt date) RETURNS SETOF base_table AS $$ 
DECLARE 
    cur refcursor; 
    rec base_table%ROWTYPE; 
BEGIN 
    OPEN cur FOR EXECUTE 'SELECT * FROM foo_' || to_char(dt, 'DDMONYYYY') || 
         ' WHERE some_condition'; 
    FETCH cur INTO rec; 
    WHILE FOUND LOOP 
    RETURN NEXT rec; 
    FETCH cur INTO rec; 
    END LOOP; 
    CLOSE cur; 
END; 
$$ LANGUAGE plpgsql STRICT; 

然后就可以调用查询像这样:

SELECT * FROM someday_query1(CURRENT_DATE); 

SELECT * FROM someday_query1('2016-01-23'); 
+0

所以我尝试了一个小玩具表,并且一直返回一个错误:'RETURN NEXT必须在函数中指定一个记录或行变量......''RETURN NEXT'SELECT ...似乎存在问题... ' – windsormatic

+0

这从文档中并不明显,但没问题。参见上面的替代方法。如果这不起作用,那么你运气不好。 – Patrick