Component must be declared error (ORA-06550) - sql

Im getting this error:
ORA-06550:line 1, column 25:PLS-00302: component PA_EXCEPTION_LIST_UPDATE must be declared: line1, column 7:PL/SQL: Statement ignored.
I can't figure out what i did wrong.
PROCEDURE Pa_exception_list_update (p_ceid collection_entities.ceid%TYPE,
p_idusr users.idusr%TYPE
)
IS
v_idusr users.idusr%TYPE;
v_ceid collection_entities.ceid%TYPE;
BEGIN
INSERT INTO pa_exception_list(pa_exception_list_id,
ceid,
creation_date,
created_by)
VALUES(pa_exception_list_seq.nextval, p_ceid, SYSDATE, p_idusr);
END Pa_exception_list_update;

It looks like you are calling the procedure before it has been declared.
Look at this example.
Procedure A calls procedure B. But B is unknown at that moment.
create or replace package test is
begin
end test;
create or replace package body test is
procedure a
is
begin
b;
end;
procedure b is
begin
-- do someting
end;
end test;
Solution. Change the order of the procedures within the package or place the procedure in the package specification.
create or replace package test is
begin
procedure b;
end test;
create or replace package body test is
procedure a
is
begin
b;
end;
procedure b is
begin
-- do someting
end;
end test;

According error message the error appears at line 1.
In case this is a stand-alone procedure you must write like create or replace procedure Pa_exception_list_update ...
In case this is part of a PL/SQL Package then you must write like
CREATE OR REPLACE PACKAGE BODY <package name> AS
procedure Pa_exception_list_update ...

I think you are missing something when you declare.
p_ceid IN collection_entities.ceid%TYPE,
p_idusr IN users.idusr%TYPE

I also faced the same problem.
After checking I found that, the procedure i was calling did not exist in the package!.
Later changed the procedure name and it worked.

Related

Package and Procedure Compilation

Struggling for over an hour now... Why won't this compile?
The Body compiles fine:
create or replace package body "PKG_CUSTOMER" is
PROCEDURE Create_Customer
( pr_customer_id customer.Customer_id%type,
pr_country customer.country%type,
pr_first_name customer.first_name%type,
pr_last_name customer.last_name%type,
pr_birth_date customer.birth_date%type,
pr_customer_type customer.customer_type%type,
pr_address customer.address%type)
IS
BEGIN
INSERT INTO customer (Customer_ID,Country,First_Name,Last_Name,Birth_Date,Customer_Type,Address)
VALUES(pr_customer_id, pr_country, pr_first_name, pr_last_name, pr_birth_date, pr_customer_type, pr_address);
END Create_Customer;
PROCEDURE Delete_Customer(pr_customer_id customer.customer_id%type) IS
BEGIN
DELETE FROM order_line WHERE fk1_order_id IN (SELECT order_id FROM placed_order WHERE fk1_customer_id = pr_customer_id);
DELETE FROM placed_order WHERE fk1_customer_id = pr_customer_id;
DELETE FROM customer WHERE customer_id = pr_customer_id;
END Delete_Customer;
end "PKG_CUSTOMER";​
But the specification won't compile:
create or replace package PKG_CUSTOMER as
Procedure CREATE_CUSTOMER;
Procedure DELETE_CUSTOMER;
end;​
I am getting this error:
Compilation failed,line 3 (21:20:46)
PLS-00323: subprogram or cursor 'CREATE_CUSTOMER' is declared in a package specification and must be defined in the package bodyCompilation failed,line 4 (21:20:46)
PLS-00323: subprogram or cursor 'DELETE_CUSTOMER' is declared in a package specification and must be defined in the package body
I'm using Oracle APEX.
The package specification has to provide the complete specification for the procedures that you want to expose. That includes the parameters. Assuming that you want to make both of the procedures that you declared in the package available to callers outside of the package
create or replace package PKG_CUSTOMER
as
Procedure CREATE_CUSTOMER(
pr_customer_id customer.Customer_id%type,
pr_country customer.country%type,
pr_first_name customer.first_name%type,
pr_last_name customer.last_name%type,
pr_birth_date customer.birth_date%type,
pr_customer_type customer.customer_type%type,
pr_address customer.address%type);
Procedure DELETE_CUSTOMER(pr_customer_id customer.customer_id%type);
end;​
If your intention is to declare a CREATE_CUSTOMER and a DELETE_CUSTOMER procedure that each accept 0 arguments, you would need to implement those procedures in the package body as well.

Returning a cursor from a procedure

