首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Oracle脚本中使用变量

在Oracle脚本中使用变量
EN

Stack Overflow用户
提问于 2011-02-18 13:09:45
回答 2查看 27.7K关注 0票数 2

有一个复杂的查询,它生成报告。该查询有几个子查询,它们为不同的产品生成3列表。每个子查询返回一行。然后,所有返回的行都需要合并。但有一个要求。如果子查询没有结果行,那么无论如何我们都需要将相应的产品包含到最终报告中,但是要指定Trades_Count等于零。

我可以使用一组变量来实现这一点。以下代码将在中完美地工作:

代码语言:javascript
复制
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)
)

我认为我没有使用任何特定于that的东西,但是使用了纯ANSI(我不是100%确定)。

在甲骨文中,这是不工作的

首先,它需要只有一个DECLARE关键字。然后它强迫我使用Begin…结束执行范围。然后它不允许我像我一样分配变量(见上面的例子)--我需要使用“Select”语句。在完成所有计算之后,它不允许我从局部变量中选择值。见鬼。

有人知道如何让它在Oracle中工作吗?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-18 13:35:18

PL/SQL与t不同,我为您做了一些修改,但是一定要查看Andy的链接。这是在oracle的免费SQL中运行的(该开发人员还提供了一个可能有用的“翻译划痕处理程序(tools>Migration>Translation划痕处理程序)”。

代码语言:javascript
复制
--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                      

这里使用的甲骨文概念:对偶表NVL变量pl/sql异常

看看这个plsql.htm

票数 8
EN

Stack Overflow用户

发布于 2011-02-18 13:17:47

PL/SQL对过程块的格式与than不同。

您需要使用以下结构:

代码语言:javascript
复制
DECLARE
    astring varchar2(1000);
    anumber number;

BEGIN
   my SQL code here...
END;

您在PL/SQL中也不使用@。直接使用变量名。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5041653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档