我的一个PLSQL函数 先查询再插入数据库的函数 动态SQL拼接查询条件、通用游标、记录定义(封装部分查询字段并赋值给游标)、insert select 序列、常量【我】

时间:2024-11-10 19:03:38

先查询再插入数据库的函数

CREATE OR REPLACE FUNCTION F_REVENUE_SI(l_p_cd             in Varchar2,
l_c_cd in Varchar2,
l_prod_type in Varchar2,
l_identity_type in Varchar2,
l_industry_type_id in Varchar2, l_p_id in Varchar2,
l_c_id in Varchar2,
l_region_name in Varchar2,
l_industry_code in Varchar2,
l_industry_name in Varchar2,
l_par_industry_id in Varchar2,
l_industry_grade in Varchar2 ) return varchar2 IS
/*
DECLARE
l_p_cd Varchar2(1000) := 8350000;
l_c_cd Varchar2(1000) := 8350102;
l_prod_type Varchar2(1000) := 10;
l_identity_type Varchar2(1000) := 2;
l_industry_type_id Varchar2(1000) := 2; l_p_id Varchar2(1000) := 1;
l_c_id Varchar2(1000) := 1;
l_region_name Varchar2(1000) := 1;
l_industry_code Varchar2(1000) := 1;
l_industry_name Varchar2(1000) := 1;
l_par_industry_id Varchar2(1000) := 1;
l_industry_grade Varchar2(1000) := 1;
*/
--定义变量接收参数,以便对参数进行修改
ll_identity_type varchar2(1000) := l_identity_type;
ll_industry_type_id varchar2(1000) := l_industry_type_id; --函数返回值
return_val varchar2(8000) := '开始';
--通用游标
cv SYS_REFCURSOR;
--创建记录用于封装部分查询结果
TYPE revenue_type IS RECORD(
r1 REVENUE_STATISTICS_RES.Audit_Cust_Num%TYPE,
r2 REVENUE_STATISTICS_RES.AUDIT_CUST_PARTY_NUM%TYPE, t1 REVENUE_STATISTICS_RES.TY_1%TYPE,
t2 REVENUE_STATISTICS_RES.TY_1%TYPE,
t3 REVENUE_STATISTICS_RES.TY_1%TYPE,
t4 REVENUE_STATISTICS_RES.TY_1%TYPE,
t5 REVENUE_STATISTICS_RES.TY_1%TYPE,
t6 REVENUE_STATISTICS_RES.TY_1%TYPE,
t7 REVENUE_STATISTICS_RES.TY_1%TYPE,
t8 REVENUE_STATISTICS_RES.TY_1%TYPE,
t9 REVENUE_STATISTICS_RES.TY_1%TYPE,
t10 REVENUE_STATISTICS_RES.TY_1%TYPE,
t11 REVENUE_STATISTICS_RES.TY_1%TYPE,
t12 REVENUE_STATISTICS_RES.TY_1%TYPE, y1 REVENUE_STATISTICS_RES.TY_1%TYPE,
y2 REVENUE_STATISTICS_RES.TY_1%TYPE,
y3 REVENUE_STATISTICS_RES.TY_1%TYPE,
y4 REVENUE_STATISTICS_RES.TY_1%TYPE,
y5 REVENUE_STATISTICS_RES.TY_1%TYPE,
y6 REVENUE_STATISTICS_RES.TY_1%TYPE,
y7 REVENUE_STATISTICS_RES.TY_1%TYPE,
y8 REVENUE_STATISTICS_RES.TY_1%TYPE,
y9 REVENUE_STATISTICS_RES.TY_1%TYPE,
y10 REVENUE_STATISTICS_RES.TY_1%TYPE,
y11 REVENUE_STATISTICS_RES.TY_1%TYPE,
y12 REVENUE_STATISTICS_RES.TY_1%TYPE);
--声明变量为自定义记录类型
revenue_rec revenue_type;
--最终查询sql
s_all varchar2(3000) := ''; --基本SQL(注意 UPPER(m.PARTY_ID) != ''NULL'' 中字符串NULL要用4个单引号,否则执行不报错但查询结果是错的)
s1 varchar2(1000) := 'SELECT /*+PARALLEL(12)*/
COUNT(e.CUST_ID) AUDIT_CUST_NUM, COUNT(DISTINCT(m.PARTY_ID)) AUDIT_CUST_PARTY_NUM,
SUM(TY_1) TY1 ,SUM(TY_2) TY2,SUM(TY_3) TY3,SUM(TY_4) TY4,SUM(TY_5) TY5,SUM(TY_6) TY6,SUM(TY_7) TY7,SUM(TY_8) TY8,SUM(TY_9) TY9,SUM(TY_10) TY10,SUM(TY_11) TY11,SUM(TY_12) TY12,
SUM(LY_1) LY1 ,SUM(LY_2) LY2,SUM(LY_3) LY3,SUM(LY_4) LY4,SUM(LY_5) LY5,SUM(LY_6) LY6,SUM(LY_7) LY7,SUM(LY_8) LY8,SUM(LY_9) LY9,SUM(LY_10) LY10,SUM(LY_11) LY11,SUM(LY_12) LY12
FROM EDA_CUST_INC e, CUST_CP_MERGE m
WHERE
e.CUST_ID = m.CUST_ID
AND e.STD_LATN_CD = m.STD_LATN_CD
and m.PARTY_ID IS NOT NULL
AND UPPER(m.PARTY_ID) != ''NULL''
AND e.STD_PRVNCE_CD = ' || l_p_cd ||
' AND e.STD_LATN_CD = ' || l_c_cd; --产品类型
s_prod_type varchar2(1000) := ' AND e.PROD_TYPE =' || l_prod_type; --身份证类型
s_identity varchar2(1000) := ' AND EXISTS (SELECT 1
FROM PARTY P
WHERE m.PARTY_ID = p.PARTY_ID
AND p.IDENTITY_TYPE = ' ||
l_identity_type || ')'; --行业类型
s_industry varchar2(1000) := ' and exists (select 1
from party_org po
where m.party_id = po.party_id
and po.INDUSTRY_TYPE_ID = ' ||
l_industry_type_id || ')'; BEGIN
--处理产品类型参数
/*
IF l_prod_type is null
THEN
s_prod_type := ' AND e.PROD_TYPE is null';
END IF;
*/
--处理身份证类型参数
IF l_identity_type = '-1' THEN
s_identity := ' AND not EXISTS (SELECT 1
FROM PARTY P
WHERE m.PARTY_ID = p.PARTY_ID)';
ELSIF l_identity_type = '-2' THEN
s_identity := ' AND EXISTS (SELECT 1
FROM PARTY P
WHERE m.PARTY_ID = p.PARTY_ID
AND p.IDENTITY_TYPE is null)';
END IF; --处理行业类型参数
IF l_identity_type = '-1' THEN
s_industry := ' and not exists (select 1
from party_org po
where m.party_id = po.party_id)';
ELSIF l_identity_type = '-2' THEN
s_industry := ' and exists (select 1
from party_org po
where m.party_id = po.party_id
and po.INDUSTRY_TYPE_ID is null)';
END IF; --拼接最终查询sql
s_all := s1 || s_prod_type || s_identity || s_industry;
DBMS_OUTPUT.PUT_LINE(s_all);
return_val := '查询sql:' || s_all;
--打开通用游标
OPEN cv FOR s_all;
--将游标赋值给变量
FETCH cv
INTO revenue_rec;
--关闭游标
CLOSE cv; --给本地变量赋值以便后面插入时使用(适用于对传入参数转换后使用)
IF l_identity_type != '' and l_identity_type != '' THEN
ll_identity_type := null;
END IF; IF l_industry_type_id = '-1' or l_industry_type_id = '-2' THEN
ll_industry_type_id := null;
END IF; --执行插入
insert into REVENUE_STATISTICS_RES
(ID,
AUDIT_CUST_NUM,
AUDIT_CUST_PARTY_NUM,
TY_1,
TY_2,
TY_3,
TY_4,
TY_5,
TY_6,
TY_7,
TY_8,
TY_9,
TY_10,
TY_11,
TY_12,
LY_1,
LY_2,
LY_3,
LY_4,
LY_5,
LY_6,
LY_7,
LY_8,
LY_9,
LY_10,
LY_11,
LY_12, PROVINCE_REGION_ID,
CITY_REGION_ID,
REGION_NAME, IDENTITY_TYPE,
PROD_TYPE, INDUSTRY_TYPE_ID,
INDUSTRY_TYPE_CODE,
INDUSTRY_TYPE_NAME,
PAR_INDUSTRY_TYPE_ID,
INDUSTRY_TYPE_GRADE, IN_DATE)
select SEQ_REVENUE_STATISTICS_RES.NEXTVAL, f.*
from (SELECT revenue_rec.r1,
revenue_rec.r2, revenue_rec.t1,
revenue_rec.t2,
revenue_rec.t3,
revenue_rec.t4,
revenue_rec.t5,
revenue_rec.t6,
revenue_rec.t7,
revenue_rec.t8,
revenue_rec.t9,
revenue_rec.t10,
revenue_rec.t11,
revenue_rec.t12, revenue_rec.y1,
revenue_rec.y2,
revenue_rec.y3,
revenue_rec.y4,
revenue_rec.y5,
revenue_rec.y6,
revenue_rec.y7,
revenue_rec.y8,
revenue_rec.y9,
revenue_rec.y10,
revenue_rec.y11,
revenue_rec.y12, l_p_id,
l_c_id,
l_region_name, ll_identity_type,
l_prod_type, ll_industry_type_id,
l_industry_code,
l_industry_name,
l_par_industry_id,
l_industry_grade, sysdate
from dual) f;
COMMIT;
return_val := '插入完成';
return return_val; EXCEPTION
WHEN OTHERS THEN
return_val := return_val || '异常编码:' || SQLCODE || ' 异常信息:' || SQLERRM;
--return return_val;
DBMS_OUTPUT.PUT_LINE(return_val);
--抛出异常
RAISE;
END;

测试时,建议去掉 异常处理,避免出现异常不提示。