我正在使用Postgres 8.3数据库并尝试使用PL / pgSQL创建函数,该函数根据输入到表中的日期生成表名:
我必须创建一系列按日期索引的表格,例如:
drop table one_day_11_13 cascade;
create table one_day_11_13 as
select * from master_table where
timestamp < '2012-11-14' and timestamp >= '2012-11-13';
drop table one_day_11_14 cascade;
create table one_day_11_14 as
select * from master_table where
timestamp < '2012-11-15' and timestamp >= '2012-11-14';
我在想这样做的方法是创建一个PL / pgSQL函数,以参数('11_13', '2012-11-14', '2012-11-13')
为例创建上面的第一个表。我编写相应的EXECUTE语句时遇到问题。
执行此类操作的最佳方法是PL / pgSQL过度杀伤?
答案 0 :(得分:4)
首先,考虑升级到更新版本。 8.3 is on its way out.
对于8.3,它可以这样工作:
CREATE OR REPLACE FUNCTION f_recreate_tbl(date, date)
RETURNS void AS
$func$
DECLARE
-- derive tablename from first date
_tbl text := 'one_day_' || to_char($1, 'MM_YY');
BEGIN
-- Use IF EXISTS to avoid an exception when table does not exist.
EXECUTE
'DROP TABLE IF EXISTS ' || _tbl || ' CASCADE';
EXECUTE
'CREATE TABLE ' || _tbl || ' AS
SELECT *
FROM master_table
WHERE timestamp >= ''' || $1::text || '''::date
AND timestamp < ''' || $2::text || '''::date';
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT f_recreate_tbl('2012-11-13'::date, '2012-11-14'::date);
每当您想要参数化标识符时,都不能使用纯SQL。在PL / pgSQL函数或EXECUTE
(版本9.0 +)中使用DO
statement动态SQL。
此版本足够安全。通过更灵活的输入,您必须使用quote_ident()
and quote_literal()
清理标识符和值,以防止可能的SQL注入。
在现代版本中(自8.4起),您可以使用USING
子句跳过将参数转换为文本。
请勿使用timestamp
作为列名。它是数据类型的名称。
使用DROP TABLE
IF EXISTS
。 Already available in 8.3.
我从日期派生表名并跳过第三个参数。看似简化。