PostgreSQL anyelement函数报错:无法确定多态类型,输入类型未知
问题分析与解决方案
错误含义
当你传入'https://example.com/submit'这类未指定类型的字符串字面量时,PostgreSQL无法确定它的具体类型——anyelement是多态类型,需要明确的输入类型来推断函数的具体实例。而未加类型转换的字符串字面量默认类型为unknown,PostgreSQL无法从unknown推断出anyelement对应的实际类型,因此抛出该错误。
无需提前转换的解决方法
最优方案是通过重载函数实现,既保留对任意类型的支持,又能直接接收未指定类型的字符串:
1. 新增text类型参数的重载函数
保留原anyelement版本的同时,新增一个接收text参数的函数版本,让未指定类型的字符串字面量自动匹配该版本:
-- 新增text参数版本,适配未指定类型的字符串 CREATE OR REPLACE FUNCTION isURL(data text) RETURNS BOOLEAN AS $$ BEGIN RETURN data ~ '^https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,255}\.[a-z]{2,6}(\/[-a-zA-Z0-9@:%._\+~#=]*)*(\?[-a-zA-Z0-9@:%_\+.~#()?&//=]*)?$'; END $$ LANGUAGE plpgsql; -- 保留原anyelement版本,支持其他任意类型输入 CREATE OR REPLACE FUNCTION isURL(data anyelement) RETURNS BOOLEAN AS $$ BEGIN RETURN data::text ~ '^https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,255}\.[a-z]{2,6}(\/[-a-zA-Z0-9@:%._\+~#=]*)*(\?[-a-zA-Z0-9@:%_\+.~#()?&//=]*)?$'; END $$ LANGUAGE plpgsql;
此时调用select isurl('https://example.com/submit');会自动匹配text版本函数,传入varchar、citext等其他类型时则匹配anyelement版本,无需手动转换输入。
其他可选方案(便捷性略逊)
如果不想重载函数,也可以通过coalesce帮PostgreSQL推断类型:
-- 修改原函数参数为anynonarray并设置STRICT属性 CREATE OR REPLACE FUNCTION isURL(data anynonarray) RETURNS BOOLEAN AS $$ BEGIN RETURN data::text ~ '^https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,255}\.[a-z]{2,6}(\/[-a-zA-Z0-9@:%._\+~#=]*)*(\?[-a-zA-Z0-9@:%_\+.~#()?&//=]*)?$'; END $$ LANGUAGE plpgsql STRICT; -- 调用时通过coalesce指定默认类型 select isurl(coalesce('https://example.com/submit', ''::text));
这种方式需要额外编写coalesce,便捷性不如重载函数。
内容的提问来源于stack exchange,提问作者sudoExclamationExclamation
相关产品推荐
相关产品推荐

