繁体   English   中英

SQL状态:42601语法错误在“11”或附近

[英]SQL state: 42601 syntax error at or near “11”

我有一个表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

尝试这种大致简化的形式:

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子句与EXECUTE一起USING ,因此您不必将timestamp转换为text并返回 - 可能会像您一样运行引用问题。 更快,更简单,更安全。

  • LANGUAGE plpgsqlplpgsql是一个关键字,不应引用。

  • 您可能想要检查表是否已存在CREATE TABLE IF NOT EXISTS ,自PostgreSQL 9.1起可用。

显然你需要引用backupdays,或者它不被视为解析时间戳的字符串。

您正在使用字符串操作构建SQL,因此您必须正确引用所有内容,就像使用任何其他语言一样。 您需要了解一些函数

  • 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调用不是必需的,但它们是一个好习惯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM