问题描述
我有一个带有可选参数的简单函数。当我遗漏一个参数时,它应该只是默认为 null,我得到一个错误,它不是一个整数。
功能如下:
CREATE FUNCTION rewrite(_postid integer DEFAULT NULL::integer,_url character varying DEFAULT NULL::character varying)
RETURNS TABLE
(
PostTypeID integer,DestinationURL varchar,)
LANGUAGE plpgsql
AS
$function$
BEGIN
RETURN QUERY
SELECT
NULL AS PostTypeID,_url AS DestinationURL,FROM reference.destinations dest1
WHERE length(TRIM(dest1.DestinationURL)) > 0
AND _url LIKE '%' || TRIM(dest1.DestinationURL)) || '%'
ORDER BY length(dest1.DestinationURL)) DESC
LIMIT 1;
END;
$function$
如果我运行 SELECT * FROM utility.rewrite(_url := 'wikipedia.org')
然后我得到这个错误:
[42804] 错误:查询结构与函数结果类型不匹配 详细信息:返回的类型文本与预期的类型整数不匹配 第 1 列。
所以 column1
必须是我的 PostTypeID
定义中的 RETURNS TABLE
列。但是我选择了 NULL AS PostTypeID
那么为什么它不只是返回 NULL?
如果我运行 SELECT * FROM utility.rewrite(_postid = 0,_url := 'wikipedia.org')
那么它工作正常。但我不想返回 0
,我想要 NULL。
解决方法
仅仅因为您在查询中使用别名 posttypeid
并不意味着 PostgreSQL 会推断出您的 PL/pgSQL 变量的数据类型。
尽管 NULL 可以是任何数据类型,但 PostgreSQL 必须确定查询结果列的数据类型。缺乏其他信息,它任意选择text
。
将查询结果类型映射到函数结果类型稍后发生,在 PL/pgSQL 中。这就是导致您观察到错误的原因。
您可以通过使用显式类型转换指定 NULL 的类型来避免该问题:
SELECT CAST (NULL AS integer)