CREATE TABLE T1 (EMP_NAME VARCHAR2 (40));
INSERT INTO t1
VALUES ('Vinoth');
COMMIT;
CREATE TABLE T2 (EMP_NAME VARCHAR2 (40));
CREATE OR REPLACE PACKAGE TEST_PKG_V
AS
PROCEDURE P_MAIN (p_status OUT VARCHAR2);
TYPE T1_TYPE IS RECORD (EMP_NAME T1.EMP_NAME%TYPE);
TYPE T1_TBL IS TABLE OF T1_TYPE;
END TEST_PKG_V;
/
CREATE OR REPLACE PACKAGE BODY TEST_PKG_V
AS
PROCEDURE P_MAIN (p_status OUT VARCHAR2)
IS
LV_T1_TBL T1_TBL := T1_TBL ();
CURSOR T1_CUR
IS
(SELECT EMP_NAME FROM t1);
BEGIN
OPEN T1_CUR;
LOOP
FETCH T1_CUR
BULK COLLECT INTO LV_T1_TBL
LIMIT 10000;
INSERT INTO t2 (EMP_NAME)
SELECT EMP_NAME FROM TABLE (LV_T1_TBL);
EXIT WHEN T1_CUR%NOTFOUND;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
p_status := 'FAIL';
RAISE;
END P_MAIN;
END TEST_PKG_V;
/
DECLARE
VAR VARCHAR2(4000);
BEGIN
TEST_PKG_V.P_MAIN(VAR);
END;
执行该过程时会抛出ORA-00902:无效的数据类型。 如果我在过程中注释掉insert语句,它运行得很好。这有什么问题,帮助我解决问题。
答案 0 :(得分:0)
为了能够像这样做,必须在包外创建类型。这是更正后的版本。如果你改变你的表来改变列的类型,那么下行是创建的类型,你可能会忘记修改类型。
CREATE TYPE T1_TYPE AS OBJECT ( EMP_NAME VARCHAR2(40));
CREATE TYPE T1_TBL AS TABLE OF T1_TYPE;
CREATE OR REPLACE PACKAGE TEST_PKG_V
AS
PROCEDURE P_MAIN (p_status OUT VARCHAR2);
END TEST_PKG_V;
/
CREATE OR REPLACE PACKAGE BODY TEST_PKG_V
AS
PROCEDURE P_MAIN (p_status OUT VARCHAR2)
IS
LV_T1_TBL T1_TBL;
CURSOR T1_CUR
IS
(SELECT T1_TYPE(EMP_NAME) EMP_NAME FROM t1);
BEGIN
OPEN T1_CUR;
LOOP
FETCH T1_CUR
BULK COLLECT INTO LV_T1_TBL
LIMIT 10000;
INSERT INTO t2 (EMP_NAME)
SELECT EMP_NAME FROM TABLE (LV_T1_TBL);
EXIT WHEN T1_CUR%NOTFOUND;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
p_status := 'FAIL';
RAISE;
END P_MAIN;
END TEST_PKG_V;
/
如果您希望您的类型是通用的并适应您的桌子,我认为您必须这样做:
CREATE OR REPLACE PACKAGE TEST_PKG_V AS
TYPE T1_TYPE IS RECORD (EMP_NAME T1.EMP_NAME%TYPE);
TYPE T1_TBL IS TABLE OF T1_TYPE;
PROCEDURE P_MAIN (p_status OUT VARCHAR2);
FUNCTION GET_T1 RETURN T1_TBL PIPELINED;
END TEST_PKG_V;
/
CREATE OR REPLACE PACKAGE BODY TEST_PKG_V IS
CURSOR T1_CUR IS (SELECT EMP_NAME FROM t1);
FUNCTION GET_T1 RETURN T1_TBL PIPELINED IS
LV_T1_TBL T1_TBL;
BEGIN
OPEN T1_CUR;
FETCH T1_CUR BULK COLLECT INTO LV_T1_TBL;
CLOSE T1_CUR;
FOR IDX IN 1..LV_T1_TBL.COUNT LOOP
PIPE ROW (LV_T1_TBL(IDX));
END LOOP;
END;
PROCEDURE P_MAIN (p_status OUT VARCHAR2) IS
BEGIN
INSERT INTO t2 (EMP_NAME) SELECT EMP_NAME FROM TABLE (GET_T1);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_status := 'FAIL';
RAISE;
END P_MAIN;
END TEST_PKG_V;
/
或者,您可以通过直接迭代光标来实现:
CREATE OR REPLACE PACKAGE TEST_PKG_V AS
TYPE T1_TYPE IS RECORD (EMP_NAME T1.EMP_NAME%TYPE);
TYPE T1_TBL IS TABLE OF T1_TYPE;
PROCEDURE P_MAIN (p_status OUT VARCHAR2);
END TEST_PKG_V;
/
CREATE OR REPLACE PACKAGE BODY TEST_PKG_V IS
PROCEDURE P_MAIN (p_status OUT VARCHAR2) IS
CURSOR T1_CUR IS (SELECT EMP_NAME FROM t1);
BEGIN
FOR CURRENT_ROW IN T1_CUR LOOP
INSERT INTO t2 (EMP_NAME) VALUES (CURRENT_ROW.EMP_NAME);
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_status := 'FAIL';
RAISE;
END P_MAIN;
END TEST_PKG_V;
/