【发布时间】:2021-02-24 14:31:44
【问题描述】:
输入参数是用逗号分隔的 2 个 id(from_id 和 to_id)。每个 id 都必须在报告运行时进行评估。 From_id='202031,202032,202035,202041,...' To_id ='202111,202112,202135,202141,...' 应该从 _id 过滤每个记录,并在打印到日志文件时打印相应的 to_id。始终为 202031 至 202111、202032 至 202112、202035 至 202135、20241 至 202141。以下是预期的结果。
Num_ber Description person_id person_name Rolled_To_term From_id to_id term_priority_to_term max_amt_to_term
90010001 fund1 1 abc N 202031 202111 3 23
90010001 fund1 1 abc N 202032 202112 6 110
50010001 fund2 2 xyz N 202035 202135 2 45
50010001 fund2 3 efg N 202035 202135 5 50
下面的过程会更新 to_id ,但 from_id 仍然是 202031 并再次循环。游标不过滤其他 frm_id。
PROCEDURE report_v1 (
p_frm_id_list VARCHAR2,
p_to_id_list VARCHAR2
) AS
exemp_log_file utl_file.file_type;
log_msg VARCHAR2(600);
frm_id_list VARCHAR2(50);
frm_id_list_temp VARCHAR2(50);
frm_id VARCHAR2(50);
to_id_list VARCHAR2(50);
to_id_list _temp VARCHAR2(50);
to_id VARCHAR2(50);
CURSOR get_expt_info_c IS
SELECT
code AS num_ber,
desc AS description,
a.term_expiration AS exp_term,
(select p_id from tab3 c where a.id=c.id) as person_id,
(select p_name from tab3 c where a.id=c.id) as person_name,
a.term_code AS from_id,
nvl(
(
SELECT DISTINCT
'Y'
FROM
tab2 b
WHERE
b.term_code = to_term
AND b.id = a.id
), 'N'
) rolled_to_term,
a.priority AS term_priority_to_term,
a.amount AS max_amt_to_term
FROM
tab left
JOIN tab2 a ON code = a.code
AND term_code = a.term_code
WHERE
instr(
frm_id, a.term_code
) > 0;
BEGIN
exemp_log_file := utl_file.fopen(dir,'report.csv','w');
log_msg := 'Report header';
utl_file.put_line(exemp_log_file,log_msg,autoflush => true );
frm_id_list := replace(p_frm_id_list ,' ','');
to_id_list := replace( p_ to_id_list, ' ','' );
WHILE frm_id_list IS NOT NULL LOOP
IF instr( frm_id_list,',') > 0 THEN
frm_id := substr(frm_id_list,1,instr(frm_id_list,',') - 1 );
frm_id_list_temp := substr(frm_id_list,instr(frm_id_list,',' ) + 1);
ELSE
frm_id := frm_id_list;
frm_id_list_temp := NULL;
END IF;
frm_id_list := frm_id_list_temp;
WHILE to_id_list IS NOT NULL LOOP
IF instr(to_id_list,',' ) > 0 THEN
to_id := substr(to_id_list,1,instr(to_id_list,',' ) - 1 );
to_id_list_temp := substr(to_id_list,instr(to_id_list,',' ) + 1 );
ELSE
to_id := to_id_list;
to_id_list_temp := NULL;
END IF;
to_id_list := to_id_list_temp;
FOR exemp IN get_expt_info_c LOOP
utl_file.put_line(
exemp_log_file,
exemp.num_ber
|| ';'
|| exemp.description
|| ';'
|| exemp.exp_term
|| ';'
|| exemp.person_id
|| ';'
|| exemp.person_name
|| ';'
|| exemp.from_id
|| ';'
|| exemp.rolled_to_term
|| ';'
|| exemp.priority
|| ';'
|| exemp.amt
|| ';'
|| to_id,
autoflush => true
);
END LOOP;
END LOOP;
END LOOP;
EXCEPTION
WHEN no_data_found THEN
NULL;
WHEN OTHERS THEN
EXIT;
utl_file.fclose(exemp_log_file);
END report_v1;
表格定义和样本数据
CREATE TABLE "TAB"
(CODE" VARCHAR2(8 CHAR) NOT NULL ENABLE,
"TERM_CODE" VARCHAR2(6 CHAR) NOT NULL ENABLE,
"DESC" VARCHAR2(30 CHAR) NOT NULL ENABLE,
"DETAIL_CODE" VARCHAR2(4 CHAR) NOT NULL ENABLE,
"ACTIVITY_DATE" DATE NOT NULL ENABLE
)
CODE TERM_CODE DESC DETAIL_CODE ACTIVITY_DATE
90010001 202031 fund1 aaa 09-Jun-2009
CREATE TABLE."TAB2"
("CODE" VARCHAR2(8 CHAR),
"ID" NUMBER(8,0),
"TERM_CODE" VARCHAR2(6 CHAR),
"ACTIVITY_DATE" DATE,
"TERM_EXPIRATION" VARCHAR2(6 CHAR),
"PRIORITY" NUMBER(2,0),
"AMOUNT" NUMBER(7,2)
)
CODE ID TERM_CODE ACTIVITY_DATE TERM_EXPIRATION PRIORITY AMOUNT
90010001 1 202031 09-Jun-2009 31-DEC-2030 3 23
CREATE TABLE "TAB3"
("P_ID" NUMBER(8,0) NOT NULL ENABLE,
"P_NAME" VARCHAR2(60 CHAR) NOT NULL ENABLE,
"ACTIVITY_DATE" DATE NOT NULL ENABLE
)
P_ID P_NAME ACTIVITY_DATE
1 abc 01-JAN-2007
任何人都可以提出更好的方法/替代我的方法或纠正我的程序。
【问题讨论】:
标签: sql for-loop plsql while-loop plsqldeveloper