Reputation: 4435
I've been digging around the internet, including Stack, for the better part of the morning trying to figure out how to create a parameter and then set its value and pass it into various locations within my where clause in my Oracle SQL. I can't seem to find exactly what I want. it's quite possible that I am not asking the question correctly, so I apologize if this is a redundant question (it seems likely that it is).
Here is the SQL I am running in Oracle SQL Developer:
SELECT t.mta_tenure_sub_type_code , t.mta_tenure_type_code , COUNT(t.tenure_number_id), SUM(t.area_in_hectares)
FROM MTA_TENURE t
WHERE
t.mta_tenure_type_code in ('M','P') AND
to_char(t.issue_date, 'YYYY') <= '&year' AND
(
to_char(t.termination_date, 'YYYY') > '&year' OR
t.termination_date IS NULL OR
t.mta_termination_type_code = 'PROT'
)
GROUP BY t.mta_tenure_sub_type_code, t.mta_tenure_type_code;
As you can see, I have '&year' located twice within my query which prompts the user to enter a value each time that variable occurs. The value is always the same year at each variable (i.e. every time the prompt pops up, the user will always enter the same year twice) Being a bit of a python programmer, I had thought that I could make this query more efficient by setting a parameter to '&year' so the user only has to enter it once and the parameter will pass the value into the where clause. Is this even possible? I really thought this would have been an easy google search, but maybe my feeble brain overlooked something. Thanks.
Upvotes: 0
Views: 7208
Reputation: 191570
You can replace the &year
references with &&year
as @Glenn suggested; see Avoiding Unnecessary Prompts for Values in the SQL*Plus docs (most of which apply to SQL Developer too).
You could also explicitly define the substitution variable, which allows you to tailor the prompt:
accept year number prompt 'Enter year'
SELECT t.mta_tenure_sub_type_code , t.mta_tenure_type_code ,
COUNT(t.tenure_number_id), SUM(t.area_in_hectares)
FROM MTA_TENURE t
WHERE
t.mta_tenure_type_code in ('M','P') AND
to_char(t.issue_date, 'YYYY') <= '&year' AND
(
to_char(t.termination_date, 'YYYY') > '&year' OR
t.termination_date IS NULL OR
t.mta_termination_type_code = 'PROT'
)
GROUP BY t.mta_tenure_sub_type_code, t.mta_tenure_type_code;
or you could define the variable with a specific value so it doesn't prompt at all:
define year=2018
If you know the value you could also use a bind variable:
var year number
exec :year := 2018;
SELECT t.mta_tenure_sub_type_code , t.mta_tenure_type_code ,
COUNT(t.tenure_number_id), SUM(t.area_in_hectares)
FROM MTA_TENURE t
WHERE
t.mta_tenure_type_code in ('M','P') AND
to_char(t.issue_date, 'YYYY') <= :year AND
(
to_char(t.termination_date, 'YYYY') > :year OR
t.termination_date IS NULL OR
t.mta_termination_type_code = 'PROT'
)
GROUP BY t.mta_tenure_sub_type_code, t.mta_tenure_type_code;
Notice the prefix for the variable has changed from &
to :
.
You could combine both if you wanted to:
var year number
exec :year := &year;
... and then use the bind instead of substitution variable in the query.
In either case I'd probably either convert the to_char(...)
value to a number, or use extract
instead:
...
extract(year from t.issue_date) <= :year AND
(
extract(year from t.termination_date) > :year OR
...
Upvotes: 2