I hope you can help - I'm strying to assign a date to a variable, and then call that variable in my select query. The code I'm posting is only part of what I'm strying to do, I will be calling that variable more than once. I've tried to google for help, but I'm stuck on using the Select Into statement, as I've got so many selects already.
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;
group by
clause so you need to group by all collumns which aren't aggregated. 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;
to_date
and not realy on NLS parameters If you are only using PL/SQL to be able persist the date value between several plain select
statements, then it will complicate things a lot - switching to select into
isn't straightforward if you just want to display the results of the query, particularly if there are multiple rows.
Since you mention you have many selects, I'm guessing you have them in a script file ( example.sql
) and are running them through SQL*Plus, like sqlplus user/password @example
. If so you can keep your plain SQL statements and use positional parameters , substitution variables , or bind variables to track the date.
First option is if you want to pass the date on the command line, like sqlplus user/password @example 27-May-2012
:
set verify off
select 'Supplied date is ' || to_date('&1', 'DD-Mon-RRRR') from dual;
This uses the first positional parameter, which is referenced as &1
, and converts it to a date as needed in the query. The passed date has to be in the format expected by the to_date
function, which in this case I've made DD-Mon-RRRR. Note that you have to enclose the variable in single quotes, otherwise (unless it's a number) Oracle will try to interpret it as a column name rather than a value. (The set verify off
suppresses messages SQL*Plus shows by default whenever a substitution variable is used).
You can reference &1
as many times as you want in your script, but you may find it easer to redefine it with a meaningful name - particularly useful when you have multiple positional parameters - and then use that name in your queries.
define supplied_date = &1
select 'Supplied date is ' || to_date('&supplied_date', 'DD-Mon-RRRR') from dual;
If you don't want to pass the date from the command line, you can use a fixed value instead. I'm using a different default date format here, which allows me to use the date literal syntax or the to_date
function.
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;
You may want to derive the date value, using the result of one query in a later one. You can use the column ... new_value
SQL*Plus command to do that; this defines a substitution variable curr_date
with the string value from the today
column (alias) from any future query, and you can then use it in the same way:
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;
You can also use bind variables, which you define with the var[iable]
command, and set with 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
is actually a wrapper around an anonymous PL/SQL block, so it means begin :curr_date := '2012-05-31'; end;
, but you only really see that if there's an error). Note that it knows the bind variable is a string, so you don't enclose this in single quotes.
You can mix and match, so if you passed a date on the command line you could assign it to a bind variable with exec :supplied_date := '&1'
; or to use current date exec :curr_date := to_char(sysdate, 'YYYY-MM-DD')
.
Many combinations possible, so you'll need to pick what suits what you're trying to do, and which you find simplest. Most, if not all, of these should work in SQL Developer too, but not sure about other clients.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.