繁体   English   中英

在Oracle PL SQL中存储变量

[英]Storing a variable in Oracle PL SQL

我希望你能提供帮助 - 我正在尝试为变量分配日期,然后在我的选择查询中调用该变量。 我发布的代码只是我正在尝试做的事情的一部分,我将不止一次地调用该变量。 我试图谷歌寻求帮助,但我坚持使用Select Into语句,因为我已经有很多选择。

DECLARE 
    CurrMonth DATE := '27 may 2012'; -- Enter 27th of current month  

BEGIN

SELECT 
    a.policynumber
    ,a.cifnumber
    ,a.phid
    ,a.policystartdate
    ,b.sistartdate
    ,c.dateofbirth
    ,'28/02/2013' AS TaxYearEnd
    --Complete tax year end in the SELECT statement (once for tax year end and once for the age at tax year end)
    ,round ((months_between('28 feb 2013',c.dateofbirth)/12),8) AS AgeAtTaxYearEnd 
    ,b.sifrequency AS CurrSIFrequ
    ,b.sivalue AS CurrentSIValue
    ,b.simode AS CurrentSIMode
    ,d.anniversarydate AS CurrentAnnDate
    ,d.anniversaryvalue AS CurrentAnnValue
    ,b.ruleeffectivedate
    ,b.sistatus AS CurrentSIStatus
    ,b.paymentbranchcode AS CurrSIBranchCode
    ,b.transferaccounttype AS CurrSIAccountType
    ,b.transferaccountnumber AS CurrSIAccountNo
    ,SUM(k.unitbalance) AS unitbalance
    ,a.latestrule
FROM fcislob.policytbl a
    ,fcislob.policysitbl b
    ,fcislob.unitholderdetailtbl c
    ,fcislob.policyanniversaryvaluetbl d
    ,fcislob.unitholderfundtbl k
WHERE a.policynumber = b.policynumber
    AND a.policynumber = d.policynumber
    AND b.policynumber = d.policynumber
    AND a.phid = c.unitholderid
    AND a.phid = k.unitholderid
    AND c.unitholderid = k.unitholderid
    AND a.ruleeffectivedate = b.ruleeffectivedate
    AND a.ruleeffectivedate = d.ruleeffectivedate
    AND b.ruleeffectivedate = d.ruleeffectivedate
    AND a.latestrule <> 0
    AND c.authrejectstatus = 'A'        
    AND a.phid LIKE 'AGLA%'
    AND b.sistatus <> 'C'
    AND k.unitbalance >0     
    AND b.transactiontype = '64'
    AND b.sistartdate <= CurrMonth                                              
    AND b.sifrequency = 'M'

GROUP BY a.policynumber, a.cifnumber, a.phid, a.policystartdate, b.sistartdate , c.dateofbirth,b.sifrequency, b.sivalue, b.simode, d.anniversarydate, d.anniversaryvalue, b.ruleeffectivedate,
    b.sistatus, b.paymentbranchcode, b.transferaccounttype, b.transferaccountnumber, b.policynumber, a.latestrule;
    END;
  1. 您有一个group by子句,因此您需要按所有未聚合的列进行分组。
  2. 您确定结果中只有一条记录吗?
  3. 正如@TonyAndrews所说,你需要into子句。 您需要为每个collumn声明一个变量并插入其中,

即:

DECLARE
  v_policynumber fcislob.policytbl.policynumber%TYPE;
  v_cifnumber    fcislob.policytbl.cifnumber%TYPE;
  v_phid         fcislob.policytbl.phid%TYPE;
  -- and so on ...
  v_sum          number;
BEGIN
    SELECT SUM(k.unitbalance), a.policynumber, a.cifnumber, a.phid -- and so on ...
      INTO v_sum, v_policynumber, v_cifnumber, v_phid -- and so on ...
      FROM fcislob.policytbl a -- and so on ...
  GROUP BY a.policynumber, a.cifnumber, a.phid -- and so on ...
END;
  1. 处理日期的方式并不“健康”,IMO最好使用to_date而不是依赖于NLS参数

如果你只是使用PL / SQL来保存几个普通select语句之间的日期值,那么它会使事情复杂化 - 如果你只想显示查询结果,切换到select into并不简单如果有多行。

既然你提到你有很多选择,我猜你有一个脚本文件( example.sql ),并通过SQL * Plus运行它们,如sqlplus user/password @example 如果是这样,您可以保留纯SQL语句并使用位置参数替换变量绑定变量来跟踪日期。

第一个选项是如果你想在命令行上传递日期,比如sqlplus user/password @example 27-May-2012

set verify off
select 'Supplied date is ' || to_date('&1', 'DD-Mon-RRRR') from dual;

这使用第一个位置参数(引用为&1 ,并根据需要将其转换为查询中的日期。 传递的日期必须采用to_date函数所期望的格式,在这种情况下,我已经制作了DD-Mon-RRRR。 请注意,您必须将变量括在单引号中,否则(除非它是一个数字)Oracle将尝试将其解释为列名而不是值。 (无论何时使用替换变量, set verify off禁止SQL * Plus默认显示的消息)。

您可以在脚本中引用&1次,但您可能会发现使用有意义的名称重新定义它更容易 - 当您有多个位置参数时尤其有用 - 然后在查询中使用该名称。

define supplied_date = &1
select 'Supplied date is ' || to_date('&supplied_date', 'DD-Mon-RRRR') from dual;

如果您不想从命令行传递日期,则可以使用固定值。 我在这里使用不同的默认日期格式,这允许我使用日期文字语法或to_date函数。

define curr_date = '2012-05-31';
select 'Today is ' || date '&curr_date' from dual;
select 'Today is ' || to_date('&curr_date', 'YYYY-MM-DD') from dual;

您可能希望使用稍后查询中的一个查询的结果来派生日期值。 您可以使用column ... new_value SQL * Plus命令来执行此操作; 这将定义一个替换变量curr_date其中包含来自任何未来查询的today列(别名)的字符串值,然后您可以以相同的方式使用它:

column today new_value curr_date
select to_char(sysdate, 'DD-Mon-YYYY') as today from dual;
select 'Today is ' || to_date('&curr_date', 'DD-Mon-YYYY') from dual;

您还可以使用使用var[iable]命令定义的绑定变量,并使用exec设置:

var curr_date varchar2(10);
exec :curr_date := '2012-05-31';
select 'Today is ' || to_date(:curr_date, 'YYYY-MM-DD') from dual;

exec实际上是一个匿名PL / SQL块的包装器,所以它意味着begin :curr_date := '2012-05-31'; end; ,但是你真的只能看到它是否有错误)。 请注意,它知道绑定变量是一个字符串,因此不要将其括在单引号中。

您可以混合和匹配,因此如果您在命令行上传递了日期,则可以使用exec :supplied_date := '&1'将其分配给绑定变量; 或者使用当前日期exec :curr_date := to_char(sysdate, 'YYYY-MM-DD')

许多组合都是可能的,因此您需要选择适合您尝试的内容,以及您认为最简单的内容。 大多数(如果不是全部)这些也应该在SQL Developer中工作,但不确定其他客户端。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM