我一直在寻找其他线程上的解决方案,但是我从其他主题中得到的只是我需要的一些部分,我无法将它们绑在一起才能正常工作。
问题的背景是:每天晚上将事务日志写入数据库中新创建的表,然后清除主日志。创建的表的名称与日期无关(难以搜索历史日志 - 因此无法猜测给定日期的表名或硬编码)。
但是,一旦将事务移动到新表中,日志记录表就会添加一条新记录,用于存储日期和有关已归档记录的其他信息(包括表的名称)。
我正在尝试编写一个允许我将日期范围(开始日期和结束日期)传递给它的函数,然后返回在给定日期范围内具有信息的所有表的名称 - 将名称存储在阵列。填充数组后,将对阵列中的每个表运行SQL查询,以将所有这些写入单个临时表,从而允许对其进行查询。
一些伪代码将是:
CREATE OR REPLACE FUNCTION transactions(begin_date varchar(10), end_date varchar(10)) RETURN void as $$
Begin
SELECT INTO table_names 'name' from 'log_table' where 'log_date' between begin_date and end_date;
FOREACH table_names LOOP
SQL_Query = "INSERT INTO temporary_table SELECT * from " + table_names;
EXECUTE SQL_Query;
END LOOP;
任何帮助都表示赞赏 - 我的逻辑可以完全打破,我需要改变我的方法。
答案 0 :(得分:0)
CREATE OR REPLACE FUNCTION f_create_temp_trans(_begin date
,_end date, OUT _rows int) AS
$func$
BEGIN
DROP TABLE IF EXISTS temp_trans;
CREATE TEMP TABLE IF NOT EXISTS temp_trans (LIKE existing_tbl);
EXECUTE (
SELECT E'INSERT INTO temp_trans\NSELECT * FROM '
|| string_agg(quote_ident(tbl_name)
, E'\NUNION ALL SELECT * FROM '
ORDER BY log_date)
FROM log_table
WHERE log_date BETWEEN _begin AND _end
);
GET DIAGNOSTICS _rows = ROW_COUNT;
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT * FROM f_create_temp_trans('2014-06-01', '2014-06-11');
返回插入临时表的行数。
创建名为temp_trans
的临时表(抢占式)(在会话期间有效)。结构从existing_tbl
复制 - 替换为实际的表名。
使用汇总函数string_agg()
与INSERT
组成单UNION ALL
,这比运行许多INSERT
更有效语句。
生成并执行以下形式的声明:
INSERT INTO temp_trans
SELECT * FROM tbl1
UNION ALL SELECT * FROM "trickY name tbl2"
UNION ALL SELECT * FROM tbl3
...
单引号('val'
)用于值,而不是标识符,必要时使用双引号。
为什么您的约会varchar(10)
?在我的代码中使用 date
就好了。
E'\N'
是换行符。只是为了调试生成的SQL代码以进行调试。不需要。你可以用空格替换:
...
SELECT 'INSERT INTO temp_trans SELECT * FROM '
|| string_agg(quote_ident(tbl_name), ' UNION ALL SELECT * FROM ' ...
关于引用和转义字符串: