我正在开发一个应用程序,用于跟踪Apex学校的学生上课情况.我想创建一个包含三级级联选择列表的页面,因此教师可以先选择学期,然后选择主题,然后选择该主题的特定类,以便应用程序返回已注册该类的学生.
我的问题是这三个表之间有多对多的关系,所以我使用额外的表和它们的键.每个学期都有许多科目,并且可以在许多学期教授科目.每个学期每个学科都有很多课程.学生必须每学期注册一个科目,然后教师可以将他们分配到一个班级.
表格看起来像这样:
create table semester(
  id number not null,
  name varchar2(20) not null,
  primary key(id)
);
create table subject(
  id number not null,
  subject_name varchar2(50) not null,
  primary key(id)
);
create table student(
  id number not null,
  name varchar2(20),
  primary key(id)
);
create table semester_subject(
  id number not null,
  semester_id number not null,
  subject_id number not null,
  primary key(id),
  foreign key(semester_id) references semester(id),
  foreign key(subject_id) references subject(id),
  constraint unique sem_sub_uq unique(semester_id, subject_id)
);
create table class(
  id number not null,
  name number not null,
  semester_subject_id number not null,
  primary key(id),
  foreign key(semester_subject_id) references semester_subject(id)
);
create table class_enrollment(
  id number not null,
  student_id number not null,
  semester_subject_id number not null,
  class_id number,
  primary_key(id),
  foreign key(student_id) references student(id),
  foreign key(semester_subject_id) references semester_subject(id),
  foreign key(class_id) references class(id)
);
学期选择列表的值列表如下所示:
select name, id
from semester
order by 1;
主题选择列表应包括上面选择的学期中可用的所有主题的名称,但我无法确定查询,即使它是可能的.我现在拥有的:
select s.name, s.id
from subject s, semester_subject ss
where ss.semester_id = :PX_SEMESTER //value from above select list
and ss.subject_id = s.id;
但是你不能在一个LoV中有两个表,而且查询可能是错的......我甚至没有开始考虑类的查询会是什么样子.
我感谢任何帮助,或者如果你能指出我正确的方向,那么我可以自己弄清楚.
您的初始架构设计看起来不错.一个建议,一旦您开发并测试了较小规模的解决方案,在ID(主键)列附加一个触发器,可以通过序列自动填充其值.您也可以跳过触发器,并在sql insert DML命令中引用序列.它只会让事情变得简单.使用内置向导在APEX环境中创建表可以创建"自动递增"键列.
还有一个额外的列添加到SEMESTER表中称为SORT_KEY.当您存储字符串类型的值时,这会有所帮助,这些值的逻辑排序顺序本质上不完全是字母数字.
以下是我生成的测试数据,用于演示与示例一起使用的级联值设计列表.

下一步是制作前三个相互依赖的值列表定义.正如您所发现的,您可以在LOV中引用可能来自各种来源的页面参数.在这种情况下,我们的LOV中的选择将被分配给Apex页面项目.
我还认为在单个LOV查询中只能引用一个表. 这是不正确的. 页面文档表明,SQL查询语法是限制因素.以下LOV查询引用了多个表,它们可以工作:
 -- SEMESTER LOV Query
 -- name: CHOOSE_SEMESTER
 select a.name d, a.id r
   from semester a
  where a.id in ( 
        select b.semester_id
          from semester_subject b
         where b.subject_id = nvl(:P5_SUBJECT, b.subject_id))
  order by a.sort_id
 -- SUBJECT LOV Query
 -- name: CHOOSE_SUBJECT     
 select a.subject_name d, a.id r
   from   subject a
  where  a.id in ( 
         select b.subject_id
           from semester_subject b
          where b.semester_id = nvl(:P5_SEMESTER, b.semester_id))
  order by 1
 -- CLASS LOV Query
 -- name: CHOOSE_CLASS
 select a.name d, a.id r
   from class a, semester_subject b
  where a.semester_subject_id = b.id
    and b.subject_id = :P5_SUBJECT
    and b.semester_id = :P5_SEMESTER
  order by 1
