plsql 经典例子

PROCEDURE MAKE_ALL_SAMPLE_BY_MONTH_WTH(PMONTH VARCHAR2, PCYCLE VARCHAR2) AS
VBSCODE VARCHAR2(10); --营业区域
VMONTH VARCHAR2(10); --执行年月
VSSMONTH VARCHAR2(6); --数据所属日期
VSAMPLECONDSEQ INT; --样本SEQ
VPROCNAME JC_M_RULE.PROCNAME%TYPE; --规则过程名称
VSQL VARCHAR2(1000); --运行的SQL 变量
VSEQ NUMBER(10); --SEQ 变更
VMRUN BOOLEAN; --在线规则是否执行过
VZXRUN BOOLEAN; --专项规则是否执行过
VPARPROLE VARCHAR2(2); --从营销抽数据,默认的数据层级。
VPROBLEM JC_M_RULE_PROBLEM_JOIN.PROBLEM_TYPE%TYPE; --规则问题类型
VRULEID JC_M_RULE.ID%TYPE; --规则ID
VCYCLE JC_M_RULE.RULE_CYCLE%TYPE; --执行周期
VJCFS JC_M_RULE.FRACTION%TYPE; --基础分数
GRADEFLAG BOOLEAN; --规则打分执行状态
--查询所各营业区域问题户的规则
CURSOR C IS
SELECT S.PROCNAME,
C.SEQ,
C.BSCODE,
C.SUBJECTID,
S.FRACTION,
S.RULE_CYCLE
FROM JC_M_SAMPLECOND C, JC_M_RULE S, JC_M_RULE_PROBLEM_JOIN P
WHERE C.SUBJECTID = S.ID
AND S.VALIDTAG = 'Y' --启用
AND P.RULE_ID = S.ID
AND P.PROBLEM_TYPE = VPROBLEM --问题户规则
AND LENGTH(S.PROCNAME) > 0
AND LENGTH(C.BSCODE) = 2
AND C.BSCODE <> '52' /*剔除单位为52的数据*/
AND C.PARAROLE = VPARPROLE
AND S.RULE_CALL = '01' --营销分析
ORDER BY S.PROCNAME, C.BSCODE;

BEGIN

VPARPROLE := '01'; --从营销抽数据,默认的数据层级。
VPROBLEM := '1'; --问题户规则
VMRUN := FALSE; --没有执行过在线规则
VZXRUN := FALSE; --没有执行过专项规则

--数据所属日期
IF PMONTH IS NULL OR LENGTH(PMONTH) <= 0 THEN
SELECT TO_CHAR(SYSDATE, 'YYYYMM') INTO VSSMONTH FROM DUAL;
ELSE
VSSMONTH := PMONTH;
END IF;

--更新各营业区域的规则信息
APPEND_SAMPLECOND(VPROBLEM);

--清除上一次已打分的规则信息
DELETE FROM JC_M_PF_WTH_RULE_TEMP T1 WHERE T1.DETAILTYPE = VPROBLEM;

/*--删除停用规则的明细数据
DELETE_STOPRULE_DATA_WTH();*/

--循环各营业区域的规则
OPEN C;
LOOP
FETCH C
INTO VPROCNAME, VSAMPLECONDSEQ, VBSCODE, VRULEID, VJCFS, VCYCLE;
EXIT WHEN C%NOTFOUND;
BEGIN
--PCYCLE不为空,并且VCYCLE与PCYCLE参数不相同,跳出当前循环(只运行指定频率的规则)
IF LENGTH(PCYCLE) > 0 AND PCYCLE IS NOT NULL AND PCYCLE != VCYCLE THEN
CONTINUE;
END IF;

--当前规则是否要执行。如果不执行返回空,如果执行,返回执行的日期。
VMONTH := GET_RULE_CYCLE(VRULEID, VCYCLE, PMONTH);

--没有日期,当前规则不用执行,退出本次循环。
IF LENGTH(VMONTH) = 0 OR VMONTH IS NULL THEN
CONTINUE;
END IF;

--初始化样本信息,修改FINISHTAG = 'N',CNT = 0
IF INIT_SAMPLEDCOND(VSAMPLECONDSEQ) = FALSE THEN
CONTINUE;
END IF;

EXCEPTION
WHEN OTHERS THEN
LOG_ERROR(SQLCODE,
SQLERRM,
'PKG_RULECALL.MAKE_ALL_SAMPLE_BY_MONTH_WTH(运行规则)出错!样本SEQ=[' ||
VSAMPLECONDSEQ || ',规则ID=[' || VRULEID || ',公司=[' ||
VBSCODE || ']');
CONTINUE;
END;

BEGIN

--删除当前规则在问题明细表中的数据
IF DELETE_SAMPLED_WTH(VSAMPLECONDSEQ) = FALSE THEN
CONTINUE;
END IF;

--再次检查当前规则是否停用
IF RULE_VALIDTAG_STATE(VRULEID) = FALSE THEN
CONTINUE;
END IF;

