简体   繁体   中英

Toad For Oracle: Bind Variable “End_Year” not Declared

I have pieced together the following code using recommendations from a couple different post and have hit a wall. My ultimate goal for this code is to find records from Oct 1st of last year to Sep 30th of the current year without prompting the user for input or having to hard code the date range in the between statement. I am currently receiving the following error "Bind variable "End_Year" not declared" when running the code.

    declare
begin_Year date;
begin
 select trunc(sysdate, 'YEAR')-92 FY_begin_year
  Into begin_Year
  from Dual;
 end;

 declare
 End_Year date;
 begin
select  add_months(trunc(sysdate, 'YEAR'), 12)-93 FY_end_year
into End_Year
from dual;
end;

SELECT inv.company as company
               , inv.customer_id as cust
               , inv.address_id
               ,inv.invdate
               , SUM(inv.sales) as sales
               , SUM(inv.cost) as costs 
               FROM ifsinfo.hb_invoicing_all inv 
            WHERE inv.site IN ('06','01')
                AND TO_DATE(inv.invdate) between :begin_Year and :End_Year
            GROUP BY inv.company
               , inv.customer_id
               , inv.address_id 
               , inv.invdate

There are couple of things which are wrong with your query, first is to give alias to into clause. Also you have to encapsulate all the statments inside 1 PLSQL block.

Also what are you going to do with the select query. Are you displaying the output somewhere else?

The easiest way would be to use below query directly, instead of using 2 different variables.

SELECT inv.company as company
   , inv.customer_id as cust
   , inv.address_id
   ,inv.invdate
   , SUM(inv.sales) as sales
   , SUM(inv.cost) as costs 
   FROM ifsinfo.hb_invoicing_all inv 
WHERE inv.site IN ('06','01')
    AND TO_DATE(inv.invdate) 
    between  
        trunc(sysdate, 'YEAR')-92  
        and 
        add_months(trunc(sysdate, 'YEAR'), 12)-93
GROUP BY inv.company
   , inv.customer_id
   , inv.address_id 
   , inv.invdate

If you absolutely have to use variables, then put them in a same plsql block.

As mentioned by the others - you do not need any plsql block - just an sql query.

Now regarding your main goal

My ultimate goal for this code is to find records from Oct 1st of last year to Sep 30th of the current year without prompting the user for input or having to hard code the date range in the between statement

Given that Oct 1st of last year could be found as

to_date('01/10/'|| (to_number(to_char(sysdate,'YYYY'))-1),'dd/mm/rrrr')

and Sep 30th of the current year is

to_date('30/09/'|| to_char(sysdate,'YYYY'),'dd/mm/rrrr')

your query becomes

SELECT inv.company as company
   , inv.customer_id as cust
   , inv.address_id
   ,inv.invdate
   , SUM(inv.sales) as sales
   , SUM(inv.cost) as costs 
   FROM ifsinfo.hb_invoicing_all inv 
WHERE inv.site IN ('06','01')
    AND TO_DATE(inv.invdate) 
    between  
        to_date('01/10/'|| (to_number(to_char(sysdate,'YYYY'))-1),'dd/mm/rrrr')  
        and 
        to_date('30/09/'|| to_char(sysdate,'YYYY'),'dd/mm/rrrr')
GROUP BY inv.company
   , inv.customer_id
   , inv.address_id 
   , inv.invdate

This is just another approach that may be a little bit more 'programmer friendly' .

If you decide to review your dates one day - you wouldn't have to calculate what the 93 and 92 stand for in trunc(sysdate, 'YEAR')-92 (your approach).

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM