APEX 19.1通过PLSQL创建用户报安全组ID相关错误如何解决?
错误原因排查
- 权限不足:执行脚本的数据库用户未被授予
APEX_ADMINISTRATOR_ROLE角色,无法操作APEX安全组和用户管理接口,操作INTERNAL内部工作区还需要额外的系统包执行权限 - 缺少APEX运行环境初始化:APEX 19.x版本要求调用用户管理、会话创建接口前,必须先初始化APEX运行时上下文,直接设置安全组ID会导致
g_security_group_id全局变量未正确赋值 - 取值错误:你查询得到的
APPLICATION_GROUP_ID不是工作区ID,同时数值显示为科学计数法是客户端显示问题,赋值时要确保没有精度丢失 - 安全组与应用ID不匹配:创建会话时调用
post_login接口传入的应用ID,和当前设置的安全组ID不属于同一个工作区,触发一致性校验报错
正确操作方案
步骤1:给执行用户授权
使用SYS或SYSTEM用户执行以下授权语句,替换你的执行用户名为实际运行PLSQL的数据库账号:
-- 基础操作权限 GRANT APEX_ADMINISTRATOR_ROLE TO 你的执行用户名; -- INTERNAL工作区操作额外权限 GRANT EXECUTE ON APEX_190100.WWV_FLOW_API TO 你的执行用户名;
步骤2:指定应用ID创建APEX用户脚本
适配你当前应用ID为4050的场景:
DECLARE l_workspace_id NUMBER; BEGIN -- 初始化APEX运行时上下文,19.x版本必须项 APEX_190100.WWV_FLOW_API.INITIALIZE( p_flow_id => 4050, p_security_group_id => NULL ); -- 获取应用对应的工作区ID SELECT WORKSPACE_ID INTO l_workspace_id FROM APEX_APPLICATIONS WHERE APPLICATION_ID = 4050 AND ROWNUM = 1; -- 设置安全组ID APEX_UTIL.SET_SECURITY_GROUP_ID( P_SECURITY_GROUP_ID => l_workspace_id ); -- 创建工作区管理员用户 APEX_UTIL.CREATE_USER ( P_USER_NAME => 'BOB', P_EMAIL_ADDRESS => 'bob@bob.com', P_DEFAULT_SCHEMA => 'MY_SPACE', P_ALLOW_ACCESS_TO_SCHEMAS => 'MY_SPACE', P_WEB_PASSWORD => 'change_me', P_DEVELOPER_PRIVS => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL' ); COMMIT; -- 清除会话上下文避免后续操作冲突 APEX_UTIL.CLEAR_SESSION_STATE; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END; /
步骤3:指定工作区名称创建用户脚本
如果需要直接按工作区名INTERNAL创建用户,使用以下脚本:
DECLARE l_workspace_id NUMBER; BEGIN -- 先绑定工作区上下文 APEX_UTIL.SET_WORKSPACE(p_workspace => 'INTERNAL'); -- 获取工作区安全组ID l_workspace_id := APEX_UTIL.FIND_SECURITY_GROUP_ID(p_workspace => 'INTERNAL'); -- 设置安全组ID APEX_UTIL.SET_SECURITY_GROUP_ID(p_security_group_id => l_workspace_id); -- 创建普通用户 APEX_UTIL.CREATE_USER( p_user_name => 'NEWUSER1', p_web_password => 'secret99', p_default_schema => 'MY_SPACE' ); COMMIT; END; /
会话创建报错修复方案
你之前调用post_login触发的应用ID与安全组不一致报错,使用以下修正代码:
DECLARE l_workspace_id NUMBER; -- 自定义参数 p_app_id NUMBER := 4050; p_app_user VARCHAR2(100) := 'BOB'; p_app_page_id NUMBER := 1; BEGIN -- 初始化应用上下文 APEX_190100.WWV_FLOW_API.INITIALIZE( p_flow_id => p_app_id, p_security_group_id => NULL ); -- 获取并设置当前应用对应的工作区安全组 SELECT WORKSPACE_ID INTO l_workspace_id FROM APEX_APPLICATIONS WHERE APPLICATION_ID = p_app_id; APEX_UTIL.SET_SECURITY_GROUP_ID(l_workspace_id); -- 调用登录接口 apex_custom_auth.post_login( p_uname => p_app_user, p_session_id => APEX_CUSTOM_AUTH.GET_NEXT_SESSION_ID, p_app_page => p_app_id||':'||p_app_page_id ); COMMIT; END; /
内容的提问来源于stack exchange,提问作者ss_beer
相关产品推荐
相关产品推荐

