如何在Postgres 9.6中实现CREATE FUNCTION IF NOT EXISTS功能?
PostgreSQL 9.6 实现CREATE FUNCTION IF NOT EXISTS的方法
PostgreSQL 9.6 确实没有原生支持函数的CREATE ... IF NOT EXISTS语法,可通过以下两种常用方案绕过限制:
方案1:DO动态块检查创建(推荐,不修改已有对象)
直接执行以下结构的SQL即可,不会影响已存在的同签名函数,也不会丢失原有函数的权限、注释等配置:
DO $$ BEGIN -- 检查目标schema下的指定签名函数是否存在 IF NOT EXISTS ( SELECT 1 FROM pg_proc JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid WHERE proname = '替换为你的函数名' AND nspname = '替换为目标schema名' -- 替换为你要创建的函数的参数类型列表,比如'int, text, timestamp' AND pg_get_function_identity_arguments(pg_proc.oid) = '你的函数参数类型列表' ) THEN -- 替换为完整的CREATE FUNCTION语句 EXECUTE ' CREATE FUNCTION 目标schema名.你的函数名(参数名1 参数类型1, 参数名2 参数类型2) RETURNS 返回值类型 AS $func$ BEGIN -- 这里写你的函数实现逻辑 END; $func$ LANGUAGE plpgsql; '; END IF; END $$;
逻辑说明:
- 系统表
pg_proc存储PostgreSQL所有函数的元数据,pg_namespace存储schema元数据,二者关联可定位到指定schema下的函数 - 函数
pg_get_function_identity_arguments用于精确匹配函数的参数签名,避免同名不同参的函数被误判
方案2:先删后建(适用于不需要保留旧函数配置的场景)
如果你的场景允许覆盖已有同签名函数,可以用更简洁的写法:
-- 先判断存在就删除,再创建新函数 DROP FUNCTION IF EXISTS 目标schema名.你的函数名(参数类型1, 参数类型2); CREATE FUNCTION 目标schema名.你的函数名(参数名1 参数类型1, 参数名2 参数类型2) -- 后续为正常的函数定义内容
注意事项:
该方案会先删除已存在的同签名函数再重建,原有函数的权限设置、自定义注释、关联触发器等配置都会丢失,仅适合不需要保留旧函数附加信息的场景。
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

