Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

PLS-00201: identifier 'ADD_ORDER' must be declared

Posted on 2008-10-11
22
Medium Priority
?
2,933 Views
Last Modified: 2013-12-18
Hi Experts:
I am taking Oracle at school and I cannot figure out why my stored package\procedure is coming bak with "PLS-00201: identifier 'ADD_ORDER' must be declared". I am ruuning this locally on SGL PLUS, Oracle 10g, My code is listed below,
Thanks!

Kevin


CREATE OR REPLACE PACKAGE Process_Orders AS
	PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
			p_eno IN orders.eno%TYPE,
			p_received IN OUT orders.received%TYPE);
			p_creation_date DATE;
			p_last_update_date DATE;
			p_created_by VARCHAR2(10);
			p_last_update_by VARCHAR2(10);	
 
END Process_Orders;
/
show errors
set echo on
 
DROP SEQUENCE Order_number_seq;
CREATE SEQUENCE Order_number_seq
    MINVALUE 1
    MAXVALUE 1000000
    START WITH 1
    INCREMENT BY 1;
 
CREATE OR REPLACE PACKAGE BODY Process_Orders AS
  -- Add a new order for the specified class.
  -- Order_number_seq should be used to populate the order number (ONO) column.
	PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
			p_eno IN orders.eno%TYPE,
			p_received IN OUT orders.received%TYPE) AS
	BEGIN
	IF p_received = NULL
		THEN p_received := CURRENT_DATE;
	END IF;
 
	SELECT user INTO p_created_by FROM dual;
	SELECT user INTO p_last_update_by FROM dual;
	
	INSERT INTO orders (ono,cno,eno,received,creation_date,created_by,last_update_date,last_update_by)
			VALUES (Order_number_seq.NextVal,p_cno,p_eno,p_received, p_creation_date,
				p_created_by,p_last_update_date,p_last_update_by );
	
	--Exception Handler:
	  EXCEPTION
    		WHEN DUP_VAL_ON_INDEX THEN
      			DBMS_OUTPUT.PUT_LINE('ERROR - Unique Constraint Violation: ' || SQLERRM);
    		WHEN OTHERS THEN
      			DBMS_OUTPUT.PUT_LINE('Undentified error occured: ' || SQLERRM); 
END Add_Order;
 
END Process_Orders;
/
 
show errors

Open in new window

0
Comment
Question by:k_smee
  • 11
  • 9
  • 2
22 Comments
 
LVL 74

Expert Comment

by:sdstuber
ID: 22694424
can you show you show your entire output from running all of the above?  
0
 

Author Comment

by:k_smee
ID: 22694457
Here is what I get in the SQL PLUS starting with running the stored procedure and then trying to execute it:
SQL> @Pack.sql
SQL> CREATE OR REPLACE PACKAGE Process_Orders AS
  2          PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
  3                          p_eno IN orders.eno%TYPE,
  4                          p_received IN OUT orders.received%TYPE);
  5                          p_creation_date DATE;
  6                          p_last_update_date DATE;
  7                          p_created_by VARCHAR2(10);
  8                          p_last_update_by VARCHAR2(10);
  9  
 10  END Process_Orders;
 11  /
 
Package created.
 
SQL> show errors
No errors.
SQL> set echo on
SQL> 
SQL> DROP SEQUENCE Order_number_seq;
 
Sequence dropped.
 
SQL> CREATE SEQUENCE Order_number_seq
  2      MINVALUE 1
  3      MAXVALUE 1000000
  4      START WITH 1
  5      INCREMENT BY 1;
 
Sequence created.
 
