You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL 14.6中PL/pgSQL执行报错:角色'test'不存在

问题分析与解决办法

报错原因

从错误信息能看出来,执行GRANT语句时找不到test角色,但你代码里明明写了「只有角色不存在才创建」,核心问题出在这:

  • 错误里的GRANT是针对postgres数据库的,说明你当前连接的是postgres库,但代码外层判断的是「当前库必须是dev3/dev2/dev1之一」才会执行创建角色的逻辑,此时条件不满足,根本不会创建test,自然执行GRANT就会报错。
  • 如果你当前连接的是dev3/dev2/dev1中的一个,仍出现这个错误,大概率是执行代码的用户没权限创建角色(正常会报权限错误,但也不排除特殊场景),或者创建角色的语句未实际执行。

排查步骤

  1. 确认当前连接的数据库:
    执行这条SQL查看当前连接的库:

    SELECT current_database();
    

    如果结果不是dev3/dev2/dev1,外层逻辑不会触发,不会创建test,此时若手动执行过GRANT或代码被修改,就会出现角色不存在的错误。

  2. 检查当前用户的权限:
    若当前连接的是目标库,执行这条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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:11:05