数据库表设计
代码实现之前首先是表设计,
六个基本步骤
1.需求分析 (分析用户需求,包括数据、功能和性能需求)
2.概念结构设计(主要采用 E-R图)
3.逻辑结构设计 (将ER图转换成表,实现从E-R模型到关系模型转换)
4.数据库物理设计 (为设计的数据库选择合适的存储结构和存取路径)
5.数据库的实施(包括编程 测试和试运行)
6.数据库运行与维护
三大范式
1.确保每列原子性,即不可再分 ;
2.确保每列都与主键相关;
3.确保每列都和主键直接相关,而不是间接相关
表设计
涉及到的表有用户表(USER_TEST_WXX)、部门表(DEPT_TEST_WXX2)、用户部门中间表(DEPT_USER__TEST_WXX)、角色表(ROLE__TEST_WXX)、用户角色中间表(ROLE_USER_TEST_WXX)、权限表permission(PERM__TEST_WXX)、角色权限中间表(PERM_USER_TEST_WXX),共计四张实体表,三张中间表。
关系
一个用户属于一个部门
一个用户拥有一个角色
一个角色有多个操作权限
一个操作权限可以属于多个角色
一个角色可以分配给多个用户
一个部门下有多个用户
ER图
画出来的ER图如下:
涉及的简单字段有
创建新表
-- 创建部门表
create table DEPT_TEST_WXX2
(
-- 主键自增generated by default as identity primary key
DEPT_ID NUMBER generated by default as identity primary key not null,
NAME NVARCHAR2(64) not null,
DESCRIBE NVARCHAR2(256),
CREATE_DATE DATE,
UPDATE_DATE DATE
);
-- 创建角色表
create table ROLE_TEST_WXX
(
-- 主键自增generated by default as identity primary key
ROLE_ID NUMBER generated by default as identity primary key not null,
NAME NVARCHAR2(64) not null,
DESCRIBE NVARCHAR2(256),
UPDATE_DATE DATE
);
-- 创建用户角色表(中间表)
create table ROLE_USER_TEST_WXX
(
-- 主键自增generated by default as identity primary key
ROLE_USER_ID NUMBER generated by default as identity primary key not null,
ROLE_ID NUMBER not null,
USER_ID NUMBER not null,
REMARK NVARCHAR2(256),
UPDATE_DATE DATE
);
-- 创建权限表
create table PERM_TEST_WXX
(
-- 主键自增generated by default as identity primary key
PREM_ID NUMBER generated by default as identity primary key not null,
NAME NVARCHAR2(64) not null,
DESCRIBE NVARCHAR2(256),
UPDATE_DATE DATE
);
-- 创建角色权限表(中间表)
create table ROLE_PERM_TEST_WXX
(
-- 主键自增generated by default as identity primary key
ROLE_PERM_ID NUMBER generated by default as identity primary key not null,
ROLE_ID NUMBER not null,
PERM_ID NUMBER not null,
REMARK NVARCHAR2(64),
UPDATE_DATE DATE
);
现在是新创建的表引入
角色信息交互式网格
注意!!!
1. 创建好交互式网格之后记得导入工具包url,后续行选中用得到
2.关闭“值受保护”,便于后续操作,否则会出现新增/修改无法执行
新增、修改用到的空白页创建
3.点击修改因为要传入选中id,所以要有客户端条件
!utils.checkNull($v('P7_ROLE_ID')) && $v('P7_ROLE_ID').split(',').length == 1
4.如果为真,则将角色网格选中的id传到表单进行修改,这一步是传递id
5.有了真操作,还有假操作,不满足哦情况则为假
P7角色删除执行的PL/SQL代码
declare
V_COUNT number(18) := 0;
begin
-- 删除关联的用户角色数据
DELETE ROLE_USER_TEST_WXX WHERE ROLE_ID IN(SELECT * FROM TABLE(SPLITSTR(:P7_ROLE_ID,',')));
--删除角色数据
DELETE ROLE_TEST_WXX WHERE ROLE_ID IN(SELECT * FROM TABLE(SPLITSTR(:P7_ROLE_ID,',')));
V_COUNT:= SQL%ROWCOUNT;
APEX_UTIL.SET_SESSION_STATE('P7_ROW_COUNT',V_COUNT);
end;
6.记得提交输入项和返回项!!!
处理→ 处理之后→ 转到对应表单 → 行为→ 类型 重定向→ 目标 13,还设置了项,将id绑定
便于后续操作。
角色表单
1.新建P13_ROW_COUNT,记得关闭“值受保护”
执行修改的代码
declare
v_row_count number(10) := 0;
begin
update ROLE_TEST_WXX set NAME = :P13_NAME,
DESCRIBE =:P13_DESCRIBE,
UPDATE_DATE = sysdate
where ROLE_ID = :P13_ROLE_ID;
v_row_count := SQL%ROWCOUNT;
apex_util.set_session_state('P13_ROW_COUNT',v_row_count);
end;
提交的项:P13_ROLE_ID、P13_NAME、P13_DESCRIBE
返回的项:P13_ROW_COUNT
权限信息交互式网格
创建网格和表单
【错误记录】PL/SQL: ORA-00904: "PERM_ID": 标识符无效
在执行点击删除时pl/sql代码报错
ORA-06550: 第 7 行, 第 32 列: PL/SQL: ORA-00904: "PERM_ID": 标识符无效
解决方法
1、表名写错了,仔细检查核对一下表。
2、字段名写错了,仔细检查核对一下表。
3、表中无该字段,仔细检查核对一下表。
4、字段包含了Oracle的关键字,把报错的字段用单引号括起来试试
后续
经检验1.2.3皆正确,于是在“PERM_ID”加上单引号试试,可以了(双引号也试过,不行)
展现出来是这样的
啊?交互式网格怎么变表单了?
为了一探究竟重新建了一个,这次不带表单
【错误记录】行选中失败
查看了一下,居然是字段PERM_ID写错成PREM_ID,破案了终于
怪不得之前关键字报错,重新全改了
declare
V_COUNT number(18) := 0;
begin
-- 删除关联的角色权限数据
DELETE ROLE_PERM_TEST_WXX WHERE PREM_ID IN(SELECT * FROM TABLE(SPLITSTR(:P18_PREM_ID,',')));
--删除权限数据
DELETE PERM_TEST_WXX WHERE PREM_ID IN(SELECT * FROM TABLE(SPLITSTR(:P18_PREM_ID,',')));
V_COUNT:= SQL%ROWCOUNT;
APEX_UTIL.SET_SESSION_STATE('P18_ROW_COUNT',V_COUNT);
end;
改过来以后会报错
【错误记录】PL/SQL: ORA-00904: "PREM_ID": 标识符无效
Ajax 调用为Execute Server-Side Code返回了服务器错误ORA-06550: 第 5 行, 第 37 列:
PL/SQL: ORA-00904: "PREM_ID": 标识符无效。
找到了,中间表又是对的PERM_ID,盖亚!!!
我真想给粗心的自己两巴掌
正确的pl/sql如下
declare
V_COUNT number(18) := 0;
begin
-- 删除关联的角色权限数据
DELETE ROLE_PERM_TEST_WXX WHERE PERM_ID IN(SELECT * FROM TABLE(SPLITSTR(:P18_PREM_ID,',')));
--删除权限数据
DELETE PERM_TEST_WXX WHERE PREM_ID IN(SELECT * FROM TABLE(SPLITSTR(:P18_PREM_ID,',')));
V_COUNT:= SQL%ROWCOUNT;
APEX_UTIL.SET_SESSION_STATE('P18_ROW_COUNT',V_COUNT);
end;