SQL> 
SQL> CREATE OR REPLACE PACKAGE BODY Process_Orders AS
  2    -- Add a new order for the specified class.
  3    -- Order_number_seq should be used to populate the order number (ONO) column.
  4  
  5  
  6          PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
  7                          p_eno IN orders.eno%TYPE,
  8                          p_received IN OUT orders.received%TYPE) AS
  9          BEGIN
 10          IF p_received = NULL
 11                  THEN p_received := CURRENT_DATE;
 12          END IF;
 13          SELECT user INTO p_created_by FROM dual;
 14          SELECT user INTO p_last_update_by FROM dual;
 15          INSERT INTO orders (ono,cno,eno,received,creation_date,created_by,last_update_date,last_u
 16                          VALUES (Order_number_seq.NextVal,p_cno,p_eno,p_received, p_creation_date,
 17                                  p_created_by,p_last_update_date,p_last_update_by );
 18  
 19  END Add_Order;
 20  
 21  END Process_Orders;
 22  /
 
Package body created.
 
SQL> 
SQL> show errors
No errors.
SQL> 
SQL> execute Add_Order(10,12,'23-OCT-08');
BEGIN Add_Order(10,12,'23-OCT-08'); END;
 
      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'ADD_ORDER' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
 
 
SQL> 

Open in new window

0
 
LVL 42

Accepted Solution

by:
dqmq earned 200 total points
ID: 22694519
Try explicitly referencing the package.  I believe, like this:

execute Process_Orders.Add_Order(10,12,'23-OCT-08');

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 74

Expert Comment

by:sdstuber
ID: 22694523
yes, the problem isn't in compiling the procedure it's in calling it and, as noted,  you must reference the package to call it's members
0
 

Author Comment

by:k_smee
ID: 22694534
This is looking alot better, but I am getting a new problem - a small one I think. See the code snippet. Did I write this part correctly?

p_received IN OUT orders.received%TYPE);



SQL> execute Process_Orders.Add_Order(10,12,'23-OCT-08');
BEGIN Process_Orders.Add_Order(10,12,'23-OCT-08'); END;
 
                                     *
ERROR at line 1:
ORA-06550: line 1, column 38:
PLS-00363: expression '23-OCT-08' cannot be used as an assignment target
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Open in new window

0
 
LVL 42

Expert Comment

by:dqmq
ID: 22694590
It's difficult to advise because we don't know what your procedure is supposed to do.  But here is the issue.

An OUT parameter is intended to pass data from the procedure back to the caller.   Obviously, you cannot do that when the argument passed from the caller is a literal.

You should always pass OUT parameters in variables.  





0
 
LVL 42

Expert Comment

by:dqmq
ID: 22694626
It's difficult to advise because we don't know what your procedure is supposed to do.  But here is the issue.

An OUT parameter is intended to pass data from the procedure back to the caller.   Obviously, you cannot do that when the argument passed from the caller is a literal.

You should always pass OUT parameters in variables.  





0
 

Author Comment

by:k_smee
ID: 22694648
It is supposed enter an order in the ORDERS table. If the date parameter of Add_Order() is NULL (no date entered) use the current date for the date received.
0
 
LVL 42

Expert Comment

by:dqmq
ID: 22694923
Then change it from IN OUT to IN.  You understand the difference, right?
0
 

Author Comment

by:k_smee
ID: 22694947
I changed from IN OUT to IN, but I can't seem to get the procedure to test the p_received for a "zero length" string or NULL. How can I test p_received for zero length? I tried "IF p_received = NULL OR LENGTH(p_received) < 1" and this didn't work. See belowfor my current effort:
 CREATE OR REPLACE PACKAGE Process_Orders AS
	PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
			p_eno IN orders.eno%TYPE,
			p_received IN DATE);
			p_creation_date DATE;
			p_last_update_date DATE;
			p_created_by VARCHAR2(10);
			p_last_update_by VARCHAR2(10);
			p_date DATE;	
 
END Process_Orders;
/
show errors
set echo on
 
DROP SEQUENCE Order_number_seq;
CREATE SEQUENCE Order_number_seq
    MINVALUE 1
    MAXVALUE 1000000
    START WITH 1
    INCREMENT BY 1;
 
CREATE OR REPLACE PACKAGE BODY Process_Orders AS
  -- Add a new order for the specified class.
  -- Order_number_seq should be used to populate the order number (ONO) column.
 
 
	PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
			p_eno IN orders.eno%TYPE,
			p_received IN DATE) AS
	BEGIN
