我已经在这个网站上使用了一段时间的信息,现在有一个大项目,我需要你的一些专业知识。我在Oracle 11g环境中工作,也有Cognos Report Studio 10.1
我正在构建一个多标签报告,显示部门出站订单的分析。我创建了一个自定义表,可以容纳大约30列数据。从这里开始,每天必须在桌面上进行150多次计算。这些计算的一个例子是
1)今天收到多少订单?
2)今天收到的订单中,当天发货了多少?
3)有多少订单被搁置?
核心表上基本上有100个4-5行查询。我考虑过创建第二个表并使用WITH子句,在过程中执行计算并插入表中。
要解决这个问题,是否有人编写了执行大量计算的程序/包,是否有可以建议的链接/网页?我的搜索没有让我看到任何有关此类性质的报告的例子,并且我希望确保我的方法尽可能高效。提前感谢任何信息/资源。
答案 0 :(得分:1)
表和存储过程是个好主意。一些考虑: 你会每天归档这些事实。
即,您是否希望能够查找5天前暂停的订单,或者150个问题中的所有数据仅与当前日期相关?
您可以拥有一个包含150列的表格,每个问题一个。如果您要归档数据并且每天需要一条记录,这可能是有意义的。
另一种方法是创建一个只包含两个或三个字段的订单事实表:
Fact_Name VARCHAR2(30)
Order_Fact NUMBER(10,2)
Last_Update_Date DATE
您的oracle存储过程将一次查询和更新一个事实:
insert into ORDER_FACTS
select "ORDERS_RECEIVED" fact_name, count(*) order_fact, sysdate
from ORDER_TABLE
where rcv_date = trunc(sysdate);
commit;
如果您只想保留每个事实的一条记录,您可以进行更新。
如果您的某些问题的答案不是数字,您可能需要为VARCHAR2类型的事实保留一个单独的表。
如果你喜欢这个解决方案的声音,我明天可以设置一个示例程序。
编辑:
由于您要存储30天的数据,我会在日期详细信息级别创建表,并有1列来存储每个结果。对于我的例子,我只包括3列,所以你可以得到这个想法。首先,创建表以保存您的订单事实。
create table order_facts
( DT DATE,
ORD_RCV NUMBER,
SAME_DAY_SHIPPED NUMBER,
ON_HOLD NUMBER);
我建议DT字段单独存储日期。这将使表格更容易与您的日历表连接,如果它们基于星形模式中包含日历的表格,您可以使用这些日历表轻松地将这些事实与其他报表相关联。
接下来,创建更新它们的过程:
CREATE OR REPLACE PROCEDURE CALC_ORDER_FACTS ( iDate date := trunc(sysdate), iPurgeDays number := 0)
IS
ddate DATE;
dummy DATE;
/*
Calc_order_facts
Date Author Note
04/11/2013 XXX Created this procedure
Param iDate (optional, default trunc(sysdate)
Specify Date to calculate order facts for
Param iPurgeDays number (optional, default 0)
Specify how many days to retain data. Data older than iPurgeDays will be deleted.
If 0, purging is disabled.
*/
BEGIN
ddate := iDate;
IF iPurgeDays > 0 THEN
dbms_output.put_line('Purging data more than ' || to_char(iPurgeDays) || ' days old.');
begin
delete ORDER_FACTS
where DT < trunc(ddate-iPurgeDays);
commit;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Purge found no data.');
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
dbms_output.put_line('Purged failed, rollling back...');
rollback;
END;
END IF;
-- If date does not already exist in table, insert it
begin
select dt
into dummy
from order_facts
where dt = ddate;
EXCEPTION
WHEN NO_DATA_FOUND THEN
insert into order_facts
values (ddate, null, null, null);
commit;
END;
-- ORD_RCV
-- Calculate Orders received
update order_facts
set ord_rcv =
(select count(*) ord_rcv
from ORDER_TABLE
where rcv_date = ddate)
where dt = ddate;
commit;
-- SAME_DAY_SHIPPED
-- Calculate Orders received and shipped on ddate
update order_facts
set same_day_shipped =
(select count(*) same_day_shipped
from order_table
where rcv_dt = ddate
and ship_dt = ddate)
where dt = ddate;
commit;
-- ON_HOLD
-- Total orders on_hold
-- This method applies if you are only concerned with total on hold
update order_facts
set on_hold =
(select count(*) ON_HOLD
from order_table
where status = 'HOLD')
where dt = ddate;
commit;
END CALC_ORDER_FACTS;