--拼接调用相应主题存储过程的执行代码
VSQL := 'CALL ' || VPROCNAME || '(''' || VBSCODE || ''',''' ||
VMONTH || ''',' || TO_CHAR(VSAMPLECONDSEQ) || ',''' ||
VPARPROLE || ''')';

/* --拼接调用相应主题存储过程的执行代码(绑定变量)
VSQL := 'CALL ' || :1 || '(''' || :2 || ''',''' ||
:3 || ''',' || TO_CHAR(:4) || ',''' ||
:5 || ''')'
EXECUTE IMMEDIATE VSQL USING VPROCNAME, VBSCODE,VMONTH,VSAMPLECONDSEQ,VPARPROLE ;*/
--生成规则样本日志
LOG_SAMPLE_BEGIN(VSEQ, VBSCODE, VSAMPLECONDSEQ, VSQL);

EXECUTE IMMEDIATE VSQL;

--提交样本数据
COMMIT;

IF INSTR(UPPER(VPROCNAME), 'PKG_YX.') > 0 THEN
VMRUN := TRUE; --执行过在线规则
ELSIF INSTR(UPPER(VPROCNAME), 'PKG_ZX.') > 0 THEN
VZXRUN := TRUE; --执行过专项规则
END IF;

--过滤黑白名单
FILTER_HBMD_WTH(VSAMPLECONDSEQ, --样本SEQ
VRULEID, --规则ID
VMONTH, --年月
VBSCODE, --营业区域
VPROCNAME, --规则过程名称
VCYCLE, --规则分类(运行周期)
VJCFS); --基础分数

--过滤无效用户
DELETE_CANCELLATION_WTH(VSAMPLECONDSEQ);

--修改样本条件记录的已完成标志和样本数据
UPDATE_SAMPLEDCOND(VSAMPLECONDSEQ,
VBSCODE,
VRULEID,
PMONTH,
VPROBLEM,
VPARPROLE);

--插入阀值层级数据
INSERT_LEVEL_DATA_WTH(VRULEID, VBSCODE);

--记录已执行的规则ID,用于后面的规则评分计算
INSERT INTO JC_M_PF_WTH_RULE_TEMP (RULE_ID,DETAILTYPE) VALUES (VRULEID,VPROBLEM);

--实时更新日志,记录每个地区规则抽取数量
LOG_SAMPLE_END(VSEQ, VSAMPLECONDSEQ);

EXCEPTION
WHEN OTHERS THEN
LOG_SAMPLE_ERROR(VSEQ, SYSDATE, SQLERRM);
END;

END LOOP;
CLOSE C;

--如果规则执行过,执行以下代码。
IF VMRUN OR VZXRUN THEN
--将SAMPLED表中的用户问题合并到SAMPLE表,SAMPLE表中一个用户一条记录,多个主题的问题描述合并。
BEGIN
LOG_SAMPLE_BEGIN(VSEQ, NULL, NULL, 'MERGE_SAMPLE_WTH');
MERGE_SAMPLE_WTH(VSEQ);
LOG_SAMPLE_END(VSEQ, NULL);
EXCEPTION
WHEN OTHERS THEN
LOG_SAMPLE_ERROR(VSEQ, SYSDATE, SQLERRM);
END;

--插入当月历问题汇总历史数据
BEGIN
--LOG_SAMPLE_BEGIN(VSEQ, NULL, NULL, 'OLD_SAMPLE_WTH');该日志已经在OLD_SAMPLE_WTH写入
OLD_SAMPLE_WTH(VSSMONTH, VMRUN, VZXRUN, VSEQ); --历史中记录的日期为当前日期
-- LOG_SAMPLE_END(VSEQ, NULL);
EXCEPTION
WHEN OTHERS THEN
LOG_SAMPLE_ERROR(VSEQ, SYSDATE, SQLERRM);
END;

--执行异动数据(每次执行完数据更新本月的异动报表,目的:使得大屏统计和明细对应上)
PKG_YDSJ.SUM_YDSJ_ALL_BY;

--计算每户的规则得分
GRADEFLAG := FALSE;
FOR GRADERULE IN (SELECT DISTINCT RULE_ID FROM JC_M_PF_WTH_RULE_TEMP WHERE DETAILTYPE = VPROBLEM) LOOP
IF RULE_GRADE_DEFINITE_WTH(GRADERULE.RULE_ID, VSSMONTH) = TRUE THEN
GRADEFLAG := TRUE;
END IF;
END LOOP;
DELETE FROM JC_M_PF_WTH_RULE_TEMP; --删除规则打分的规则信息

--如果有规则已计算打分,需要重新汇总用户得分。
IF GRADEFLAG = TRUE THEN
RULE_GRADE_MERGE_WTH(VSSMONTH);
END IF;

END IF;
EXCEPTION
WHEN OTHERS THEN
LOG_ERROR(SQLCODE,
SQLERRM,
'PKG_RULECALL.MAKE_ALL_SAMPLE_BY_MONTH_WTH(运行规则,查找问题户数据(带月份))出错!');
ROLLBACK;
END;

猜你喜欢

转载自www.cnblogs.com/kingwei55555/p/12127880.html