我有一个表address_all
,它由几个地址表继承。 address_history
从父表history_all
继承并保留当前地址信息。我正在创建一个新表继承address_all
表并将信息从address_history
复制到新表。
我的存储过程如下所示。我打电话时遇到一些错误。为了更好地解释错误,我正在使用行号。
1 CREATE OR REPLACE FUNCTION somefunc()
2 RETURNS void AS
3 $BODY$
4 DECLARE
5 year_id INTEGER;
6 month_id INTEGER;
7 week_id INTEGER;
8 addresstablename text;
9 backupdays text;
10 BEGIN
11 week_id := EXTRACT(DAY FROM TIMESTAMP 'now()');
12 month_id := EXTRACT(MONTH FROM TIMESTAMP 'now()');
13 year_id := EXTRACT(YEAR FROM TIMESTAMP 'now()');
14 addresstablename := 'address_history_' || week_id || '_' || month_id || '_' || year_id;
15 backupdays:= date_trunc('hour',CURRENT_TIMESTAMP - interval '7 days');
16 EXECUTE 'create table ' || addresstablename || '() INHERITS (address_all)';
17 EXECUTE 'insert into ' || addresstablename || ' select * from address_history where address_timestamp >= ' || backupdays || ''; --AS timestamp without time zone);
18 END;
19 $BODY$
20 LANGUAGE 'plpgsql' VOLATILE;
当我跑步时:
select somefunc()
我收到此错误:
ERROR: syntax error at or near "12"
LINE 1: ...story where address_timestamp >= 2012-07-31 12:00:00-0...
^
QUERY: insert into address_history_7_8_2012 select * from address_history where address_timestamp >= 2012-07-31 12:00:00-04
CONTEXT: PL/pgSQL function "somefunc" line 14 at EXECUTE statement
********** Error **********
ERROR: syntax error at or near "12"
SQL state: 42601
Context: PL/pgSQL function "somefunc" line 14 at EXECUTE statement
答案 0 :(得分:5)
尝试这种大致简化的形式:
CREATE OR REPLACE FUNCTION somefunc()
RETURNS void AS
$func$
DECLARE
addresstablename text := 'address_history_' || to_char(now(), 'FMDD_MM_YYYY');
BEGIN
EXECUTE
'CREATE TABLE ' || addresstablename || '() INHERITS (address_all)';
EXECUTE
'INSERT INTO ' || addresstablename || '
SELECT *
FROM address_history
WHERE address_timestamp >= $1'
USING date_trunc('hour', now() - interval '7 days');
END
$func$ LANGUAGE plpgsql;
您可以在声明时在plpgsql中分配变量。简化代码。
使用to_char()
格式化日期。更简单。
now()
和CURRENT_TIMESTAMP
也是如此。
如果您想要当前时间戳,请不要引用'now()'
,使用now()
(不带引号)。
使用USING
clause with EXECUTE
,因此您无需将timestamp
转换为text
并返回 - 可能会遇到引用等问题你做到了。更快,更简单,更安全。
在LANGUAGE plpgsql
中,plpgsql
是关键字,不应引用。
您可能想要检查表格是否已存在CREATE TABLE IF NOT EXISTS
,自PostgreSQL 9.1起可用。
答案 1 :(得分:2)
显然你需要引用backupdays,或者它不被视为解析时间戳的字符串。
答案 2 :(得分:1)
您正在使用字符串操作构建SQL,因此您必须正确引用所有内容,就像使用任何其他语言一样。有一个few functions that you'll want to know about:
quote_ident
:引用标识符,例如表名。quote_literal
:引用一个字符串作为字符串文字。quote_nullable
:作为quote_literal
,但也正确处理NULL。这样的事情会更好地为你服务:
EXECUTE 'create table ' || quote_ident(addresstablename) || ...
EXECUTE 'insert into ' || quote_ident(addresstablename) || ... || quote_literal(backupdays) ...
在您的情况下,quote_ident
电话不是必需的,但它们是一个好习惯。