带有过程和触发器的 PL/SQL 任务

我目前正在学习 PL/SQL,有一些任务需要解决,但不知道如何去做。 我有以下表格:

create table Student (
  id_stud number (10) not null,name varchar2 (30),PRIMARY KEY (id_stud)
);

create table lecture (
  id_l number (10) not null,titel varchar2 (40),PRIMARY KEY (id_l)
);

create table seminar (
  id_seminar number (10) not null,description varchar2 (30),id_l number (10) not null,PRIMARY KEY (id_seminar),FOREIGN KEY (id_l) REFERENCES lecture (id_l)
);

create Table participate_student_lecture(
  id_stud number (10) not null,PRIMARY KEY (id_stud,id_l ),FOREIGN KEY (id_stud ) REFERENCES Student(id_stud ),FOREIGN KEY (id_l ) REFERENCES lecture(id_l )
);

create table participate_student_seminar (
  id_stud number (10) not null,id_seminar number (10) not null,id_seminar ),FOREIGN KEY (id_seminar ) REFERENCES seminar(id_seminar )
);

以及以下任务:

  • 一个程序应该删除讲座和相关的研讨会。只有在讲座或研讨会中没有学生注册的情况下才有可能。如果讲座无法删除,则应抛出一条消息。

  • 程序应该删除研讨会,但前提是该研讨会没有注册学生。

  • 当学生注册研讨会时,学生也应自动注册相应的讲座。 -> 用触发器解决

  • 如果一个讲座有多个研讨会(一个讲座可以有 1-3 个研讨会),它们应该相等。这意味着学生应该轮流分配到研讨会。 (学生 1 研讨会 1,学生 2 研讨会 2,学生 3 研讨会 3,学生 4 研讨会 1) -> 用触发器解决

您是否有一些解决方案或至少一些提示?

非常感谢!!!

sanxiah1236 回答:带有过程和触发器的 PL/SQL 任务

我会看看我是否可以为您指出正确的方向,并提供一些基本建议。首先,不是直接相关,而是我强调的一点:开始养成良好习惯的时候是在学习的时候。这里有几个例子:

  1. 使用描述性名称。这在这里基本不错,但是id_l?这真的是描述性的吗?也许这里有 4 张桌子,但 40 或 400 张桌子怎么样。
  2. 花时间为您的约束命名。如果您不使用 Oracle 会,但我向您保证,您不想使用 Oracle 生成的名称;参见 Example1Example2。除了命名约束之外,它们是相同的。查看最后一条语句和错误消息。您更愿意追踪其中的哪一个。 (忽略以 `FIDDLE_... 开头的部分直到单点 (.) 分隔符。这是 dbfiddle 生成的架构名称,您将看到拥有约束的架构名称。)
  3. 让您的程序尽可能简单以完成单个任务。

现在直接解决您的问题:
您的前两个要点由上面的示例处理。在那里,我刚刚更改了 seminar to lecture 上的 FK 以包含 on delete cascade 。这会导致 Oracle 尝试删除与指定的 Seminar 关联的所有 lecture。不要将 FK 从 participate_student_seminarseminar 的删除级联。现在当 Oracle 尝试删除一个类似的有参与的学生时,FK 会导致异常(删除是直接删除还是从讲座中级联的结果。

你的第三点是变化最剧烈的一点。它说用触发器解决,我希望这是您的想法而不是要求。这是一个非常糟糕的解决方案。我会假设这不是必需的。我的解决方案什么都不做,至少在运行时是这样。它完全可以通过连接 participate_student_seminar and and and seminar 推导出来。因此删除表 participate_student_lecture 并将其重新创建为 VIEW。 Example3

您的最后一点(也希望不需要触发器)。将是最困难的。跟踪循环分配通常需要跟踪最后分配的。但即便如此,也不一定能达到“均等填充”的目的。似乎允许学生注册特定的研讨会(第 3 点)。那么当有几个人要求参加相同的研讨会时会发生什么。也许更好的方法是计算注册人数并将分配给人数最少的人。尽管没有将学生 1 分配给研讨会 1,将学生 2 分配给研讨会 2,但这更接近目标......类似:

insert into participate_student_seminar_3( id_student,id_seminar)
select &student_id,id_seminar
  from (select ls.id_seminar,count(*)  
          from  participate_student_seminar_3 pss
          join  seminar_3 ls on(pss.id_seminar = ls.id_seminar) 
         where  ls.id_lecture = &lecture_id
         group by  ls.id_seminar
         order by  count(*),ls.id_seminar   
        ) 
 fetch first 1 row only;

我会让你把它完全放入程序中。提示:不要只尝试一个程序。是的,它可以完成,但是该过程有多个任务要执行。至少使用 2 插入另一个删除。删除应该很简单。如果您有问题,请告诉我,并可以向我展示一些代码,以表明您的具体问题。

本文链接:https://www.f2er.com/10022.html

大家都在问