I am trying to return a cursor from a procedure which will display the contents of a table invoice. The package and procedure was successfully created but when I run the line - Exec CursorPckg.CursorTest_Proc(); I get the following error component 'CURSORTEST_PROC' must be declared any ideas? I'm running SQL*PLUS
CREATE or REPLACE PACKAGE CursorPckg
IS
TYPE salary_type IS REF CURSOR RETURN Invoice%ROWTYPE;
END CursorPckg;
CREATE OR REPLACE PACKAGE BODY CursorPckg AS
PROCEDURE CursorTest_Proc (c1 OUT CursorPckg.salary_type)
IS
BEGIN
OPEN c1 FOR
SELECT * FROM Invoice;
END CursorTest_Proc;
END CursorPckg;
You need to add procedure declaration in package declaration for it to be accessible from outside your package.
Like this:
CREATE or REPLACE PACKAGE CursorPckg
IS
TYPE salary_type IS REF CURSOR RETURN Invoice%ROWTYPE;
PROCEDURE CursorTest_Proc (c1 OUT CursorPckg.salary_type);
END CursorPckg;
Edit:
To answer Your comment. You cannot execute this procedure without providing parameter of type CursorPckg.salary_type.

How can I declare and initialize a package variable by SELECT

Can someone help me understand why I can declare a hardcoded date value in a package but not assign the value from a query? I've seen a number of examples (including the reference book) that show declarations of hardcoded values but I'm unable to locate examples of assigning values to variable through queries.
This is allowed:
create or replace package body PACKAGE_NAME AS
tDate DATE := '2012-05-30';
-- ...procedures follow
This is allowed:
create or replace package body PACKAGE_NAME AS
tDate DATE := sysdate;
This is not allowed:
create or replace package body PACKAGE_NAME AS
tDate DATE := select MAX(date_) from Table_Name;
I've tried a number of ways and I'm ok with it not working - I can use it as needed in the procedures themselves. But I'd like to know why I can't assign a value to tDate this way? The specific error is:
Encountered the symbol 'SELECT' when expecting ....
Adding that I can get variable values assigned through queries in a stored procedure but the same process does not seem to work for package body.
PROCEDURE Proc_Name IS
tDate Date;
BEGIN
SELECT MAX(date_) into tDate from Table_Name;
You need to create a package initialization block in your package body. This is a relatively arcane bit of PL/SQL package lore, but it's there and can be used. Here's an example:
CREATE OR REPLACE PACKAGE TEST_PKG IS
tDate DATE;
END TEST_PKG;
Here we've created a package spec which contains only a single DATE variable. Now we'll create a simple body which initializes that variable using a SELECT statement:
CREATE OR REPLACE PACKAGE BODY TEST_PKG IS
-- package-private variables go first (if any)
(...)
-- then the public functions/procedures
(...)
-- then a final BEGIN-END block which is the package initialization block
BEGIN
SELECT SYSDATE
INTO tDATE
FROM DUAL;
EXCEPTION -- you can have exception handlers in your initialization block
WHEN OTHERS THEN
NULL; -- pointless here, but this is just an example
RAISE;
END TEST_PKG;
Now if you execute the following:
begin
-- Test statements here
DBMS_OUTPUT.PUT_LINE('TEST_PKG.tDate = ' || TEST_PKG.tDate);
end;
it should print the current date.
Share and enjoy.
You need to use INTO when selecting directly into a variable.
select MAX(date_)
INTO tDate
from Table_Name;

Oracle create procedure query throwing error

I have one create procedure query i m trying to execute it in Oracle Database.Below is the query :
CREATE OR REPLACE PROCEDURE TEST_PROC IS
TYPE TESTTABLE IS TABLE OF a.TEST102%ROWTYPE;
Synatax of the query seems to be fine but when i am executing it is throwing below sql exception.
Encountered the symbol "end-of-file" when expecting one of the following:
. ( # % ; not null range alter character
Trying to find out the issue trying all possible ways from past two days but i did not get any idea wheres the issue is.Can anyone please suggest what is wrong with the query???? Would be great if some one can help me out here.
Procedures must have BEGIN..END block.
Here is a procedure that does not do anything.
CREATE OR REPLACE PROCEDURE TEST_PROC
IS
TYPE TESTTABLE IS TABLE OF dual%ROWTYPE;
BEGIN
NULL;
END;
the following will work:
CREATE TABLE TEST102(id number);
CREATE OR REPLACE PROCEDURE TEST_PROC IS
TYPE TESTTABLE IS TABLE OF TEST102%ROWTYPE;
BEGIN
NULL; -- insert procedure body here
END;

Dynamic SQL not working as expected

create or replace procedure createtables
Authid current_user as
begin
execute immediate 'create table newcustomer as select * from customer';
end;
create or replace procedure e
is
begin
createtables;
select * from newcustomer;
end;
I got two procedures above. first one will create a new tables called newcustomer, second procedure will call the first procedure and query to the newcustomer table. when I try to compile this code, it says the table is not yet created, I don't really get it as I have called createtables procedure so I assume I have created the table.
Any help will be appreciated. Thanks
Compiling the second procedure without executing the first procedure first will fail, since the table has not been created.
You cannot compile a procedure that relies on objects that do not exist.
Use EXEC createtables before creating procedure e, and do not call createtables in there.
Procedure e will also not compile because you are not using the results of select * from newcustomer as cursor or store the results into variables.
EDIT:
Instead of procedures, you could use an anonymous block. Put the following into a file and execute it (via SQL*Plus for example):
Create Table newcustomer As Select * From customer;
Begin
Null; --# Do something with your new table in here.
End;
/