一些需要考虑的设计说明:
P5_ITEM符号.我的示例应用程序中的页面恰好位于"第5页",因此约定如此.NVL命令,如nvl(:P5_SUBJECT, b.subject_id)用于CHOOSE_SEMESTERLOV是镜像对的表达式CHOOSE_SUBJECT的查询,以及.如果在进入页面时默认值为P5_SUBJECT和P5_SEMESTERnull,那么它如何帮助处理级联关系?SEMESTER_SUBJECT代表了一种关键关系.  为什么不需要这张桌子的LOV?设置用于测试架构设计和LOV查询的页面需要创建三个页面项:
 
 
每个页面项目应定义为SELECT LIST最初保留所有默认值,直到您了解基本设计的工作方式.每个选择列表项应与其对应的LOV相关联,例如:

关键设计扭曲是为LOV 制作的选择列表CHOOSE_CLASS,它表示对多个数据源的级联依赖.  
我们将使用"分级父"选项,这样,这个项目将等待两个CHOOSE_SEMESTER和CHOOSE_SUBJECT选择.如果两者中的任何一个发生变化,它也会刷新.
 
 
是!级联父项可以包含多个页面项/元素.它们只需要以逗号分隔的列表声明.
从在线帮助信息,这是如何在APEX设计中使用级联LOV的一般介绍:
来自Oracle Apex帮助文档: 级联LOV意味着如果此页面上另一项的值发生更改,则应刷新当前项的值列表.
指定用于触发刷新的以逗号分隔的页面项列表.然后,您可以在"值列表"SQL语句的where子句中使用这些页面项.
这些示例基于此解决方案开头给出的示例数据.所选示例案例的路径是:
SEMESTER:2014年春季 + 主题:物理ED + 验证有效课程选项:
Run Code Online (Sandbox Code Playgroud)Fitness for Life General Flexibility Presidential Fitness Challenge Running for Fun Volleyball Basics
上面的选择将分配给页面项目P5_CLASS.
选择选择P5_SEMESTER:

选择选择P5_SUBJECT:

选择选择P5_CLASS:

在使用此设计项目时,我发现了一些结束的想法:
关于主键:主键   的通用ID命名列的概念是一个很好的设计选择.虽然APEX可以处理复合业务密钥,但它变得笨拙且难以解决.  
使架构设计难以理解的一件事是"id"的概念在引用它的其他表中转换.(例如表格中的ID列SEMESTER变成SEMESTER_ID了SEMESTER_SUBJECT表格.只要用更大的查询来关注这些名称的变化.有时我实际上完全失去了ID我正在使用的轨道.
Word for Sanity:   在您可能决定ID通过数据库序列对象分配值的情况下,默认值通常从1开始.如果模式中有多个不同的表具有相同的列名:ID并且某些关联表(例如CLASS_ENROLLMENT连接一个主键ID和三个附加外键的值)ID's,则可能难以辨别数据值的来源.
考虑抵消序列或任意选择不同的增量和起始值.如果您主要在查询中推送ID,如果两个不同的ID集分开两个或三个数量级,那么很容易知道您是否已经提取了正确的数据值.
是否有更多级联关系?  如果"父"项关系指示使页面项LOV根据另一个的值等待或更改的依赖关系,是否可以定义另一个级联关系?在的情况下,CHOOSE_SEMESTER和CHOOSE_SUBJECT这可能吗?有必要吗?
我能够弄清楚如何使这两个项目具有可选的级联依赖关系,但它需要设置另一个外部页面项目引用.(如果它不是可选的,只要两个值中的一个发生变化,就会陷入闭环状态.)很奇怪,但并不是真的有必要解决手头的问题.
还剩下什么?  我遗漏了一些额外的任务供您继续使用,例如ENROLLMENT在选择有效后将DML管理到表中STUDENT.   
总的来说,你有一个可行的架构设计.有一种方法可以通过APEX应用程序设计模式表示数据关系.编码愉快,看起来像一个具有挑战性的项目!