2009-11-26 55 views
0

我正在嘗試使用以下過程作爲我的水晶報表的數據源。查詢工作如我所料,但問題是我不知道如何接回從這些假表中的數據 - IFS_PR_DUMMY_TAB和IFS_PR_DUMMY2_TABPL/SQL過程和水晶報告

CREATE OR REPLACE procedure dummy9_IFS_FR2_Sales (cdate IN date) 

as 

acontract customer_order.contract%type; 
ashowroom customer_order.district_code%type; 
aorderno customer_order.order_no%type; 
amount number(10); 

bcontract customer_order.contract%type; 
bshowroom customer_order.district_code%type; 
borderno customer_order.order_no%type; 
bamount number(10); 

CURSOR c2 IS 
select contract, district_code ,count(order_no), 
SUM(CUSTOMER_ORDER_API.Get_Total_Sale_Price__(order_no)) 
from CUSTOMER_ORDER 
where order_no IN (select distinct order_no from customer_order_line where state IN ('Released')) AND state IN ('Released') and to_char(date_entered,'MM/DD/YYYY')>=to_char(cdate,'MM/DD/YYYY') 
and contract IN 
('CERA','SAN','WOD','QEM','PIP','COT','KIT','MAR','PROJ') 
group by contract,district_code, date_entered ; 

CURSOR c2 IS 
select contract, district_code ,count(order_no), 
SUM(CUSTOMER_ORDER_API.Get_Total_Sale_Price__(order_no)) 
from CUSTOMER_ORDER 
where order_no IN (select distinct order_no from customer_order_line where state IN ('Reserved')) AND state IN ('Reserved') and to_char(date_entered,'MM/DD/YYYY')>=to_char(cdate,'MM/DD/YYYY') 
and contract IN 
('CERA','SAN','WOD','QEM','PIP','COT','KIT','MAR','PROJ') 
group by contract,district_code, date_entered ; 

begin 

--For Released Orders 

    OPEN c1; 

    DELETE FROM IFS_PR_DUMMY_TAB; 

    loop 
     fetch c1 into acontract, ashowroom, aorderno, amount; 
     exit when c1%notfound; 

Insert into IFS_PR_DUMMY_TAB 
(DCONTRACT ,DSHOWROOM ,DORDERNO,DAMOUNT) values (acontract,ashowroom,aorderno,amount); 

end loop; 
close c1; 

--For Reserved Orders 

OPEN c2; 

DELETE FROM IFS_PR_DUMMY2_TAB; 

loop 

     fetch c2 into bcontract, bshowroom, borderno, bamount; 
     exit when c2%notfound; 

Insert into IFS_PR_DUMMY2_TAB 
(ECONTRACT ,ESHOWROOM ,EORDERNO,EAMOUNT) values (bcontract,bshowroom,borderno,bamount); 

end loop; 
close c2; 

end; 

回答

1

解決你的問題讓你的程序的回報,最好的方法是結果集。在Oracle中我們使用REF CURSORS來實現這一點。您不需要再填充臨時表,但我們可以使用其中一個來定義REF CURSOR的簽名。

create or replace package report_records as 
    type order_recs is ref cursor 
     return IFS_PR_DUMMY_TAB%rowtype; 
end; 
/

此過程返回兩個參考遊標。

create or replace procedure dummy9_ifs_fr2_sales 
    (cdate in date 
    , c_released_orders in out report_records.order_recs 
    , c_reserved_orders in out report_records.order_recs 
    ) 

begin 
    open c_released_orders for 
     select contract 
       , district_code 
       ,count(order_no) 
       ,sum(customer_order_api.get_total_sale_price__(order_no)) 
     from customer_order 
     where order_no 
     in (select distinct order_no 
       from customer_order_line 
       where state in ('Released')) 
     AND state in ('Released') 
     and to_char(date_entered,'MM/DD/YYYY')>=to_char(cdate,'MM/DD/YYYY') 
     and contract in ('CERA','SAN','WOD','QEM','PIP','COT','KIT','MAR','PROJ') 
     group by contract,district_code, date_entered ; 
    open c_released_orders for 
     select contract 
       , district_code 
       ,count(order_no) 
       ,sum(customer_order_api.get_total_sale_price__(order_no)) 
     from customer_order 
     where order_no in (select distinct order_no 
           from customer_order_line 
           where state in ('Reserved')) 
     AND state in ('Reserved') 
     and to_char(date_entered,'MM/DD/YYYY')>=to_char(cdate,'MM/DD/YYYY') 
     and contract in ('CERA','SAN','WOD','QEM','PIP','COT','KIT','MAR','PROJ') 
     group by contract,district_code, date_entered ; 
end; 
/

由於利益的問題,如果你的date_entered列是一個日期數據類型,那麼你不應該使用TO_CHAR()的轉換。如果您正在尋找處理具有時間元素的行,則可以使用更有效的方法處理該行。

Ref遊標在Oracle PL/SQL用戶指南中有詳細說明。 Find out more.

編輯

我不是Crystal Reports的人。谷歌似乎只拋出一些漂亮的舊文檔(如this)。但是,共識似乎是CR在與Oracle存儲過程進行交互時相當受限制。

顯然,Crystal Reports需要聲明爲IN OUT的參數。此外,它似乎只能處理一個這樣的遊標參數。此外,參考光標需要是過程簽名中的參數第一個參數。最後,在我的腦海裏,完全令人難以置信的是,「存儲過程不能調用另一個存儲過程」。我們習慣於設計一些模式,這些模式聲明調用程序不應該知道被調用程序內部的任何內容,但是在這裏我們似乎有一個被調用程序的內部工作由調用它的程序決定。這很蹩腳。

因此,無論如何,上述解決方案不適用於Crystal Reports。唯一的解決辦法是把它分解成兩個程序,帶有簽名:

create or replace procedure dummy9_ifs_fr2_sales_released 
    (c_released_orders in out report_records.order_recs 
    , cdate in date 
    ) 
as ... 

create or replace procedure dummy9_ifs_fr2_sales_reserved 
    (c_reserved_orders in out report_records.order_recs 
    , cdate in date 
    ) 
as ... 

這些程序可以被捆綁到一個包(假設CR可以與構建體應付)。

如果這兩個過程的解決方案是不可接受的,那麼我認爲你留下了David的方法:完全放棄存儲過程,並在報告中使用原始SQL。

-2

你的代碼很爛。

首先,你爲什麼要使用顯式遊標?你爲什麼不把這些行插入表中?

其次,爲什麼刪除時,你可以截斷更快?

第三,to_char(date_entered,'MM/DD/YYYY')>=to_char(cdate,'MM/DD/YYYY')應用一個函數列(因此不能使用索引和優化器不能得到基數的一個很好的估計),它的日期轉換爲一個愚蠢的字符格式與月領先的地位,以至於它甚至不做正確的比較! 02-十一月-2009在你的邏輯中排序大於2010年3月1日。

第四,爲什麼你在地球上使用存儲過程呢?只要運行該死的查詢和聯盟所有他們在一起,如果你需要。

這讓我想起我從事離岸報告開發人員兩年前在以前的工作中看到的所有廢話。完全無能。

+0

請不要糖衣。告訴我們你真正的感受。哈哈 :) – Dusty 2009-11-26 22:33:10