11gR2 より前のバージョンの Oracle では、BULK COLLECT を使用してレコードのコレクション (ネストしたテーブルまたは VARRAY) を作成するように制限されていました。詳細については、Oracle Docs を参照してください。
11gR2でどのように行われるかを確認したい場合は、この回答のEDIT 2セクションまでスクロールしてください。
これに代わる方法は、列ごとに個別のコレクションを使用することです。これは、最も広く使用されているアプローチです。これには、次のものがあります。
/*
TYPE some_type IS RECORD (
row_id ROWID,
full_row table_name%ROWTYPE
);
TYPE some_type_list IS TABLE OF some_type
INDEX BY BINARY_INTEGER;
-- */
CREATE TYPE t_row_id IS TABLE OF ROWID;
CREATE TYPE t_col1 IS TABLE OF table_name.col1%TYPE;
CREATE TYPE t_col2 IS TABLE OF table_name.col2%TYPE;
CREATE TYPE t_col3 IS TABLE OF table_name.col3%TYPE;
...
...
CREATE TYPE t_colN IS TABLE OF table_name.colN%TYPE;
PROCEDURE do_stuff
IS
lc_data SYS_REFCURSOR;
-- lt_recs some_type_list;
row_id t_row_id;
col1 t_col1;
col2 t_col2;
col3 t_col3;
...
...
colN t_colN;
BEGIN
OPEN lc_date FOR
SELECT rowid, a.*
FROM table_name;
LOOP
FETCH lc_data
BULK COLLECT INTO row_id, col1, col2, col3, ..., colN
LIMIT 50000;
EXIT WHEN lt_recs.COUNT = 0;
--
FORALL i IN row_id.FIRST..row_id.LAST
DELETE table_name
WHERE ROWID = row_id(i);
--
FORALL i IN col1.FIRST..col1.LAST
INSERT INTO table_name_audit VALUES (col1(i), col2(i), col3(i), ..., colN(i));
END LOOP;
END;
変更点を理解していただくために、プログラムの行の多くを削除していません。
編集:上記のOracle Docsリンクの「BULK COLLECTの制限」セクションと、こちらも参照してください。
編集#2:
CREATE TYPE ... IS OBJECT
の代わりに使用する必要がありRECORD
ます。SELECT
また、私が試したときに行った方法でステートメントを変更する必要があります。詳細については、こちらの Oracle ドキュメントとこちらの StackOverflow の質問をご覧ください。
私のマシン(Oracle 11g R2を実行)で試したコードは次のとおりです。
-- SELECT * FROM user_objects WHERE object_type = 'TYPE'; クリアスクリーン; SERVEROUTPUT をオンに設定します。
CREATE OR REPLACE TYPE temp_t_test AS OBJECT ( -- << OBJECT, not RECORD.
test_id INTEGER
, test_val VARCHAR2(50)
);
/
CREATE OR REPLACE TYPE temp_tbl_test AS TABLE OF TEMP_T_TEST;
/
DECLARE
v_test TEMP_TBL_TEST;
BEGIN
SELECT temp_t_test(t_id, t_val) -- << Notice the syntax
-- I'm selecting the columns as the defined OBJECT type.
BULK COLLECT INTO v_test
FROM (SELECT 1 AS t_id, 'ABCD' AS t_val FROM dual
UNION ALL
SELECT 2, 'WXYZ' FROM dual
UNION ALL
SELECT 3, 'PQRS' FROM dual);
dbms_output.put_line('Bulk Collect Successful!');
END;
/
** 出力 **:
TYPE temp_t_test compiled
TYPE temp_tbl_test compiled
anonymous block completed
Bulk Collect Successful!