dbms_sqlパッケージを使用してcurosrループ内のレコードを移動する必要があるpl \ sqlプロシージャがあります。カーソルレコードを配列として使用する
カーソルクエリは動的なので、その列はわかりません。
だから、dbms_sql.define_columnsなどの関数を使用するたびに、私はall_tab_columnsのループで列名を取得します。
これは私のコードです:
procedure p is
SOURCE_CURSOR INTEGER;
destination_cursor INTEGER;
IGNORE INTEGER;
destination_cursor INTEGER;
v_stmt clob := empty_clob();
V_COLS_LIST varchar2(4000);
V_COLS_LIST2 varchar2(4000);
V_UPDATE_DATE_COL_NAME varchar2(30) := 'UPDATE_DATE_COL';
begin
-- going over all the records. each record is a table
for CURR_TABLE in (select * from mng_tables)
loop
-- get the column list for the current table
SELECT LISTAGG(CLS.COLUMN_NAME, ',') WITHIN GROUP (ORDER BY COLUMN_ID)
INTO V_COLS_LIST
FROM ALL_TAB_COLUMNS CLS
WHERE CLS.TABLE_NAME = CURR_TABLE.HISTORY_TABLE_NAME
AND CLS.OWNER = CURR_TABLE.HISTORY_TABLE_OWNER
AND CLS.COLUMN_NAME <> V_UPDATE_DATE_COL_NAME;
-- prepare the select from current table
v_stmt := 'select ' || V_COLS_LIST || ', SYSDATE' ||
' from ' || CURR_TABLE.TABLE_OWNER || '.' || CURR_TABLE.TABLE_NAME;
-- prepare the dynamic sql
-- get cursor id
source_cursor := dbms_sql.open_cursor;
-- parse cursor with query
DBMS_SQL.PARSE(SOURCE_CURSOR,V_STMT, DBMS_SQL.NATIVE);
-- going over all the columns of current table and define matching columns
FOR rec in (SELECT *
FROM ALL_TAB_COLUMNS
WHERE CLS.TABLE_NAME = CURR_TABLE.HISTORY_TABLE_NAME
AND CLS.OWNER = CURR_TABLE.HISTORY_TABLE_OWNER)
loop
DBMS_SQL.DEFINE_COLUMN(source_cursor, rec.column_id, rec.data_type);
end loop;
-- execute the select query
IGNORE := DBMS_SQL.EXECUTE(SOURCE_CURSOR);
-- define the destination cursor
destination_cursor := DBMS_SQL.OPEN_CURSOR;
select replace(V_COLS_LIST, ',' , ':,')
into V_COLS_LIST2
from dual;
-- parse the
DBMS_SQL.PARSE(destination_cursor,
'insert /*+ parallel(8) */ into ' || CURR_TABLE.HISTORY_TABLE_OWNER || '.' || CURR_TABLE.HISTORY_TABLE_NAME ||
'(' || V_COLS_LIST || ',' || V_UPDATE_DATE_COL_NAME || ')' ||
' values (:' || V_COLS_LIST2 || ',sysdate)',
DBMS_SQL.NATIVE);
LOOP
-- if there is a row
IF DBMS_SQL.FETCH_ROWS(source_cursor)>0 THEN
FOR rec in (SELECT *
FROM ALL_TAB_COLUMNS
WHERE CLS.TABLE_NAME = CURR_TABLE.HISTORY_TABLE_NAME
AND CLS.OWNER = CURR_TABLE.HISTORY_TABLE_OWNER)
loop
-- get column values of the row
DBMS_SQL.COLUMN_VALUE(source_cursor, rec.column_id, ???);
DBMS_SQL.BIND_VARIABLE(destination_cursor, ':' || rec.column_name, ???);
end loop;
ignore := DBMS_SQL.EXECUTE(destination_cursor);
ELSE
-- No more rows to copy:
EXIT;
END IF;
end loop;
end loop;
end p;
が、私は、変数をバインドするとき、私はちょうどbecuase私が動的に値を持つことができないことはできません。..
エンドで私がそれをしているときの手順:
DBMS_SQL.COLUMN_VALUE(source_cursor, rec.column_id, ???);
DBMS_SQL.BIND_VARIABLE(destination_cursor, ':' || rec.column_name, ???);
私はちょうど???を交換したいですか? "my_rec [rec.column_name]" または "my_rec [rec.column_id]"のようなものでこの列のレコードの値を取得します。
ありがとうございました。
私はインサートセレクトを使用しない理由がありますが、それは実際には些細なことです。私は発行したものを修正しました。元のコードを入れないと起こります。あなたのコードは私を助けました!どうもありがとう! – user2671057