-- here is whre i am stuck now
	IF LENGTH(p_received) < 2 
		THEN p_date := CURRENT_DATE;
	ELSE
		p_date := p_received;
	END IF;
 
	SELECT user INTO p_created_by FROM dual;
	SELECT user INTO p_last_update_by FROM dual;
	p_creation_date := CURRENT_DATE;
	p_last_update_date := CURRENT_DATE;
	INSERT INTO orders (ono,cno,eno,received,creation_date,created_by,last_update_date,last_update_by)
			VALUES (Order_number_seq.NextVal,p_cno,p_eno,p_date, p_creation_date,
				p_created_by,p_last_update_date,p_last_update_by );
 
END Add_Order;
 
END Process_Orders;
/
 
show errors
			

Open in new window

0
 
LVL 42

Expert Comment

by:dqmq
ID: 22694980
Given this is a school assignment, I cannot do your work.  But here's a clue:

'p_received IN DATE' means that p_received is a DATE, not a STRING.  Therefore, it cannot contain a zero-length string.  
0
 

Author Comment

by:k_smee
ID: 22694992
So I might be able to convert to a string and test it then?
0
 
LVL 42

Expert Comment

by:dqmq
ID: 22695015
Why to you want to test it for a zero-length string if it cannot contain a zero-length string?  If it cannot contain a zero-length string before you convert it, then it will not contain one after you convert it.

A DATE can only contain two things:  a date and null.  
0
 

Author Comment

by:k_smee
ID: 22695048
When I excute this: execute Process_Orders.Add_Order(15,21,''); The procedure does not recognize this as a NULL in the IF statement; it goes straight to the ELSE branch. Our requirement is that if the date is NULL, we use the cuurent date for the "received" date. It thought this IF statement would work fine:

  IF p_received = NULL
          THEN p_date := CURRENT_DATE;
  ELSE
          p_date := p_received;
  END IF;

The way it works now is that it either enters a NULL, if nothing is entered in Add_Orders(), or the date, if one entered in the Add_Orders().
0
 
LVL 42

Expert Comment

by:dqmq
ID: 22695106
I see. I'm amused.  Learn this lesson well.

To illustrate your problem, change the code like this:

 IF p_received = NULL
          THEN p_date := '06/06/2006';
 ELSE
 IF p_received <> NULL
          THEN p_date := '07/07/2007';
 ELSE
         p_date := '08/08/2008';
 END IF;
 END IF;


Now test with NULL, '', and a valid date

0
 

Author Comment

by:k_smee
ID: 22696056
Ok..I had to take some of the literals out and replace them with variables to get the desired result I left the <> NULL as a literal. Here is what I have:
      BEGIN
       IF p_received = NULL
          THEN p_date := CURRENT_DATE;
       ELSE
       IF p_received <> NULL
          THEN p_date := '30-OCT-08';
       ELSE
         p_date := CURRENT_DATE;
       END IF;
       END IF;
The "IF p_received = NULL" piece always evaluates to "p_date = CURRENT_DATE". So wether I enter a date or not I get the current date inserted into the record...
0
 

Author Closing Comment

by:k_smee
ID: 31505318
As for your last comment, "I am amused.", I am not; and not sure why you would be. An online class is a very tough environment to learn a technical subject. Thanks for he help with this problem, it definitely made a difference..
0
 
LVL 42

Expert Comment

by:dqmq
ID: 22698070
The purpose of my example was a test so you could tell which leg of the IF statement got exercised. By using Current_Date on two legs, you sort of defeat the purpose.  

Please bear with me, because there is a very important lesson to be learned.  I do not think you grasp it yet.

The above code falls thru to p_date := CURRENT_DATE.  That happens regardless of what is passed in p_received.

The reason is because NULL is neither equal nor unequal to anything.  Even these expressions are false:
  IF NULL = NULL
  IF NULL <> NULL

To evaluate whether a variable contains NULL, you must use the ISNULL function.  Instead of this:
   IF p_received = NULL

Do this:
   IF ISNULL(p_received)

You should discover that a DATE variable cannot hold ''.  When you try to pass '' in a DATE argument, it gets implicitly converted to NULL.  However, you fail to detect the NULL date because the way you are testing p_received ALWAYS evaluates to false, regardless of what it contains.

To summarize,  you should have learned:
1.  A DATE variable can only hold two things:  a date and NULL.
2.  When you assign '' to a DATE variable, it implicitly gets cast as NULL
3.  NULL is not equal to anything, including itself
4.  To test for NULL, use the ISNULL() function, not the traditional  =<> operators.









 




 







 





0
 

Author Comment

by:k_smee
ID: 22698149
Thanks for the clarification on this. I tried a lot of things to test for NULL before  - and I think ISNULL() was one of them. Do you have to somehow delare the Oracle function before you use it? When I try to use ISNULL(p_received) I get:

Errors for PACKAGE BODY PROCESS_ORDERS:

LINE/COL ERROR
-------- -----------------------------------------------------------------
10/3     PL/SQL: Statement ignored
10/6     PLS-00201: identifier 'ISNULL' must be declared
SQL>
SQL>
0
 

Author Comment

by:k_smee
ID: 22698214
It works if I do:
IF p_received IS NULL
THEN <do something>
Here is the working product:

CREATE OR REPLACE PACKAGE Process_Orders AS
      PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
                  p_eno IN orders.eno%TYPE,
                  p_received IN DATE);
                  p_creation_date DATE;
                  p_last_update_date DATE;
                  p_created_by VARCHAR2(10);
                  p_last_update_by VARCHAR2(10);      
                  p_date DATE;
END Process_Orders;
/
show errors
set echo on

DROP SEQUENCE Order_number_seq;
CREATE SEQUENCE Order_number_seq
    MINVALUE 1
    MAXVALUE 1000000
    START WITH 1
    INCREMENT BY 1;

CREATE OR REPLACE PACKAGE BODY Process_Orders AS
  -- Add a new order for the specified class.
  -- Order_number_seq should be used to populate the order number (ONO) column.


      PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
                  p_eno IN orders.eno%TYPE,
                  p_received IN DATE) AS
      BEGIN
       IF p_received IS NULL
                           THEN p_date := CURRENT_DATE;
       ELSE p_date := p_received;
                      END IF;

      SELECT user INTO p_created_by FROM dual;
      SELECT user INTO p_last_update_by FROM dual;
      p_creation_date := CURRENT_DATE;
      p_last_update_date := CURRENT_DATE;
      INSERT INTO orders (ono,cno,eno,received,creation_date,created_by,last_update_date,last_update_by)
                  VALUES (Order_number_seq.NextVal,p_cno,p_eno,p_date, p_creation_date,
                        p_created_by,p_last_update_date,p_last_update_by );
      COMMIT;

END Add_Order;

END Process_Orders;
/


0
 
LVL 42

Expert Comment

by:dqmq
ID: 22698306
My mistake, for ORACLE, use IS NULL not the ISNULL() function.  Now your logic is looking much better.

What do you of streamlining, like this:


 




 PROCEDURE Add_Order(p_cno IN orders.cno%TYPE,
                  p_eno IN orders.eno%TYPE,
                  p_received IN DATE) AS
  BEGIN
  INSERT INTO orders (ono,cno,eno,received,creation_date,created_by,last_update_date,last_update_by)
  SELECT Order_number_seq.NextVal,p_cno,p_eno,NVL(p_date,CURRENT_DATE),CURRENT_DATE,USER,CURRENT_DATE,USER FROM DUAL;
  COMMIT;
 
END Add_Order;

Open in new window

0
 

Author Comment

by:k_smee
ID: 22698401
That works great! Much simpler, too. I like how you used the NVL() function to eliminate the IF..
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had to make fundamental changes to a table in Oracle, but haven't been able to get any downtime?  I'm talking things like: * Dropping columns * Shrinking allocated space * Removing chained blocks and restoring the PCTFREE * Re-or…
How to Unravel a Tricky Query Introduction If you browse through the Oracle zones or any of the other database-related zones you'll come across some complicated solutions and sometimes you'll just have to wonder how anyone came up with them.  …
This video shows how to copy a database user from one database to another user DBMS_METADATA.  It also shows how to copy a user's permissions and discusses password hash differences between Oracle 10g and 11g.
Via a live example, show how to take different types of Oracle backups using RMAN.
Suggested Courses

783 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question