Search code examples
stored-proceduresplsqlidentifier

Oracle PL/SQL procedure identifier must be declared error


I am very new to SQL and PL/SQL. I am writing a procedure to take a museum, average the price of art, then increase the average by a percent. The user enters the museum ID (musmID) and percent increase. If the percent is too high there is an exception raised. If the musmID entered does not match one on the table, an exception is raised. Output is museum name, old avg price, and new avg price. So far it will only work when the exception for invalid musmID is not written. I keep getting the same error of PLS-00201:identifier 'MUMSID' must be declared.

Table 1 is arts and column names are musmID(FK) and price. Table 2 is museums and column names are museum and musmID(PK).

My code:

CREATE OR REPLACE PROCEDURE proc_second (p_musmID IN arts.musmID%TYPE,
p_percent IN NUMBER) IS

v_musmID arts.musmID%TYPE;
v_oldavg arts.price%TYPE;
v_newavg arts.price%TYPE;
v_musmName museums.museum%TYPE; 
too_high EXCEPTION;
musmID_invalid EXCEPTION;

BEGIN
IF p_percent > 40 THEN
  raise too_high;
END IF;
IF musmID != p_musmID THEN
  raise musmID_invalid;
END IF;

SELECT musmID, AVG(price) INTO v_musmID, v_oldavg from arts
WHERE musmID = p_musmID
GROUP BY musmID;

SELECT museum INTO v_musmName from museums
WHERE musmId = p_musmID;

v_newavg := v_oldavg * (1 + (p_percent/100));

dbms_output.put_line (v_musmname || ' ' || v_oldavg || ' ' || v_newavg);

EXCEPTION
WHEN too_high THEN
dbms_output.put_line ('Specify less than 40 percent increase');
WHEN musmID_invalid THEN
dbms_output.put_line ('You entered an invalid museum ID');

END;
/

Warning: Procedure created with compilation errors.

These are the errors i am getting.

LINE/COL ERROR
-------- -----------------------------------------------------------------
15/3     PL/SQL: Statement ignored
15/6     PLS-00201: identifier 'MUSMID' must be declared

I know it is probably something basic i am not seeing but so far if i get rid of the errors, the procedure raises the musmID_invalid exception no matter what is entered.


Solution

  • Huh. This code is wrongly arranged, as far as I can tell. You're first checking a variable, and then fetch its value.

    I've created two dummy tables, just to make the procedure compile.

    SQL> create table arts
      2    (musmid number,
      3     price  number);
    
    Table created.
    
    SQL> create table museums
      2    (musmid number,
      3     museum number);
    
    Table created.
    

    Now, the procedure: it seems that you don't need V_MUSMID variable at all, because it is equal to P_MUSMID parameter (see the SELECT which selects the AVG(PRICE) and its WHERE clause). It means that you can use P_MUSMID throughout the code, instead of V_MUSMID.

    It also means that MUSMID_INVALID will never be raised; you should, though, handle the NO_DATA_FOUND which will be raised if you pass a non-existent P_MUSMID.

    So, I removed what I thought you don't need and - this is the remaining code; see if it does any good.

    SQL> create or replace procedure proc_second (p_musmid  in arts.musmid%type,
      2                                           p_percent in number)
      3  is
      4    v_oldavg       arts.price%type;
      5    v_newavg       arts.price%type;
      6    v_musmname     museums.museum%type;
      7    too_high       exception;
      8  begin
      9    if p_percent > 40 then
     10       raise too_high;
     11    end if;
     12
     13    select m.museum, avg(a.price)
     14      into v_musmname, v_oldavg
     15      from arts a join museums m on m.musmid = a.musmid
     16      where a.musmid = p_musmid
     17      group by m.museum;
     18
     19    v_newavg := v_oldavg * (1 + (p_percent/100));
     20
     21    dbms_output.put_line (v_musmname || ' ' || v_oldavg || ' ' || v_newavg);
     22
     23  exception
     24    when too_high then
     25      dbms_output.put_line ('Specify less than 40 percent increase');
     26    when no_data_found then
     27      dbms_output.put_line ('You entered an invalid museum ID');
     28  end;
     29  /
    
    Procedure created.
    
    SQL> exec proc_second(1, 20);
    You entered an invalid museum ID
    
    PL/SQL procedure successfully completed.
    
    SQL>