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;

 

posted @ 2018-12-28 15:30  醉城、  阅读(5533)  评论(0编辑  收藏  举报