oracle存储过程临时表
接到一个以前领导的需求,说的大概意思是:
如果能关联上就取关联上的最大值更新到表里,没有关联上的就取原来的值。
写一个存储过程,这正好用到了临时表,上网查询,用的太乱了,特别记录。
准备阶段
创建PD_INFO
create table PD_INFO
(
id INTEGER,
pd NUMBER,
pd_f NUMBER,
data_date DATE
);
insert into pd_info (ID, PD, PD_F, DATA_DATE) values (1, 0.7, 0.9, to_date('28-12-2018', 'dd-mm-yyyy'));
insert into pd_info (ID, PD, PD_F, DATA_DATE) values (2, 0.8, 0.1, to_date('28-12-2018', 'dd-mm-yyyy'));
insert into pd_info (ID, PD, PD_F, DATA_DATE) values (3, 0.9, 0.3, to_date('28-12-2018', 'dd-mm-yyyy'));
insert into pd_info (ID, PD, PD_F, DATA_DATE) values (4, 0.5, 0.5, to_date('28-12-2018', 'dd-mm-yyyy'));
创建CUST_INFO
create table CUST_INFO
(
cust_id VARCHAR2(12),
id INTEGER
);
insert into CUST_INFO (CUST_ID, ID) values ('A', 1);
insert into CUST_INFO (CUST_ID, ID) values ('A', 2);
insert into CUST_INFO (CUST_ID, ID) values ('A', 3);
创建过程
CREATE OR REPLACE PROCEDURE PROC_PD_INFO_TEST(P_DATE IN VARCHAR2,RFLAG OUT NUMBER) AUTHID CURRENT_USER IS str1 VARCHAR(2000); str2 VARCHAR(2000); str_sql VARCHAR(2000); str3 varchar(2000); str4 varchar(2000); V_DATA date; BEGIN str1 := 'CREATE GLOBAL TEMPORARY TABLE PD_TMP(ID INTEGER,PD NUMBER,PD_F NUMBER) ON COMMIT PRESERVE ROWS'; EXECUTE IMMEDIATE str1; SELECT to_date(P_DATE,'YYYYMMDD') INTO V_DATA from dual; str_sql := 'INSERT INTO PD_TMP SELECT A.ID,A.PD,B.PD_F FROM ( SELECT PD.ID, PD.PD, CASE WHEN CUST.ID IS NOT NULL THEN ''FLAG'' ELSE ''NO_FLAG'' END AS FLAG FROM PD_INFO PD LEFT JOIN CUST_INFO CUST ON PD.ID = CUST.ID where pd.data_date = '''||V_DATA||''' ) A LEFT JOIN (SELECT MAX(PD) PD_F, FLAG FROM (SELECT PD.ID, PD.PD, CASE WHEN CUST.ID IS NOT NULL THEN ''FLAG'' ELSE ''NO_FLAG'' END AS FLAG FROM PD_INFO PD LEFT JOIN CUST_INFO CUST ON PD.ID = CUST.ID where pd.data_date = '''||V_DATA||''' ) GROUP BY FLAG) B ON A.FLAG=B.FLAG'; EXECUTE immediate str_sql; str2:='MERGE INTO PD_INFO TAB1 USING (SELECT ID,PD,PD_F FROM PD_TMP T )TAB2 ON (TAB1.ID = TAB2.ID) WHEN MATCHED THEN UPDATE SET TAB1.PD_F = TAB2.PD_F'; EXECUTE IMMEDIATE str2; str3:='truncate table pd_tmp'; execute immediate str3; str4:='drop table pd_tmp'; execute immediate str4; commit; END PROC_PD_INFO_TEST;
用到了临时表,动态SQL创建的,执行的时候,用EXECUTE IMMEDIATE 。
在用到临时表的时候,需要删除,首先到truncate table 后,才能dorp table 。
调用过程
declare RFLAG number; begin -- Call the procedure proc_pd_info_test('20181228',RFLAG); end;