问题描述
我用一个简单的函数创建了一个简单的表格,插入一些已过去学期的日志:
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 into log_elapsedsemester(sy,recordedby) values ('2020-
2021','sample@gmail.com');
我将 Postgresql 9.5 与 pgadmin III 一起使用。
解决方法
您需要显式转换为 timestamp
。喜欢:
SELECT addelapsedsemester('2019-2020','1',now()::timestamp,'sample@gmail.com');
或者使用 LOCALTIMESTAMP
代替 now()::timestamp
(等效)。
函数 now()
返回类型 timestamp with time zone
(timestamptz
),而您的函数接受 timestamp without time zone
(timestamp
)。 now()
函数产生一个 typed 值(与其他无类型文字不同),其中 Postgres 更不愿意将其强制为不同类型。 Function type resolution 没有成功。
相同类型的强制仍然适用于裸 INSERT
命令,因为 (quoting the manual):
如果任何列的表达式不是正确的数据类型,将尝试自动类型转换。
请注意,从 timestamptz
到 timestamp
的转换取决于会话的当前 timezone
设置。您可能想要更明确。喜欢now() AT TIME ZONE 'Europe/London'
。或者使用 timestamptz
开始。然后你没有演员的原始电话就可以工作。见:
此外,您很可能不想使用类型 ,它是 char
character(1)
的误导性短语法。请改用 text
或 varchar
。见:
这个表定义更有意义:
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'
函数参数将匹配列类型。