Plsql 使用游标在循环中获取元组的PL/SQL过程
我正在尝试创建一个过程,从TableA中读取100个元组。对于从TableA检索到的每个元组,它还将使用student_ID索引从TableB检索相关元组,并将所需的属性添加到内存/记录中。具有新属性的元组将加载到数据仓库中。在加载之前,需要检查维度表是否已经包含该信息。如果是,那么它将只更新事实表,或者更新两个表。重复所有步骤,直到所有数据都加载到数据仓库中 下面是我正在构建的代码Plsql 使用游标在循环中获取元组的PL/SQL过程,plsql,tuples,cursor,fetch,procedure,Plsql,Tuples,Cursor,Fetch,Procedure,我正在尝试创建一个过程,从TableA中读取100个元组。对于从TableA检索到的每个元组,它还将使用student_ID索引从TableB检索相关元组,并将所需的属性添加到内存/记录中。具有新属性的元组将加载到数据仓库中。在加载之前,需要检查维度表是否已经包含该信息。如果是,那么它将只更新事实表,或者更新两个表。重复所有步骤,直到所有数据都加载到数据仓库中 下面是我正在构建的代码 CREATE OR REPLACE PROCEDURE PROJ AS
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;
/
这是您的代码,已修复。因为我没有你的表格,我自己无法编译 怎么了?以下代码中注释了多余的DECLARE和END循环:
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_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; --> this
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;