我希望你能提供帮助 - 我正在尝试为变量分配日期,然后在我的选择查询中调用该变量。我发布的代码只是我正在尝试做的事情的一部分,我将不止一次地调用该变量。 我试图谷歌寻求帮助,但我仍然坚持使用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;
答案 0 :(得分:3)
group by
子句,因此您需要按所有未聚合的列进行分组。即:
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;
to_date
而不是依赖NLS参数答案 1 :(得分:0)
如果你只是使用PL / SQL来保持几个普通select
语句之间的日期值,那么它会使事情复杂化 - 如果你只是转换到select into
并不简单想要显示查询结果,特别是如果有多行。
由于你提到你有很多选择,我猜你在脚本文件(example.sql
)中有它们,并且正在通过SQL * Plus运行它们,如sqlplus user/password @example
。如果是这样,您可以保留纯SQL语句并使用positional parameters,substitution variables或bind variables来跟踪日期。
第一个选项是您希望在命令行上传递日期,例如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中工作,但不确定其他客户端。