問題描述:需要把遊標中查詢到的數據批量插入到表中
創建如下表結構:
-- Create table
CREATE table CUX.CUX_GL_AR_REV_REPT
( group_id NUMBER,
ledger_id NUMBER,
ledger_name VARCHAR2(50),
period_name VARCHAR2(50),
segment1 NUMBER,
company_name VARCHAR2(50),
segment3 NUMBER,
account_name VARCHAR2(50),
channel_name VARCHAR2(50),
currency_code VARCHAR2(10),
gl_fms_amount NUMBER,
gl_ar_amount NUMBER,
ims_ar_amount NUMBER,
ims_gl_amount NUMBER,
amount_difference NUMBER
);
CREATE SYNONYM CUX_GL_AR_REV_REPT FOR cux.CUX_GL_AR_REV_REPT;
-- Create/Recreate indexes
CREATE INDEX CUX.CUX_GL_AR_REV_REPT_U1 ON CUX.CUX_GL_AR_REV_REPT (GROUP_ID);
獲取數據的遊標如下:
--1.2. GL-AR-IMS金額數據
CURSOR cursor_gl_ar_data IS
SELECT l_group_id,
gl.ledger_id, --帳套ID
gl.name, --帳套
gjh.period_name period_name, --期間
gcc.segment1 segment1, --公司段
com_val.description company_name,
gcc.segment3 segment3, --科目段
acc_val.description account_name,
chan_val.description chanel_name, --渠道值
gjh.currency_code currency_code, --幣種
SUM(nvl(gjl.entered_dr, 0) - nvl(gjl.entered_cr, 0)) amount --金額
FROM gl_je_headers gjh, --憑證頭
gl_je_lines gjl, --憑證行
gl_import_references gi,
xla_ae_headers xah,
xla_ae_lines xal,
xla.xla_transaction_entities xte,
gl_code_combinations gcc,
fnd_flex_values_vl com_val,
fnd_flex_value_sets com_vs,
fnd_flex_values_vl acc_val,
fnd_flex_value_sets acc_vs,
fnd_flex_values_vl chan_val,
fnd_flex_value_sets chan_vs,
ra_customer_trx_all rcta, --應收發票
ra_batch_sources_all bs,
gl_ledgers gl,
cux_all_org_information_v cao
WHERE gjh.je_header_id = gjl.je_header_id
AND gjh.je_source = 'Receivables'
AND gjl.je_header_id = gi.je_header_id
AND gjl.je_line_num = gi.je_line_num
AND gi.gl_sl_link_id = xal.gl_sl_link_id
AND gi.gl_sl_link_table = xal.gl_sl_link_table
AND xah.ae_header_id = xal.ae_header_id
AND gjl.code_combination_id = gcc.code_combination_id
AND xte.entity_code = 'TRANSACTIONS'
AND xah.entity_id = xte.entity_id
AND xah.application_id = xte.application_id
AND rcta.customer_trx_id = xte.source_id_int_1
AND xah.application_id = 222
AND rcta.attribute3 IS NOT NULL
AND gcc.summary_flag = 'N'
AND gcc.segment1 = com_val.flex_value
AND com_val.flex_value_set_id = com_vs.flex_value_set_id
AND com_vs.flex_value_set_name = 'TENCENT_COMPANY'
AND gcc.segment3 = acc_val.flex_value
AND acc_val.flex_value_set_id = acc_vs.flex_value_set_id
AND acc_vs.flex_value_set_name = 'TENCENT_ACCOUNT'
AND gcc.segment7 = chan_val.flex_value
AND chan_val.flex_value_set_id = chan_vs.flex_value_set_id
AND chan_vs.flex_value_set_name = 'TENCENT_CHANNEL'
AND (gcc.segment3 LIKE '1131%' --應收帳款
OR gcc.segment3 LIKE '2162%' --遞延收益
OR gcc.segment3 LIKE '5101%' --主營業務收入
OR gcc.segment3 LIKE '5301%' --營業外收入
OR gcc.segment3 LIKE '5102%' --其他業務收入
OR gcc.segment3 IN ('21210600', '21710110', '21710113', '21710114', '21710115'))
AND gcc.chart_of_accounts_id = gl.chart_of_accounts_id
AND gjh.ledger_id = gl.ledger_id
AND rcta.batch_source_id = bs.batch_source_id
AND rcta.org_id = bs.org_id
AND cao.org_id = rcta.org_id
AND gjh.status = 'P' --已過賬
AND (l_org_id IS NULL OR gcc.segment1 = l_org_id) --102 參數
AND gjh.period_name = p_period_name --'2007-07' 參數
AND (p_currency_code IS NULL OR gjh.currency_code = p_currency_code) --參數幣種,如CYN
AND (p_account_code IS NULL OR gcc.segment3 = p_account_code) --參數科目
AND sign(instr(bs.name, 'IMS系統')) = '1' --來自IMS
GROUP BY bs.name,
gl.ledger_id,
gl.name,
gjh.period_name,
gcc.segment1,
gcc.segment3,
gcc.segment7,
com_val.description,
acc_val.description,
chan_val.description,
gjh.currency_code;
方法1:定義一個記錄類型
l_gl_ar_row_num NUMBER;
--定義一個記錄類型,用於臨時存放要插入到臨時表的數據
TYPE tempt_record_type IS RECORD(
group_id NUMBER,
ledger_id NUMBER,
ledger_name VARCHAR2(50),
period_name VARCHAR2(50),
segment1 NUMBER,
company_name VARCHAR2(50),
segment3 NUMBER,
account_name VARCHAR2(50),
channel_name VARCHAR2(50),
currency_code VARCHAR2(10),
gl_fms_amount NUMBER,
gl_ar_amount NUMBER,
ims_ar_amount NUMBER,
ims_gl_amount NUMBER,
amount_difference NUMBER);
由於記錄類型只能存放單條記錄,需要利用記錄表類型來實現存放多條記錄,即 table of record,如下:
--table of record
TYPE gl_ar_tbl_rec IS TABLE OF tempt_record_type INDEX BY BINARY_INTEGER;
gl_ar_rec gl_ar_tbl_rec;
定義完記錄表後,我們遍歷遊標,把數據暫存到上面定義的記錄表中,即gl_ar_rec -- 將GL-AR-IMS金額數據暫存在table of record,並批量插入表 cux_gl_ar_rev_rept
l_gl_ar_row_num := 1;
FOR l_cur_gl_ar IN cursor_gl_ar_data LOOP
gl_ar_rec(l_gl_ar_row_num).group_id := l_group_id;
gl_ar_rec(l_gl_ar_row_num).ledger_id := l_cur_gl_ar.ledger_id;
gl_ar_rec(l_gl_ar_row_num).ledger_name := l_cur_gl_ar.name;
gl_ar_rec(l_gl_ar_row_num).period_name := l_cur_gl_ar.period_name;
gl_ar_rec(l_gl_ar_row_num).segment1 := l_cur_gl_ar.segment1;
gl_ar_rec(l_gl_ar_row_num).company_name := l_cur_gl_ar.company_name;
gl_ar_rec(l_gl_ar_row_num).segment3 := l_cur_gl_ar.segment3;
gl_ar_rec(l_gl_ar_row_num).account_name := l_cur_gl_ar.account_name;
gl_ar_rec(l_gl_ar_row_num).channel_name := l_cur_gl_ar.chanel_name;
gl_ar_rec(l_gl_ar_row_num).currency_code := l_cur_gl_ar.currency_code;
gl_ar_rec(l_gl_ar_row_num).gl_fms_amount := '0.00';
gl_ar_rec(l_gl_ar_row_num).gl_ar_amount := l_cur_gl_ar.amount;
gl_ar_rec(l_gl_ar_row_num).ims_ar_amount := '0.00';
gl_ar_rec(l_gl_ar_row_num).ims_gl_amount := '0.00';
gl_ar_rec(l_gl_ar_row_num).amount_difference := '';
l_gl_ar_row_num := l_gl_ar_row_num + 1;--下一條記錄
END LOOP;
最後,我們把記錄表gl_ar_rec中暫存的數據批量插入到cux_gl_ar_rev_rept中,代碼如下:
--批量插入表cux_gl_ar_rev_rept
FORALL i IN INDICES OF gl_ar_rec
INSERT INTO cux_gl_ar_rev_rept VALUES gl_ar_rec (i);
方法二:
我們直接定義一個表類型的變量,如下:
--TYPE type_gl_ar IS TABLE OF cux_gl_ar_rev_rept%ROWTYPE;
--l_gl_ar_rec type_gl_ar;
這裏,區別於方法一的做法在於,我們不再利用記錄表暫存,直接插入
OPEN cursor_gl_ar_data;
LOOP
FETCH cursor_gl_ar_data BULK COLLECT
INTO l_gl_ar_rec LIMIT 1000;
--批量插入表 cux_gl_ar_rev_rept
FORALL i IN 1 .. l_gl_ar_rec.count
INSERT INTO cux_gl_ar_rev_rept VALUES l_gl_ar_rec (i);
EXIT WHEN cursor_gl_ar_data%NOTFOUND;
END LOOP;
CLOSE cursor_gl_ar_data;