PostgreSQL 14.6中PL/pgSQL执行报错:角色'test'不存在
问题分析与解决办法
报错原因
从错误信息能看出来,执行GRANT语句时找不到test角色,但你代码里明明写了「只有角色不存在才创建」,核心问题出在这:
- 错误里的
GRANT是针对postgres数据库的,说明你当前连接的是postgres库,但代码外层判断的是「当前库必须是dev3/dev2/dev1之一」才会执行创建角色的逻辑,此时条件不满足,根本不会创建test,自然执行GRANT就会报错。 - 如果你当前连接的是dev3/dev2/dev1中的一个,仍出现这个错误,大概率是执行代码的用户没权限创建角色(正常会报权限错误,但也不排除特殊场景),或者创建角色的语句未实际执行。
排查步骤
确认当前连接的数据库:
执行这条SQL查看当前连接的库:SELECT current_database();如果结果不是dev3/dev2/dev1,外层逻辑不会触发,不会创建
test,此时若手动执行过GRANT或代码被修改,就会出现角色不存在的错误。检查当前用户的权限:
若当前连接的是目标库,执行这条SQL查看权限:SELECT rolsuper, rolcreaterole FROM pg_catalog.pg_roles WHERE rolname = current_user;要是
rolsuper和rolcreaterole都是f,说明你没有创建角色的权限,需要切换到postgres这类超级用户执行代码。
修正后的代码
给代码加了权限检查和日志提示,方便排查问题:
DO $do$ DECLARE lc_db_names CONSTANT text[] := array['dev3','dev2','dev1']; BEGIN IF current_database() = any(lc_db_names) THEN -- 先检查是否有创建角色的权限 IF NOT EXISTS ( SELECT FROM pg_catalog.pg_roles WHERE rolname = current_user AND (rolsuper OR rolcreaterole) ) THEN RAISE EXCEPTION '当前用户无创建角色权限,请切换超级用户执行'; END IF; IF NOT EXISTS ( SELECT FROM pg_catalog.pg_roles WHERE rolname = 'test' ) THEN CREATE ROLE test login encrypted password 'md5d2cdf586595c9e1ca7c7d7db3951f3fd'; CREATE SCHEMA authorization test; EXECUTE format('GRANT connect, temporary ON DATABASE %I TO %I', current_database(), 'test'); RAISE NOTICE '角色test创建并授权成功'; ELSE RAISE NOTICE '角色test已存在,无需重复创建'; END IF; ELSE RAISE NOTICE '当前数据库不在目标列表中,跳过角色创建'; END IF; END $do$;
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

