想重命名表名,但是失败了,提示[0A000][3001] ORA-03001: 未实施的功能 Position: 0.
获取到USER_ID和ROLE_ID但是无法新增成功
问题出在哪里捏?
报错:ORA-06502: PL/SQL: 数字或值错误 : 字符到数值的转换错误
展示的是NAME(nvarchar类型),存入的是ID(number类型)
新增出错:Access to undefined Per Request (Memory Only) variable P35_ROLE_ID
访问未定义的每个请求 (仅内存)变量P35 ROLEID
是因为传入的项有ROLE_ID
在前台打印ROLE_ID,USER_ID,发现无法将其转化为想要的NUMBER类型
原来是测试用的输出语句错误,换成
console.log('角色id:' + $v('P35_ROLE_ID'));
console.log('用户id:' + $v('P35_USER_ID'));
可以在F12后在控制台看到USER_ID和ROLE_ID。
试试多用户的情况:
也能获取到,那就是存储SQL的问题了
晶点 p35 用户角色表单保存
-- 晶点 p35 用户角色表单保存
declare
v_err_msg nvarchar2(2000);
row_count number(20) := 1;
/**
* create by: xiaoxian
* create date:2023/11/17 13:19
* modify by:
* modify date:
* describe:晶点 p35 用户角色表单保存
*/
begin
-- 更新对应关联表单
update BASIC_SYSTEM_USER_ROLE set
USER_ID = :P35_USER_ID,
ROLE_ID = :P35_ROLE_ID,
REMARK = :P35_REMARKE,
IS_ENABLE = :P35_IS_ENABLE,
UPDATED_BY = :USER_ID,
UPDATE_DATE = sysdate
where USER_ROLE_ID = :P35_USER_ROLE_ID;
-- 删除本次取消选中的用户表单
delete BASIC_SYSTEM_USER_ROLE s
where s.USER_ID = :P35_USER_ID
and not exists(
select 1
from JA_UTILS_PKG.SPLIT_STR(:P35_USER_ID, ':') A
where s.USER_ID = A.data_val
);
-- 选中该的USER_ID分割 222360914514053:222360909348997 把: 去除
MERGE INTO BASIC_SYSTEM_USER_ROLE A
USING (
select data_val user_id, :P35_USER_ROLE_ID user_role_id
from JA_UTILS_PKG.SPLIT_STR(:P35_USER_ID, ':')
) B
ON (A.USER_ROLE_ID = B.USER_ROLE_ID and A.USER_ID = B.USER_ID)
WHEN NOT MATCHED THEN
insert (created_by, updated_by, user_role_id, user_id)
values (:USER_ID, :USER_ID, B.USER_ROLE_ID, B.USER_ID);
commit;
apex_util.set_session_state('P35_ROW_COUNT', row_count);
exception
when others then
rollback;
apex_util.set_session_state('P35_ROW_COUNT', 0);
v_err_msg := sqlerrm || chr(13) || dbms_utility.format_error_backtrace;
JA_WRITE_LOG('P' || :APP_PAGE_ID || '-用户 角色管理-保存', 'ERROR', V_ERR_MSG, :USER_ID, :USER_TENANT,
:APP_NAME || ':' || :APP_ID);
end;
-- 查询结果[2023-11-17 14:03:35] 不安全的查询: 不带 ''where'' 的 ''Update'' 语句会同时更新所有表行
[2023-11-17 14:03:35] 不安全的查询: 不带 ''where'' 的 ''Update'' 语句会同时更新所有表行
动态权限
晶台登录 apex_mpf_authentication_basic
登陆后验证 LOGIN_SUCCESS_SAVE_USER_BASIC
create function apex_mpf_authentication_basic(
p_username in varchar2,
p_password in varchar2)
return boolean
as
v_password varchar2(64);
v_mobile varchar2(64);
v_job_number varchar2(64);
v_err_msg varchar2(2000);
begin
select PASSWORD, MOBILE,JOB_NUMBER
into v_password,v_mobile,v_job_number
from BASIC_SYSTEM_LOGIN_USER
where LOGIN_USER_ID in (SELECT u.LOGIN_USER_ID
FROM BASIC_SYSTEM_USER_ROLE u
where u.IS_ENABLE = 1
and u.USER_ID in (select a.USER_ID
from SHARE_BASIC_USER_V a
where a.IS_LEAVE = 0 -- 中台 EHR账户“未离职”的状态下
and a.TENANT_ID = apex_util.get_session_state('USER_TENANT'))
and u.TENANT_ID = apex_util.get_session_state('USER_TENANT'))
and JOB_NUMBER = upper(p_username)
and SYSTEM_TYPE = 'BASIC'
and DEL_FLAG = 0
and TENANT_ID = apex_util.get_session_state('USER_TENANT');
if v_password is null then
return false;
else
if JA_UTILS_PKG.ENCRYPT_ENC(p_password) <> v_password then
return false;
else
return true;
end if;
end if;
exception
when others then
v_err_msg := sqlerrm || chr(13) || dbms_utility.format_error_backtrace;
JA_WRITE_LOG(JA_UTILS_PKG.GET_FN_NAME(), 'error', v_err_msg, apex_util.get_session_state('USER_ID'),
apex_util.get_session_state('USER_TENANT'), V('APP_NAME') || ':' || V('APP_ID'));
return false;
end;
/
create procedure LOGIN_SUCCESS_SAVE_USER_BASIC
as
v_user_id number(20);
v_basic_login_user_id number(20); --晶台登录用户ID
v_tenant_id varchar2(10);
v_tenant_name varchar2(64);
v_name varchar2(64);
v_job_number varchar2(64);
v_mobile varchar2(64);
app_key VARCHAR2(100);
app_secret VARCHAR2(100);
v_err_msg VARCHAR2(2000);
v_basic_role_id number(20); --晶台角色ID
v_basic_role_level number(20); -- 晶台角色级别
v_is_sync_user number(20); -- 晶台角色 是否同步为晶系列用户,1同步,0未同步
v_original_dept_id VARCHAR2(200);
v_parent_original_dept_id VARCHAR2(200);
V_PARENT_DEPT_ID number(30); -- 虚拟组织 上级ID
V_IS_OTHERS_LOGIN_USER_ID NUMBER(20) := 0; -- 晶系列角色用户ID是否存在
V_OTHERS_LOGIN_USER_ID NUMBER(20) := 0; -- 晶系列角色用户ID
begin
select u.USER_ID,
u.NAME,
u.JOB_NUMBER,
u.MOBILE,
u.TENANT_ID,
s.LOGIN_USER_ID
into
v_user_id,v_name,v_job_number,v_mobile,v_tenant_id,v_basic_login_user_id
from BASIC_USER u
inner join BASIC_SYSTEM_LOGIN_USER s
on s.USER_ID = u.USER_ID and s.TENANT_ID = u.TENANT_ID and s.DEL_FLAG = 0
where u.DEL_FLAG = 0
AND s.SYSTEM_TYPE = 'BASIC'
and u.JOB_NUMBER = upper( V( 'P9999_USERNAME' ) )
and u.TENANT_ID = apex_util.get_session_state( 'USER_TENANT' );
-- 晶系列角色登录用户ID
SELECT COUNT( 1 )
INTO V_IS_OTHERS_LOGIN_USER_ID
FROM BASIC_SYSTEM_LOGIN_USER
WHERE JOB_NUMBER = (SELECT JOB_NUMBER
FROM BASIC_SYSTEM_LOGIN_USER
WHERE LOGIN_USER_ID = v_basic_login_user_id
AND SYSTEM_TYPE = 'BASIC'
AND DEL_FLAG = 0
AND TENANT_ID = apex_util.get_session_state( 'USER_TENANT' ))
AND SYSTEM_TYPE = 'OTHERS'
AND DEL_FLAG = 0
AND TENANT_ID = apex_util.get_session_state( 'USER_TENANT' );
-- 存在的情况下
IF V_IS_OTHERS_LOGIN_USER_ID > 0 THEN
SELECT LOGIN_USER_ID
INTO V_OTHERS_LOGIN_USER_ID
FROM BASIC_SYSTEM_LOGIN_USER
WHERE JOB_NUMBER = (SELECT JOB_NUMBER
FROM BASIC_SYSTEM_LOGIN_USER
WHERE LOGIN_USER_ID = v_basic_login_user_id
AND SYSTEM_TYPE = 'BASIC'
AND DEL_FLAG = 0
AND TENANT_ID = apex_util.get_session_state( 'USER_TENANT' ))
AND SYSTEM_TYPE = 'OTHERS'
AND DEL_FLAG = 0
AND TENANT_ID = apex_util.get_session_state( 'USER_TENANT' );
END IF;
select APP_KEY, APP_SECRET
into app_key,app_secret
from TENANT_APP
where TENANT_ID = v_tenant_id
and IS_MANAGE = 1
and DEL_FLAG = 0
and ROWNUM = 1;
-- 获取租户名称
select NAME
into v_tenant_name
from TENANT
where TENANT_ID = v_tenant_id
and DEL_FLAG = 0
and ROWNUM = 1;
-- 获取当前角色ID和角色等级
select ROLE_ID, ROLE_LEVEL, IS_SYNC_USER
into v_basic_role_id,v_basic_role_level,v_is_sync_user
from (select role.ROLE_ID, role.ROLE_LEVEL, role.IS_SYNC_USER
from BASIC_SYSTEM_USER_ROLE u
inner join BASIC_SYSTEM_ROLE role
on u.ROLE_ID = role.ROLE_ID and role.TENANT_ID = u.TENANT_ID and
role.DEL_FLAG = 0
where u.LOGIN_USER_ID = v_basic_login_user_id
and role.SYSTEM_TYPE = 'BASIC'
and u.IS_ENABLE = 1 --账户“启用”的状态下
and u.TENANT_ID = v_tenant_id
order by role.ROLE_LEVEL desc)
where rownum = 1;
-- 获取当前角色所在的数据权限
select max( ORIGINAL_DEPT_ID ), max( PARENT_ORIGINAL_DEPT_ID )
into v_original_dept_id,v_parent_original_dept_id
from (select A.ORIGINAL_DEPT_ID, A.PARENT_ORIGINAL_DEPT_ID
from BASIC_SYSTEM_USER_ORIGINAL A
where A.LOGIN_USER_ID = v_basic_login_user_id
and A.ROLE_ID = v_basic_role_id
and SYSTEM_ID is null
and A.TENANT_ID = v_tenant_id
order by PARENT_ORIGINAL_DEPT_ID)
where rownum = 1;
-- 虚拟组织 上级ID
SELECT LISTAGG( DEPT_ID , ',' )
INTO V_PARENT_DEPT_ID
FROM BASIC_DEPT
WHERE (PARENT_DEPT_ID IS NULL or PARENT_DEPT_ID = 1)
AND DEL_FLAG = 0
AND TENANT_ID = v_tenant_id;
IF V_PARENT_DEPT_ID IS NULL THEN
V_PARENT_DEPT_ID := 1;
END IF;
apex_custom_auth.set_user( v_name );
apex_util.set_session_state( 'USER_ID' , v_user_id );
apex_util.set_session_state( 'BASIC_LOGIN_USER_ID' , v_basic_login_user_id );
apex_util.set_session_state( 'OTHERS_LOGIN_USER_ID' , V_OTHERS_LOGIN_USER_ID );
apex_util.set_session_state( 'USER_TENANT' , v_tenant_id );
apex_util.set_session_state( 'USER_TENANT_NAME' , v_tenant_name );
apex_util.set_session_state( 'USER_NAME' , v_name );
apex_util.set_session_state( 'USER_JOB_NUMBER' , v_job_number );
apex_util.set_session_state( 'USER_MOBILE' , v_mobile );
apex_util.set_session_state( 'APP_KEY' , app_key );
apex_util.set_session_state( 'APP_SECRET' , app_secret );
apex_util.set_session_state( 'API_URL' , 'http://gateway_test.ywjasolar.com' );
apex_util.set_session_state( 'BASIC_ROLE_ID' , v_basic_role_id );
apex_util.set_session_state( 'BASIC_ROLE_LEVEL' , v_basic_role_level );
apex_util.set_session_state( 'BASIC_ROLE_IS_SYNC_USER' , v_is_sync_user );
apex_util.set_session_state( 'USER_ORIGINAL_DEPT_ID' , v_original_dept_id );
apex_util.set_session_state( 'USER_PARENT_ORIGINAL_DEPT_ID' , v_parent_original_dept_id );
apex_util.set_session_state( 'BASIC_PARENT_DEPT_ID' , V_PARENT_DEPT_ID );
exception
when others then
v_err_msg := sqlerrm || chr( 13 ) || dbms_utility.format_error_backtrace;
JA_WRITE_LOG( JA_UTILS_PKG.GET_FN_NAME( ) , 'error' , v_err_msg , apex_util.get_session_state( 'USER_ID' ) ,
apex_util.get_session_state( 'USER_TENANT' ) , V( 'APP_NAME' ) || ':' || V( 'APP_ID' ) );
end ;
/
晶点登录函数 apex_app_auth_authentication
登陆后函数 LOGIN_SUCCESS_SAVE_USER
create function apex_app_auth_authentication (
p_username in varchar2,
p_password in varchar2 )
return boolean
as
t_job_number varchar2(20);
t_password varchar2(20);
t_count number(10);
T_TENANT NUMBER(10);
V_ERR_MSG varchar2(1000);
begin
--获取租户
T_TENANT := apex_util.get_session_state('P9999_USER_TENANT');
--查询用户是否在中台中存在
select count(1) into t_count from DIAN_SHARE_USER_V where upper(JOB_NUMBER) = upper(p_username) and IS_LEAVE = 0 AND TENANT_ID = T_TENANT;
--select count(*) into t_count from TENANT_EXT_USERS where MOBILE = upper(p_username) and IS_LEAVE = 0 and DEL_FLAG = 0;
--判断用户是否在中台中存在
if t_count > 0 then
--存在
--查询用户是否在用户表中存在
select count(1) into t_count from APEX_TENANT_USERS where JOB_NUMBER = upper(p_username) AND TENANT_ID = T_TENANT AND DEL_FLAG = 0;
--判断用户是否在用户表中存在
if t_count > 0 then
--存在
--查询该用户的工号和解密后的密码
select JOB_NUMBER,UTILS_PKG.DECRYPT_DEC(PASSWORD) into t_job_number,t_password
from APEX_TENANT_USERS
where JOB_NUMBER = upper(p_username)
AND TENANT_ID = T_TENANT
AND DEL_FLAG = 0;
else
-- insert into apex_tenant_users(ext_user_id,del_flag,tenant_id,sync_user_id,unionid,title,name,avatar,state_code,mobile,job_number,email,is_leave,leader_ext_user_id,hired_date,Is_Ext_User,LAST_SYNC_DATE)
-- select EXT_USER_ID,0,TENANT_ID,SYNC_USER_ID,UNION_ID,TITLE,NAME,AVATAR,STATE_CODE,MOBILE,JOB_NUMBER,EMAIL,IS_LEAVE,LEADER_EXT_USER_ID,HIRED_DATE,0,SYSDATE FROM DIAN_SHARE_USER_V WHERE JOB_NUMBER=upper(p_username) AND TENANT_ID = T_TENANT;
-- COMMIT;
-- --insert into APEX_TENANT_USERS select * from TENANT_EXT_USERS WHERE MOBILE = upper(p_username);
-- update APEX_TENANT_USERS set PASSWORD = UTILS_PKG.ENCRYPT_ENC('Aa123456') where JOB_NUMBER = upper(p_username) AND TENANT_ID = T_TENANT;
-- commit;
--
-- select JOB_NUMBER,UTILS_PKG.DECRYPT_DEC(PASSWORD) into t_job_number,t_password
-- from APEX_TENANT_USERS
-- where JOB_NUMBER = upper(p_username)
-- AND TENANT_ID = T_TENANT;
--不存在,提示“工号不存在”
apex_util.set_custom_auth_status(p_status => '工号不存在');
return false;
end if;
else
--不存在,提示“工号不存在”
apex_util.set_custom_auth_status(p_status => '工号不存在');
return false;
end if;
if (t_job_number is null or t_password is null) then
apex_util.set_custom_auth_status(p_status => '工号和密码不能为空');
return false;
else if p_password <> t_password then
apex_util.set_custom_auth_status(p_status => '工号或密码错误');
return false;
else if p_password = t_password then
return true;
end if;
end if;
end if;
return false;
EXCEPTION
WHEN OTHERS THEN
apex_error.add_error(
p_message => '非管理员不能登录,请联系管理员',
p_ignore_ora_error=> true,
p_display_location => apex_error.c_inline_in_notification);
V_ERR_MSG := SQLERRM || CHR(13) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ;
JA_WRITE_LOG(JA_UTILS_PKG.GET_FN_NAME(), 'error', V_ERR_MSG, -1, 2, '登录');
return false;
end;
/
create procedure LOGIN_SUCCESS_SAVE_USER
as
--登录验证后,保存用户基本信息与系统默认信息
v_userid number(20);
v_tenantid varchar2(10);
v_name varchar2(48);
v_job_number varchar2(10);
v_mobile varchar2(15);
v_app_key VARCHAR2(100);
v_app_secret VARCHAR2(100);
V_DEPT_ID VARCHAR2(100);
V_RULE_LEVEL NUMBER;
V_ERR_MSG VARCHAR2(1000);
begin
select EXT_USER_ID,
NAME,
JOB_NUMBER,
MOBILE,
TENANT_ID
into
v_userid,v_name,v_job_number,v_mobile,v_tenantid
from DIAN_SHARE_USER_V
where IS_LEAVE = 0
and JOB_NUMBER = upper(V('P9999_USERNAME'))
and TENANT_ID = V('P9999_USER_TENANT')
AND ROWNUM = 1;
SELECT ORIGINAL_DEPT_ID
INTO V_DEPT_ID
FROM DIAN_BASIC_DEPT_HIERARCHICAL_USER_V
WHERE TENANT_ID = v_tenantid
AND USER_ID = v_userid
AND ROWNUM = 1;
select APP_KEY, APP_SECRET
into v_app_key,v_app_secret
from DIAN_TENANT_APP
where TENANT_ID = v_tenantid
and DEL_FLAG = 0
and name = 'JING_DIAN'
and ROWNUM = 1;
apex_custom_auth.set_user(v_name);
apex_util.set_session_state('USER_ID', v_userid);
apex_util.set_session_state('DEPT_ID', V_DEPT_ID);
apex_util.set_session_state('USER_TENANT', v_tenantid);
apex_util.set_session_state('USER_NAME', v_name);
apex_util.set_session_state('USER_JOB_NUMBER', v_job_number);
apex_util.set_session_state('USER_MOBILE', v_mobile);
apex_util.set_session_state('APP_KEY', v_app_key);
apex_util.set_session_state('APP_SECRET', v_app_secret);
-- apex_util.set_session_state('API_URL', 'http://gateway_test.ywjasolar.com');
apex_util.set_session_state('API_URL', 'http://gateway_dev.ywjasolar.com.cn:19999');
EXCEPTION
WHEN OTHERS THEN
V_ERR_MSG := SQLERRM || CHR(13) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ;
WRITE_LOG(GET_FN_NAME(), 'ERROR', V_ERR_MSG, -1, v_tenantid);
end;
/
解决了一次选中多个用户的问题
declare
v_row_count number(10) := 1;
v_err_msg nvarchar2(2000);
/**
* create by: xiaoxian
* create date:2023/11/17 16:28
* modify by:
* modify date:
* describe:新增2.0(参考晶豹p247)
*/
begin
for c in (select USER_ID
from DIAN_BASIC_USER_V
where USER_ID in (
select *
from JA_UTILS_PKG.SPLIT_STR(:P35_USER_ID, ':')
))
loop
insert into BASIC_SYSTEM_USER_ROLE(USER_ID,ROLE_ID,REMARK,IS_ENABLE, TENANT_ID,
CREATED_BY, CREATION_DATE)
values (c.USER_ID,:P35_ROLE_ID,:P35_REMARK, 1, :USER_TENANT, :USER_ID, sysdate);
end loop;
apex_util.set_session_state('P35_ROW_COUNT', v_row_count);
exception
when others then
apex_util.set_session_state('P35_ROW_COUNT', 0);
v_err_msg := sqlerrm || chr(13) || dbms_utility.format_error_backtrace;
JA_WRITE_LOG('P' || :APP_PAGE_ID || '用户-角色管理-新增', 'ERROR', V_ERR_MSG, :USER_ID, :USER_TENANT,
:APP_NAME || ':' || :APP_ID);
end;
新的问题
晶点P38切换角色
Ajax 调用为Execute Server-Side Code返回了服务器错误ORA-06550: 第 46 行, 第 4 列:
PLS-00103: 出现符号 "end-of-file"在需要下列之一时:
(
begin case declare end exception exit for goto if loop mod
null pragma raise return select update while with
<an identifier> <a double-quoted delimited-identifier>
<a bind variable> << continue close current delete fetch lock
insert open rollback savepoint set sql execute commit forall
merge pipe purge json_exists json_value json_query
json_object json_array。
ROLE_ID可以被获取
P37 角色权限新增
Hiding error additional_info, as it contains ORA error message: ORA-01400: 无法将 NULL 插入 ("JING_DIAN"."BASIC_SYSTEM_ROLE_PERMISSION"."PERMISSION_ID")
是没获取到ROLE_PERMISSION_IDS吗?
ROLE_ID返回类型错误
【错误原因】本应是NUMBER类型的ROLE_ID变成了NVARCHAR类型的NAME
获取不到权限IDS
原因:
权限菜单ROLE_ID
动态权限
晶鱼 task_authentication
验证函数名 APEX_TASK_AUTHENTICATION
验证后过程名 LOGIN_SUCCESS_SAVE_USER_TASK_DEMO
权限分配函数 IS_HAVE_PERMISSION_TASK
create FUNCTION IS_HAVE_PERMISSION_TASK(P_USER_ID IN NUMBER,P_RULE_ID IN NUMBER, P_PAGE_ID IN NUMBER,P_TENANT_ID IN NUMBER)
RETURN BOOLEAN
IS
V_COUNT NUMBER;
BEGIN
-- WRITE_LOG(GET_FN_NAME(),'info',P_PAGE_ID,-1,P_TENANT_ID);
IF P_PAGE_ID = 1 THEN
RETURN TRUE;
END IF;
WITH SY1 AS
(SELECT A.USER_ID, A.RULE_ID, B.RULE_NAME, B.PERMISSION_RANGE, A.TENANT_ID
FROM TASK_APEX_USER_RULE A
LEFT JOIN TASK_APEX_RULE B
ON A.RULE_ID = B.RULE_ID
WHERE A.DEL_FLAG = 0
AND A.RULE_ID = P_RULE_ID
AND A.TENANT_ID = P_TENANT_ID
AND A.IS_ENABLE = 1
AND A.USER_ID = P_USER_ID)
SELECT COUNT(*)
INTO V_COUNT
FROM TABLE (SPLITSTR((SELECT PERMISSION_RANGE FROM SY1), ','))
WHERE COLUMN_VALUE = P_PAGE_ID;
IF V_COUNT > 0 THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN FALSE;
END;
/
【开发技巧】多值的获取与展示
需要借助函数Listagg(),可以帮助用户将多个列数据转换为一条数据记录,更加直观展示
【精选】Oracle列转行函数 Listagg()详解-CSDN博客https://blog.csdn.net/tianxingyun/article/details/116222199