2011-02-18 64 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。只需直接使用变量名称。