【问题标题】:Inserting data following cursor creation with restricted selection oracle使用受限选择 oracle 创建光标后插入数据
【发布时间】:2019-07-02 01:42:06
【问题描述】:

这是我第一次在 Stack Overflow 上发帖。我通常只是搜索以前的问题并找到我的答案,但在这种情况下,我似乎无法在这里或更广泛的互联网上找到我的问题的答案。

我遇到的问题是我想填充一个用于自动存储考勤的多对多链接表。当新学生添加到课程中时,学生 StudentNo 和每个适用的 Lesson's LessonNo 将作为主键输入到链接表中。此外,学生的考勤代码将自动设置为“T”,以表明考勤有待确认。

我不希望这是一个程序,因为数据库预计有超过 6,000 个活跃的 studentNo 条目,每个学生都有超过 100 节课。只有家庭学生(他们的定义,不是我的)上大学。 homeStudent 主键与整个学生主键相同。

我的触发器如下:

CREATE OR REPLACE TRIGGER Student_Added_to_Course
AFTER INSERT ON HomeStudent
FOR EACH ROW
DECLARE 
CURSOR applicable_lessons
IS
   Select Student.studentNo, Lesson.LessonNo
   FROM
   Student, Lesson, Course, Module
   WHERE
   Student.StudentNo = :new.studentNo
   AND
   Student.CourseNo = Course.CourseNo
   AND
   Course.CourseNo = Module.CourseNo
   AND
   Lesson.ModuleNo = Module.ModuleNo;
BEGIN
 FOR I IN applicable_lessons
 LOOP
 INSERT INTO Attendance (StudentNo, LessonNo, AttendanceCode)
 VALUES (I.student.studentNo, I.Lesson.LessonNo, 'T');
  END LOOP;
END;
/

我收到以下错误:

第 18 行:忽略 SQL 语句 第 19 行:必须声明组件“课程” 第 19 行:此处不允许列

由于我所有的错误都是从第 18 行开始发生的,我假设我在插入循环期间犯了一个错误?

谁能告诉我我在这里做错了什么。我认为解决方法相当简单,但我对自己的工作有点眼花缭乱,找不到问题所在。

提前谢谢你, 鲍布雷克

【问题讨论】:

    标签: oracle plsql oracle11g database-trigger


    【解决方案1】:

    当您只能执行单个插入语句时,为什么要循环游标?这样会更快!

    例如:

    CREATE OR REPLACE TRIGGER Student_Added_to_Course
    AFTER INSERT ON HomeStudent
    FOR EACH ROW
    BEGIN
    
      INSERT INTO attendance (studentno, lessonno, attendancecode)
      SELECT s.studentno,
             l.lessonno,
             'T'
      FROM   student s
             INNER JOIN course c ON s.courseno = c.courseno
             INNER JOIN module m ON c.courseno = m.courseno
             INNER JOIN lesson l ON m.moduleno = l.moduleno
      WHERE  s.studentno = :new.studentno;
    
    END Student_Added_to_Course;
    /
    

    请注意,我已将您的连接语法更改为使用 ANSI 连接语法,并注意如何更容易查看表的链接方式。

    【讨论】:

    • 老实说,我通常不从事数据库工作,并且在过去几周内我不得不学习基本的 oracle。我查看了批量收集以尝试执行您刚刚向我展示的内容,但看起来我根据您的代码的优雅程度让事情变得过于复杂。不过这真的很有趣,我会好好利用它的!
    • 值得花一些时间学习一下 SQL,IMO。一般来说,如果您可以在单个 SQL 语句中执行某项操作,那么您应该这样做,并且只有在无法执行的情况下才进入过程 PL/SQL。通过使用单个 SQL 语句,您减少了 SQL 和 PL/SQL 引擎之间的上下文切换和数据移动,这意味着大部分工作由 SQL 引擎一次性完成,而 PL/SQL 的参与最少SQL 引擎。
    • P.S.如果你要搜索这种类型的东西,它被称为“基于集合的思维”而不是“程序思维”
    【解决方案2】:

    如果您将INSERT 语句更改为

    INSERT INTO Attendance (StudentNo, LessonNo, AttendanceCode)
    VALUES (I.studentNo, I.LessonNo, 'T');
    

    你应该很好。

    因为,游标变量是i,并且游标选择studentnolessonno列;它们属于哪个表并不重要(不再重要) - 您可以通过游标变量的名称引用它们,即 i.studentnoi.lesonno

    【讨论】:

    • 非常感谢。这立即解决了我的问题!
    猜你喜欢
    • 2019-10-20
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 2020-08-17
    相关资源
    最近更新 更多