2016-06-10 94 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