使用 TIMESTAMP 创建插入函数

Creating insert function with TIMESTAMP

我创建了简单的 table 和一个简单的函数,为过去的学期插入一些日志:

CREATE TABLE log_elapsedsemester(
sy char(9) NOT NULL,
sem char(1) NOT NULL,
date_recorded TIMESTAMP NOT NULL,
recordedby varchar(255)
);

CREATE OR REPLACE FUNCTION addelapsedsemester(p_sy char,p_sem char,p_date_recorded 
TIMESTAMP,p_recordedby varchar)
returns void
AS
$$
BEGIN
insert into log_elapsedsemester (sy,sem,date_recorded,recordedby) values 
(p_sy,p_sem,p_date_recorded,p_recordedby);
END
$$
LANGUAGE plpgsql;

但我每次都用

select addelapsedsemester('2019-2020','1',now(),'sample@gmail.com');

我收到错误:

No function matches the given name and argument types. You might need to add explicit type casts.

如果我使用没有函数的简单 INSERT,它会成功插入:

insert into log_elapsedsemester(sy,sem,date_recorded,recordedby) values ('2020- 
2021','1',now(),'sample@gmail.com');

我在 pgadmin III 中使用 PostgreSQL 9.5。

您需要明确转换为 timestamp。喜欢:

SELECT addelapsedsemester('2019-2020', '1', now()::timestamp,'sample@gmail.com');

或使用 LOCALTIMESTAMP 代替 now()::timestamp(等效)。

函数 now() returns 键入 timestamp with time zone (timestamptz),而您的函数采用 timestamp without time zone (timestamp)。 now() 函数产生一个 typed 值(与其他无类型文字不同),Postgres 更不愿意将其强制转换为不同的类型。 Function type resolution 没有成功。

相同类型的强制转换仍然适用于裸 INSERT 命令,因为 (quoting the manual):

If the expression for any column is not of the correct data type, automatic type conversion will be attempted.

请注意,从 timestamptztimestamp 的转换取决于会话的当前 timezone 设置。您可能想要更明确。喜欢now() AT TIME ZONE 'Europe/London'。或者使用 timestamptz 作为开头。然后你的原始电话没有演员就可以了。参见:

  • Now() without timezone

此外,您很可能不想使用类型 char,这是 character(1) 的误导性短语法。请改用 textvarchar。参见:

  • Any downsides of using data type "text" for storing strings?

这个 table 定义更有意义:

CREATE TABLE log_elapsedsemester(
  sy varchar(9) NOT NULL
, sem integer   NOT NULL
, date_recorded timestamptz NOT NULL
, recordedby text
);

甚至:

sy integer NOT NULL  -- 2019 can stand for '2019-2020'

函数参数将匹配列类型。