将数据从一个表发送到另一表

时间:2019-03-06 10:16:27

标签: plsql

我有以下任务:

任务描述

有一些客户使用某些服务的事实表:

image1

USAGES表存储在模式USAGE_MGMT中。每月由外部应用程序填充一次。 有必要通过读取USAGES表并在BILL_CALC模式中填写以下表来实施帐单计算解决方案以为客户准备帐单,以在三个级别的层次结构中详细列出计算结果:

image2

解决方案应在DB存储包中实施。它应允许针对单个或所有客户的特定月份和年份启动帐单计算流程。 假定USAGES表可以包含数十亿条不同客户和使用日期的记录,则该解决方案应适用于大量计算过程。如果某些使用记录的PRICE列为空,则过程不会停止,但应记录错误,并为下一个客户端继续计算过程。 假设USAGE_MGMT和BILL_CALC模式在不同的Oracle数据库实例中,并且两者都授予了sys管理员权限,请提供DDL脚本来创建必要的数据库实体,包括(但不限于)数据库链接,授权,程序包规范和主体,表索引等。

我的问题是如何将数据从USAGES表发送到其他三个表?另外,为什么需要包装?我们需要三个将成为游标的SELECT语句和一个过程。我说的对吗?

编辑:

CREATE OR REPLACE PROCEDURE proc_test (p_year        IN VARCHAR2,
                                       p_month       IN VARCHAR2,
                                       p_client_id   IN NUMBER)
IS
    num_of_clients   NUMBER;
    t_client_id      NUMBER;

    CURSOR cur_clients
    IS
        SELECT DISTINCT CLIENT_ID
          FROM USAGE_MGMT.USAGES;

    CURSOR cur_bill_total
    IS
        SELECT u.CLIENT_ID
          FROM USAGE_MGMT.USAGES u;
BEGIN
    DBMS_OUTPUT.PUT_LINE ('number of clients' || num_of_clients);

    OPEN cur_clients

    LOOP
        FETCH cur_clients INTO t_client_id;

        EXIT WHEN cur_clients%NOTFOUND;
        --INSERT INTO
        DBMS_OUTPUT.put_line ('Client:' || t_client_id);
    END LOOP;

    COMMIT;
END;

我对如何插入INTO感兴趣?

编辑:

有人可以检查以下步骤吗?它给我一个错误:Error(44,13): PL/SQL: ORA-00933: SQL command not properly ended

CREATE OR REPLACE PROCEDURE proc_test (p_year        IN VARCHAR2,
                                       p_month       IN VARCHAR2,
                                       p_client_id   IN NUMBER)
IS
    vIDArray         DBMS_SQL.NUMBER_TABLE;

    vIDClientArray   DBMS_SQL.NUMBER_TABLE;
BEGIN
    INSERT INTO bill_total (id,
                            client_id,
                            month,
                            year,
                            first_usage_date,
                            last_usage_date,
                            cost)
        SELECT *
          FROM (WITH Myfilter
                     AS (SELECT p_client_id         pClientID,
                                TO_NUMBER (p_month) pMonth,
                                TO_NUMBER (p_year)  pYear,
                                TO_DATE (
                                       LPAD (p_month, 2, '0')
                                    || LPAD (p_year, 4, '0'),
                                    'MMYYYY')
                                    FirstOfMonth
                           FROM DUAL)
                  SELECT usage_mgmt.seq_usages.NEXTVAL,
                         u.client_ID,
                         f.pMonth,
                         f.pYear,
                         MIN (u.DTE),
                         MAX (u.DTE),
                         SUM (u.Price)         -- or SUM(u.Quantity * u.Price)
                    FROM Myfilter f
                         JOIN usage_mgmt.usages u
                             ON (NVL (f.pClientID, u.client_ID) = u.client_ID
                             AND u.DTE >= f.FirstOfMonth
                             AND u.DTE < ADD_MONTHS (f.FirstOfMonth, 1))
                GROUP BY u.client_ID, f.pMonth, f.pYear
                  HAVING SUM (CASE WHEN u.Price IS NULL THEN 1 ELSE 0 END) =
                             0)
      RETURNING id, client_id
           BULK COLLECT INTO vIDArray, vIDClientArray;
END;

编辑:

这有什么问题?问题出在SUBTOTAL内部循环中。它不会打印所有必要的行。

create or replace PROCEDURE proc_test2

(p_year IN VARCHAR2, p_month IN VARCHAR2, p_client_id IN NUMBER)

IS

--num_of_clients NUMBER;

--t_client_id NUMBER;



f_client_id NUMBER;

f_month VARCHAR2(100);

f_year VARCHAR2(100);

f_cost NUMBER;

f_min_date DATE;

f_max_date DATE;



f2_client_id NUMBER;

f2_unit_of_measure NUMBER;

f2_quantity NUMBER;

f2_cost NUMBER;



