1

希望您能提供帮助-我正在尝试将日期分配给变量,然后在我的选择查询中调用该变量。我发布的代码只是我正在努力做的一部分,我将不止一次调用该变量。我曾尝试向谷歌寻求帮助,但我坚持使用 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;
4

2 回答 2

3
  1. 您有一个group by子句,因此您需要按所有未聚合的列进行分组。
  2. 您确定结果中只有一条记录吗?
  3. 正如@TonyAndrews 所说,您需要 into 子句。您需要为每个列声明一个变量并插入其中,

IE:

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 参数
于 2012-05-30T11:54:49.270 回答
0

如果您只使用 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_valueSQL*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 中工作,但不确定其他客户端。

于 2012-05-31T08:32:31.520 回答