如何解决PL / SQL过程使用游标在循环中获取元组
我正在尝试创建一个将从TableA中读取100个元组的过程。对于从TableA检索到的每个元组,它还将使用student_ID索引从TableB检索相关的元组,并将所需的属性添加到内存/记录中。具有新属性的元组将被加载到数据仓库中。加载之前,需要检查维度表是否已包含该信息。如果是,那么它将仅更新事实表,否则将更新两个表。重复所有步骤,直到将所有数据加载到数据仓库中。
下面是我正在构建的代码。
CREATE OR REPLACE PROCEDURE PROJ AS
v_tab_rec varchar2 (100);
v_counter number (5);
v_student_id TableB.student_id%type;
v_studname TableB.studname%type;
v_address TableB.address%type;
v_coursename TableB.coursename%type;
DECLARE
CURSOR c_TableA IS
SELECT * FROM TableA;
v_tab_rec c_TableA%ROWTYPE;
BEGIN
OPEN c_TableA;
v_counter :=1;
WHILE (v_counter <= 500)
LOOP
FETCH c_TableA INTO v_tab_rec;
EXIT WHEN c_TableA%NOTFOUND;
SELECT * FROM v_tab_rec WHERE v_tab_rec.student_id = v_TableB.student_id;
IF v_tab_rec.student_id NOT IN (SELECT * FROM Student) THEN
INSERT INTO Student VALUES (v_tab_rec.student_ID,v_studname,v_address);
ELSIF v_tab_rec.course_id NOT IN (SELECT * FROM Course) THEN
INSERT INTO Course VALUES (v_tab_rec.course_id,v_coursename);
ELSIF v_tab_rec.subject_id NOT IN (SELECT * FROM Subject) THEN
INSERT INTO Subject VALUES (v_tab_rec.subject_id,v_tab_rec.subject_name);
END IF;
END LOOP;
END LOOP;
IF c_tableA%ISOPEN THEN
CLOSE c_tableA;
END IF;
COMMIT;
v_counter := v_counter +100;
END PROJ;
/
解决方法
您的过程充满了结构(编译时)和逻辑(运行时)错误。另外,您的代码似乎与描述不符;这本身就是令人困惑的。在下文中,我试图指出您程序中的结构性错误和一些注释。参见标记---
CREATE OR REPLACE PROCEDURE PROJ AS
v_tab_rec varchar2 (100);
v_counter number (5);
v_student_id TableB.student_id%type;
v_studname TableB.studname%type;
v_address TableB.address%type;
v_coursename TableB.coursename%type;
DECLARE
---<<< Declare. Not necessary,or you are sstarting a nested block
---<<< This is not an Error,but does have ramafacations later which
---<<< would generate an error.
CURSOR c_TableA IS
SELECT * FROM TableA;
v_tab_rec c_TableA%ROWTYPE;
---<<< v_ab_rec already defined as scalar variable
BEGIN
OPEN c_TableA;
v_counter :=1;
WHILE (v_counter <= 500)
---<<< Login: Above essentially createa an infinate loop
---<<< as v_counter only incremented AFTER loop is complete
---<<< so above condition will always remain true.
LOOP
FETCH c_TableA INTO v_tab_rec;
---<<< v_tab_rec duplicate definition as Cursor Row type AND Scalar
EXIT WHEN c_TableA%NOTFOUND;
SELECT * FROM v_tab_rec WHERE v_tab_rec.student_id = v_TableB.student_id;
---<<< v_tab_rec is NOT a table or view so cannot select from it
---<<< even if you could INTO clause missing from select. Required in PL/SQL.
---<<< v_TableB is undefined
IF v_tab_rec.student_id NOT IN (SELECT * FROM Student) THEN
---<<< The "Select *: is invalid as used but even if it were allowed
---<<< it retrieves all columns from student. You cannot compare
---<<< the scalar v_tab_rec.student_id to the row returned by the select.
INSERT INTO Student VALUES (v_tab_rec.student_ID,v_studname,v_address);
---<<< nor would the above select (if valid) populate the "v_" variables.
ELSIF v_tab_rec.course_id NOT IN (SELECT * FROM Course) THEN
---<<< Same problems as Student
INSERT INTO Course VALUES (v_tab_rec.course_id,v_coursename);
ELSIF v_tab_rec.subject_id NOT IN (SELECT * FROM Subject) THEN
---<<< Same problems as Student
INSERT INTO Subject VALUES (v_tab_rec.subject_id,v_tab_rec.subject_name);
END IF;
END LOOP;
END LOOP;
---<<< End second loop,however there is only 1 loop
IF c_tableA%ISOPEN THEN
CLOSE c_tableA;
END IF;
COMMIT;
v_counter := v_counter +100;
---<<< Why increment after the loop is complete (not an error,---<<< but serves no purpose
END PROJ;
---
“ If ... Elsif ... Elsif ... End if”允许3个表中的任何一个都不包含必要的ID。但是,当“学生”,“课程”和“主题”都缺少必要的ID时会发生什么。
描述令人困惑。 “从TableA中读取100个元组”然后在处理500行之后尝试退出的目的是什么?还不清楚“仅更新事实表,否则更新两个表”。什么是事实表(学生表,课程表和主题表?),但是“两个表”中的另一个表是什么? TableB的作用是什么?
,这是您的代码,已修复。由于我没有您的表,因此我无法自己编译它。
这是怎么了?多余的DECLARE
和END LOOP
(在下面的代码中进行了注释):
CREATE OR REPLACE PROCEDURE PROJ
AS
v_tab_rec VARCHAR2 (100);
v_counter NUMBER (5);
v_student_id TableB.student_id%TYPE;
v_studname TableB.studname%TYPE;
v_address TableB.address%TYPE;
v_coursename TableB.coursename%TYPE;
-- DECLARE --> this
CURSOR c_TableA
IS
SELECT * FROM TableA;
v_tab_rec c_TableA%ROWTYPE;
BEGIN
OPEN c_TableA;
v_counter := 1;
WHILE (v_counter <= 500)
LOOP
FETCH c_TableA INTO v_tab_rec;
EXIT WHEN c_TableA%NOTFOUND;
SELECT *
FROM v_tab_rec
WHERE v_tab_rec.student_id = v_TableB.student_id;
IF v_tab_rec.student_id NOT IN (SELECT * FROM Student)
THEN
INSERT INTO Student
VALUES (v_tab_rec.student_ID,v_address);
ELSIF v_tab_rec.course_id NOT IN (SELECT * FROM Course)
THEN
INSERT INTO Course
VALUES (v_tab_rec.course_id,v_coursename);
ELSIF v_tab_rec.subject_id NOT IN (SELECT * FROM Subject)
THEN
INSERT INTO Subject
VALUES (v_tab_rec.subject_id,v_tab_rec.subject_name);
END IF;
END LOOP;
--END LOOP; --> this
IF c_tableA%ISOPEN
THEN
CLOSE c_tableA;
END IF;
COMMIT;
v_counter := v_counter + 100;
END PROJ;
/
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。