Mike
Mike

Reputation: 4435

Passing value from parameter to SQL Query

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

Answers (1)

Alex Poole
Alex Poole

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

Related Questions