2011-02-18 61 views
2

有一個生成報告的複雜查詢。該查詢有幾個子查詢,可爲不同產品生成3列表。每個子查詢返回一行。所有返回的行然後需要聯合。 但有一個要求。如果子查詢沒有結果行,我們需要將相應的產品包含到最終報告中,但是指定Trades_Count等於零。在Oracle腳本中使用變量

我可以使用一組變量來實現這一點。下面的代碼將在MS SQL Server中很好地工作:

DECLARE @PRODUCT_NAME_1 nvarchar(100); 
DECLARE @OFFER_VALID_DATE_1 datetime; 
DECLARE @TRADES_COUNT_1 int; 

DECLARE @PRODUCT_NAME_2 nvarchar(100); 
DECLARE @OFFER_VALID_DATE_2 datetime; 
DECLARE @TRADES_COUNT_2 int; 

--Product 1 
select @PRODUCT_NAME_1 = PRODUCT_NAME, @OFFER_VALID_DATE_1 = MAX(EXPIRY_DATE), @TRADES_COUNT_1 = COUNT(DEAL_NUMBER) 
from (
     --Data extractions with several joins goes here.... 

) as TempTable1 
GROUP BY PRODUCT_NAME 


--Product 2 
select @PRODUCT_NAME_2 = PRODUCT_NAME, @OFFER_VALID_DATE_2 = MAX(EXPIRY_DATE), @TRADES_COUNT_2 = COUNT(DEAL_NUMBER) 
from (
     --Data extractions with several joins goes here.... 
) as TempTable2 
GROUP BY PRODUCT_NAME 


SELECT ISNULL(@PRODUCT_NAME_1,'Product 1') AS PRODUCT_NAME, @OFFER_VALID_DATE_1 AS MAX_MATURITY, ISNULL(@TRADES_COUNT_1,0) 
UNION 
(
SELECT ISNULL(@PRODUCT_NAME_2,'Product 2') AS PRODUCT_NAME, @OFFER_VALID_DATE_2 AS MAX_MATURITY, ISNULL(@TRADES_COUNT_2,0) 
) 

我認爲我沒有使用任何T-SQL特有的,但是純粹的ANSI-SQL(我不是100%肯定,雖然)。

因此這是在Oracle中不能正常工作

首先它只需要一個DECLARE關鍵字。然後它強制我使用Begin ... End execution scope。然後它不允許我像我一樣分配變量(請參見上面的示例) - 我需要使用「Select INTO」語句。完成所有計算後,它不允許我從局部變量中選擇值。哎呀。

有誰知道如何使它在Oracle中工作?

謝謝!

回答

7

PL/SQL與t-sql不同,我對你做了一些修改,但是一定要看看Andy的鏈接。這是在Oracle的免費SQL開發人員(其中也有一個「翻譯劃痕處理程序(工具>遷移>翻譯劃痕處理程序),可能是使用的跑到這裏使用

--this creates a refcursor to allow us to simply print the results 
var refc refcursor 
/

declare --here we declare our variables 
    product_name_1 varchar2(15) ; 
    offer_valid_date_1 date ; 
    trade_count_1 number ; 
    product_name_2 varchar2(15) ; 
    offer_valid_date_2 date ; 
    trade_count_2 number ;  
begin 
    begin --this creates a block so we may handle any exceptions just to this 
      select PRODUCT_NAME, MAX(EXPIRY_DATE), COUNT(DEAL_NUMBER) 
      into product_name_1 , offer_valid_date_1 , trade_count_1 
      --in oracle you select INTO, not var=COL 
     from (
       --Data extractions with several joins goes here.... 
       select 
        123 PRODUCT_NAME,  
        sysdate EXPIRY_DATE,  
        5 DEAL_NUMBER 
       from dual --this is a 'fake' table to generate some data for testing 

     ) TempTable1 --drop the "as" 
     GROUP BY PRODUCT_NAME ; 
    exception --if not data is found, then this error is thrown 
       --if multiple values are thrown an error will also be thrown (not caught here) 
    when no_data_found then 
     product_name_1 := null ; --note, to do a var = , we use "var := value;" 
     offer_valid_date_1 := null; 
     trade_count_1 := null; 
    end ; 
    begin 
      select PRODUCT_NAME, MAX(EXPIRY_DATE), COUNT(DEAL_NUMBER) 
      into product_name_2 , offer_valid_date_2 , trade_count_2 
      --in oracle you select INTO, not var=COL 
     from (
       --Data extractions with several joins goes here.... 
       select 555 PRODUCT_NAME, sysdate EXPIRY_DATE, 6 DEAL_NUMBER 
       from dual 

     ) TempTable2 -- drop the "as" 
     GROUP BY PRODUCT_NAME ; 
    exception --if not data is found, then this error is thrown 
       --if multiple values are thrown an error will also be thrown (not caught here) 
    when no_data_found then 
     product_name_2 := null ; 
     offer_valid_date_2 := null; 
     trade_count_2 := null; 
    end ; 

    open :refc for --you cannot just have a select statement, you must "open" a cursor for it  
    --oracle IsNull is NVL (or NVL2 or you can do a case or decode...) 
    SELECT nvl(PRODUCT_NAME_1,'Product 1') AS PRODUCT_NAME 
      , OFFER_VALID_DATE_1 AS MAX_MATURITY 
      , nvl(TRADE_COUNT_1,0) 
     FROM DUAL --you also must have a table, DUAL is an oracle table for this tasks 
     UNION 
    SELECT nvl(PRODUCT_NAME_2,'Product 2') AS PRODUCT_NAME 
      , OFFER_VALID_DATE_2 AS MAX_MATURITY 
      , nvl(TRADE_COUNT_2,0) 
    FROM DUAL; 

end ; 
/

--now print the results, if you did this in a proc you would simple have this as an output 
print refc; 

------------- 
PRODUCT_NAME MAX_MATURITY    NVL(:B1,0)    
-------------------------------------- ---------------------- 
123   18.FEB.2011 08:43   1      
555   18.FEB.2011 08:43   1      

甲骨文概念: Dual TableNVLVariablespl/sql Exception

,並期待在此http://www.dba-oracle.com/t_convent_sql_server_tsql_oracle_plsql.htm

+0

非常感謝你。Inspite它是非常複雜的,它的工程!:) – 2011-02-18 14:22:51

1

PL/SQL格式過程塊與T-SQL不同。

您需要使用以下結構:

DECLARE 
    astring varchar2(1000); 
    anumber number; 

BEGIN 
    my SQL code here... 
END; 

你不使用@無論是在PL/SQL。只需直接使用變量名稱。