/*cursor cur_clients is

select distinct CLIENT_ID

from USAGE_MGMT.USAGES;



cursor cur_bill_total is

select u.CLIENT_ID

from USAGE_MGMT.USAGES u;*/



cursor cur_table1 is

select u.CLIENT_ID,to_char(sysdate, 'MM'), to_char(sysdate, 'YY') , SUM(u.QUANTITY*u.PRICE) AS COST, MIN(u.DTE), MAX(u.DTE)

from USAGES u

where u.CLIENT_ID=p_client_id

and to_char(u.DTE, 'MM')=p_month

and to_char(u.DTE, 'YY')=p_year

GROUP BY CLIENT_ID,to_char(sysdate, 'MM'), to_char(sysdate, 'YY')

;



cursor cur_table1_all is

select CLIENT_ID,to_char(sysdate, 'MM'), to_char(sysdate, 'YY') , SUM(u.QUANTITY*u.PRICE) AS COST, MIN(u.DTE), MAX(u.DTE)

from USAGES u

where

to_char(u.DTE, 'MM')=p_month

and to_char(u.DTE, 'YY')=p_year

GROUP BY CLIENT_ID, to_char(sysdate, 'MM'), to_char(sysdate, 'YY')

;



cursor cur_table2 is

select

u.UNIT_OF_MEASURE, SUM(u.QUANTITY),SUM(u.QUANTITY*u.PRICE) AS COST

from USAGES u

where u.CLIENT_ID=p_client_id

and to_char(u.DTE, 'MM')=p_month

and to_char(u.DTE, 'YY')=p_year

GROUP BY UNIT_OF_MEASURE

;



cursor cur_table2_all is

select

u.CLIENT_ID,u.UNIT_OF_MEASURE, SUM(u.QUANTITY),SUM(u.QUANTITY*u.PRICE) AS COST

from USAGES u

--where u.CLIENT_ID=p_client_id

where to_char(u.DTE, 'MM')=p_month

and to_char(u.DTE, 'YY')=p_year

GROUP BY CLIENT_ID,UNIT_OF_MEASURE

;



cursor cur_table3 is

select



u.TYPE_ID,MIN(u.DTE),MAX(u.DTE),SUM(u.QUANTITY),u.UNIT_OF_MEASURE,u.PRICE,SUM(u.QUANTITY*u.PRICE) AS COST

from USAGES u

where u.TYPE_ID=p_client_id

and to_char(u.DTE, 'MM')=p_month

and to_char(u.DTE, 'YY')=p_year



GROUP BY UNIT_OF_MEASURE,TYPE_ID,PRICE

;





seq_id NUMBER;

seq_id_2 NUMBER;



begin

--DBMS_OUTPUT.PUT_LINE('number of clients'||num_of_clients);

/*open cur_clients;

loop

fetch cur_clients

into t_client_id;

exit when cur_clients%notfound;*/



--INSERT INTO

if(p_client_id=0) then

open cur_table1_all;

else open cur_table1;

end if;



/*if(p_client_id=0) then

open cur_table2_all;

else open cur_table2;

end if;*/



open cur_table2;



loop



if(p_client_id=0) then

fetch cur_table1_all into f_client_id, f_month, f_year, f_cost, f_min_date, f_max_date;

exit when cur_table1_all%notfound;

else

fetch cur_table1 into f_client_id, f_month, f_year, f_cost, f_min_date, f_max_date;

exit when cur_table1%notfound;



end if;





SELECT BILL_CALC.SEQ_BILL_TOTAL.NEXTVAL into seq_id from dual;

INSERT INTO BILL_CALC.BILL_TOTAL (ID, CLIENT_ID, MONTH, YEAR, FIRST_USAGE_DATE, LAST_USAGE_DATE, COST)

VALUES(seq_id, f_client_id, f_month, f_year , f_min_date, f_max_date, f_cost );



loop



/*if(p_client_id=0) then

fetch cur_table2_all into f2_client_id,f2_unit_of_measure,f2_quantity,f2_cost;

exit when cur_table2_all%notfound;*/

--else

fetch cur_table2 into f2_unit_of_measure,f2_quantity,f2_cost;

exit when cur_table2%notfound;

--end if;



if(f2_client_id=f_client_id) then

SELECT BILL_CALC.SEQ_BILL_SUBTOTAL.NEXTVAL into seq_id_2 from dual;

INSERT INTO BILL_CALC.BILL_SUBTOTAL (ID, BILL_TOTAL_ID, UNIT_OF_MEASURE, QUANTITY,COST)

VALUES(seq_id_2, seq_id, f2_unit_of_measure, f2_quantity, f2_cost);

end if;



end loop;





--dbms_output.put_line ('Client:'||t_client_id);

end loop;

if (p_client_id=0) then

close cur_table1_all;

else

close cur_table1;



end if;



/*if (p_client_id=0) then

close cur_table2_all;

else

close cur_table2;



end if;*/



close cur_table2;



commit;

END;

0 个答案:

没有答案