How to create a Package with Procedure in it? Procedure will take designation and incentive as input and update the employee salary by adding the incentive for the given designation. Display the number of employee records that have got updated, e.g. ‘3 employee record(s) are updated’.
I have a table EMPLOYEE, with EMP_ID, EMP_NAME, SALARY and DESIGNATION.
The given Functional Requirements are:
Package name as EMP_DESIGNATION, and
Procedure signature:
EMP_DETAILS(design employee.designation%TYPE, incentive number);
The code which I tried is -
set serveroutput on;
CREATE OR REPLACE PACKAGE EMP_DESIGNATION AS
PROCEDURE EMP_DETAILS(
design employee.designation%TYPE,
incentive NUMBER) IS
BEGIN
UPDATE employee SET employee.salary = employee.salary + incentive
WHERE employee.designation = design;
dbms_output.put_line(SQL%ROWCOUNT || ' employee record(s) are updated');
END EMP_DESIGNATION;
END;
/
The output is-
Warning: Package Body created with compilation errors.
BEGIN
*
ERROR at line 1:
ORA-04063: package body "P10017.EMP_DESIGNATION" has errors
ORA-06508: PL/SQL: could not find program unit being called:
"P10017.EMP_DESIGNATION"
ORA-06512: at line 2
How to solve this error? Please help. Thank you in advance.
PL/SQL: Statement ignored
You have to create a package specification first, then its body. Something like this:
SQL> CREATE OR REPLACE PACKAGE emp_designation
2 AS
3 PROCEDURE emp_details (design employee.designation%TYPE, incentive NUMBER);
4 END emp_designation;
5 /
Package created.
SQL>
SQL> CREATE OR REPLACE PACKAGE BODY emp_designation
2 AS
3 PROCEDURE emp_details (design employee.designation%TYPE, incentive NUMBER)
4 IS
5 BEGIN
6 UPDATE employee
7 SET employee.salary = employee.salary + incentive
8 WHERE employee.designation = design;
9
10 DBMS_OUTPUT.put_line (
11 SQL%ROWCOUNT || ' employee record(s) are updated');
12 END emp_details;
13 END emp_designation;
14 /
Package body created.
SQL>
Related
This is the question
-Create customers table and add these columns:
Id
Name
AGE
ADDRESS
SALARY
-Add 10 rows.
-Create a package with three procedures:
one that add a customer to the table.
one that removes a customer from the table.
one that lists all the customers.
-Create customers table and add these columns:
Id
Name
AGE
ADDRESS
SALARY
-Add 10 rows.
-Create a package with three procedures:
one that add a customer to the table.
one that removes a customer from the table.
one that lists all the customers.
CREATE TABLE customer(
customer_id NUMBER NOT NULL,
customer_name VARCHAR2(50) NOT NULL,
customer_age NUMBER NOT NULL,
customer_address VARCHAR2(50) NOT NULL,
customer_salary NUMBER NOT NULL,
PRIMARY KEY(customer_id)
);
INSERT INTO customer
VALUES
(1,'Ahemed',22,'wq1',2500);
INSERT INTO customer
VALUES
(2,'salem',24,'wq2',2000);
INSERT INTO customer
VALUES
(3,'Aboud',26,'wq3',2200);
INSERT INTO customer
VALUES
(4,'Tarek',27,'wq4',2100);
INSERT INTO customer
VALUES
(5,'Hazem',33,'wq5',3000);
INSERT INTO customer
VALUES
(6,'Hayder',32,'wq6',2300);
INSERT INTO customer
VALUES
(7, 'Sammy',35,'wq7',2700);
INSERT INTO customer
VALUES
(8,'Mohammed',20,'wq8',4000);
INSERT INTO customer
VALUES
(9,'Tayseer',18,'wq9',3600);
INSERT INTO customer
VALUES
(10,'Hamoud',40,'wq10',3100);
CREATE OR REPLACE PACKAGE mypackage AS
PROCEDURE add_customer(c_id customer.customer_id%type,
c_name customer.customer_name%type,
c_age customer.customer_age%type,
c_address customer.customer_address%type,
c_salary customer.customer_salary%type);
PROCEDURE remove_customer(c_id customer.customer_id%type);
PROCEDURE list_customer;
END mypackage ;
CREATE OR REPLACE PACKAGE BODY mypackage AS
PROCEDURE add_customer(c_id customer.customer_id%type,
c_name customer.customer_name%type,
c_age customer.customer_age%type,
c_address customers.address%type,
c_salary customer.customer_salary%type)
IS
BEGIN
INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
VALUES(c_id, c_name, c_age, c_address, c_salary);
END add_customer;
PROCEDURE remove_customer(c_id customer.customer_id%type) IS
BEGIN
DELETE FROM customer
WHERE customer_id= c_id;
END remove_customer;
PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
BEGIN
select * from customer;
END list_customer;
If i create this package the error is(The package is configured with translation errors) how can i solve it?
Table and package specification are OK (kind of):
SQL> CREATE TABLE customer(
2 customer_id NUMBER NOT NULL,
3 customer_name VARCHAR2(50) NOT NULL,
4 customer_age NUMBER NOT NULL,
5 customer_address VARCHAR2(50) NOT NULL,
6 customer_salary NUMBER NOT NULL,
7 PRIMARY KEY(customer_id)
8 );
Table created.
SQL> CREATE OR REPLACE PACKAGE mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type);
7
8 PROCEDURE remove_customer(c_id customer.customer_id%type);
9 PROCEDURE list_customer;
10 END mypackage ;
11 /
Package created.
But then, for some reason, you didn't follow the same recipe for package body:
SQL> CREATE OR REPLACE PACKAGE BODY mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customers.address%type,
6 c_salary customer.customer_salary%type)
7 IS
8 BEGIN
9 INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
10 VALUES(c_id, c_name, c_age, c_address, c_salary);
11 END add_customer;
12
13 PROCEDURE remove_customer(c_id customer.customer_id%type) IS
14 BEGIN
15 DELETE FROM customer
16 WHERE customer_id= c_id;
17 END remove_customer;
18
19 PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
20 BEGIN
21 select * from customer;
22 END list_customer;
23 end mypackage;
24 /
Warning: Package Body created with compilation errors.
What's wrong?
SQL> show err
Errors for PACKAGE BODY MYPACKAGE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
19/41 PLS-00103: Encountered the symbol "," when expecting one of the
following:
in out <an identifier> <a double-quoted delimited-identifier>
table ... columns long double ref char standard time
timestamp interval date binary national character nchar
20/4 PLS-00103: Encountered the symbol "BEGIN" when expecting one of
the following:
not null of nan infinite dangling a empty json
SQL>
Line #19 is wrong:
19 PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
So: if - apparently - you do know how to use parameters while declaring procedures, why didn't you do the same for list_customer? Besides, it wouldn't work anyway - in PL/SQL, a SELECT must have an INTO (and your procedure doesn't). I guess that at customer_id should be passed as a parameter (so I'm doing that in my example).
Moreover, all procedures you declare in package specification must exist in package body, with exactly the same description (you've used customer.address%type but that column doesn't exist in the table).
So, when fixed: specification:
SQL> CREATE OR REPLACE PACKAGE mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type);
7
8 PROCEDURE remove_customer(c_id customer.customer_id%type);
9 PROCEDURE list_customer (p_customer_id customer.customer_id%type);
10 END mypackage ;
11 /
Package created.
Body:
SQL> CREATE OR REPLACE PACKAGE BODY mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type)
7 IS
8 BEGIN
9 INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
10 VALUES(c_id, c_name, c_age, c_address, c_salary);
11 END add_customer;
12
13 PROCEDURE remove_customer(c_id customer.customer_id%type) IS
14 BEGIN
15 DELETE FROM customer
16 WHERE customer_id= c_id;
17 END remove_customer;
18
19 PROCEDURE list_customer(p_customer_id in customer.customer_id%type)
20 --,customer_name,customer_age ,customer_address ,customer_salar) IS
21 is
22 l_row customer%rowtype;
23 BEGIN
24 select * into l_row from customer where customer_id = p_customer_id;
25 END list_customer;
26 end mypackage;
27 /
Package body created.
SQL>
This, at least, compiles. Does it do what you wanted it, I didn't try - I'll leave it to you.
Package
CREATE OR REPLACE PACKAGE EMP_DESIGNATION
AS
PROCEDURE EMP_DETAILS
(
design IN employee.designation%TYPE,
incentive IN number
);
END EMP_DESIGNATION;
CREATE OR REPLACE PACKAGE BODY EMP_DESIGNATION
AS
PROCEDURE EMP_DETAILS
(
design IN employee.designation%TYPE,
incentive IN number
)
AS
BEGIN
update Employee
SET SALARY = SALARY + incentive
where DESIGNATION = design;
dbms_output.put_line(SQL%rowcount || ' employee record(s) are updated');
END EMP_DETAILS;
END EMP_DESIGNATION;
/
Actually both this code is in same file I am getting bellow error message.
ERROR at line 2:
ORA-06550: line 2, column 4:
PLS-00905: object P11169.EMP_DESIGNATION is invalid
ORA-06550: line 2, column 4:
PL/SQL: Statement ignored
Can some one please help me out in figuring out the error.
If you use SQL*Plus, run
show err
or - elsewhere - query user_errors; both will tell you what's invalid.
When I tried it (with a dummy employee table), everything seems to be fine:
SQL> create table employee(designation number, salary number);
Table created.
SQL> CREATE OR REPLACE PACKAGE EMP_DESIGNATION
2 AS
3 PROCEDURE EMP_DETAILS
4 (
5 design IN employee.designation%TYPE,
6 incentive IN number
7 );
8
9 END EMP_DESIGNATION;
10 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY EMP_DESIGNATION
2 AS
3 PROCEDURE EMP_DETAILS
4 (
5 design IN employee.designation%TYPE,
6 incentive IN number
7 )
8 AS
9 BEGIN
10 update Employee
11 SET SALARY = SALARY + incentive
12 where DESIGNATION = design;
13 dbms_output.put_line(SQL%rowcount || ' employee record(s) are updated');
14
15 END EMP_DETAILS;
16 END EMP_DESIGNATION;
17 /
Package body created.
SQL>
I get these errors during a creation of a trigger but I don't understand why
create or replace NONEDITIONABLE TRIGGER magazzino_bef_ins
BEFORE INSERT ON MAGAZZINO
FOR EACH ROW
DECLARE
tempcodice varchar2(8);
cacc char(3);
ogg int;
CURSOR cursore_disp IS
SELECT cacciatore, oggetto
FROM TABLE EDDY.disponibilita
WHERE ID_DISPONIBILITA = :NEW.disponibilità;
BEGIN
CURSOR cursore_disp IS
SELECT cacciatore, oggetto
FROM TABLE DISPONIBILITA
WHERE ID_DISPONIBILITA = :NEW.disponibilità;
open cursore_disp;
fetch cursore_disp into cacc,ogg;
temp:= pk_gestione_magazzino.genera_catalogo(cacc,ogg);
:new.codcatalogo:=temp;
END;
The errors are:
Error(5,9): PL/SQL: SQL Statement ignored
Errore(6,20): PL/SQL: ORA-00906: missing opening parenthesis
Errore(9,8): PLS-00103: encountered symbol "CURSORE_DISP" instead of one of the following: := . ( # % ;
I can't understand these errors, I'm just trying to take the values from a table in where the id inserted is equal in the other table.
Here's how. I created test environment which is kind of stupid, but it makes the following code work.
SQL> create table magazzino (disponibilita number, codcatalogo varchar2(8));
Table created.
SQL> create table disponibilita (cacciatore char(3), oggetto number, id_disponibilita number);
Table created.
SQL> create or replace package pk_gestione_magazzino as
2 function genera_catalogo (cacc number, ogg number) return varchar2;
3 end;
4 /
Package created.
SQL> create or replace package body pk_Gestione_magazzino as
2 function genera_catalogo (cacc number, ogg number) return varchar2 is
3 begin
4 return 'Little';
5 end;
6 end;
7 /
Package body created.
Trigger which causes you trouble: no need for a cursor; moreover, you have two of them (was it just a typo)? It looks as if you used it to avoid no data found error. If so, don't do it - it just makes confusion. Handle exceptions properly. By the way, you "forgot" to close the cursor.
SQL> create or replace trigger magazzino_bef_ins
2 before insert on magazzino
3 for each row
4 declare
5 cacc char(3);
6 ogg int;
7 begin
8 select cacciatore, oggetto
9 into cacc, ogg
10 from disponibilita
11 where id_disponibilita = :new.disponibilita;
12
13 :new.codcatalogo := pk_gestione_magazzino.genera_catalogo (cacc, ogg);
14 end;
15 /
Trigger created.
Testing:
SQL> insert into disponibilita values (1, 1, 1);
1 row created.
SQL> insert into magazzino (disponibilita) values (1);
1 row created.
SQL> select * From magazzino;
DISPONIBILITA CODCATAL
------------- --------
1 Little
SQL>
Works, kind of.
Error message
CREATE TABLE DEPARTMENT(DID INT,DNAME VARCHAR2(20),DLOC VARCHAR2(20));
INSERT INTO DEPARTMENT VALUES(101,'SRINATH','HINDUPUR');
INSERT INTO DEPARTMENT VALUES(102,'SAINATH','ANANTAPUR');
create or replace PROCEDURE ADD_DEPARTMENT
(P_DID IN DEPARTMENT.DID%TYPE,
P_DNAME IN DEPARTMENT.DNAME%TYPE,
P_DLOC IN DEPARTMENT.DLOC%TYPE,
P_ERROR_MSG OUT VARCHAR2)
IS
BEGIN
INSERT INTO DEPARTMENT(DID,DNAME,DLOC)VALUES(P_DID,P_DNAME,P_DLOC);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
P_ERROR_MSG:=SQLERRM;
END ADD_DEPARTMENT;
iam writing a simple procedure try to excute but it shows object_id:invalid identifier how i can solve
complete procedure execution image
One of your column names may be wrong in the parameter list/insert. Try just using varchar2 for all of them and see if that helps
create or replace PROCEDURE ADD_DEPT2
(P_DEPTNO IN VARCHAR2,
P_DNAME IN VARCHAR2,
P_LOC IN VARCHAR2,
P_ERROR_MSG OUT VARCHAR2)
IS
BEGIN
INSERT INTO DEPT1(DEPTNO,DNAME,LOC)VALUES(P_DEPTNO,P_DNAME,P_LOC);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
P_ERROR_MSG :=SQLERRM;
END ADD_DEPT2;
"it will come same error can be displayed"
No, no it won't. Let's prove it by running the code you posted.
Here is your table:
SQL> CREATE TABLE DEPARTMENT(DID INT,DNAME VARCHAR2(20),DLOC VARCHAR2(20));
Table created.
SQL> INSERT INTO DEPARTMENT VALUES(101,'SRINATH','HINDUPUR');
1 row created.
SQL> INSERT INTO DEPARTMENT VALUES(102,'SAINATH','ANANTAPUR');
1 row created.
SQL>
Here is your procedure:
SQL> create or replace PROCEDURE ADD_DEPARTMENT
2 (P_DID IN DEPARTMENT.DID%TYPE,
3 P_DNAME IN DEPARTMENT.DNAME%TYPE,
4 P_DLOC IN DEPARTMENT.DLOC%TYPE,
5 P_ERROR_MSG OUT VARCHAR2)
6 IS
7 BEGIN
8 INSERT INTO DEPARTMENT(DID,DNAME,DLOC)VALUES(P_DID,P_DNAME,P_DLOC);
9 COMMIT;
10 EXCEPTION
11 WHEN OTHERS THEN
12 P_ERROR_MSG:=SQLERRM;
13 END ADD_DEPARTMENT;
14 /
Procedure created.
SQL>
And lo! not only does it compile but it runs without error too.
SQL> set serveroutput on
SQL> declare
2 v varchar2(128);
3 begin
4 add_department(666, 'Area 51', 'Roswell', v);
5 end;
6 /
PL/SQL procedure successfully completed.
SQL> select * from department;
DID DNAME DLOC
---------- -------------------- --------------------
101 SRINATH HINDUPUR
102 SAINATH ANANTAPUR
666 Area 51 Roswell
SQL>
So once again I ask, what is the problem?
"PLS-00905: object SCOTT.ADD_DEPARTMENT is invalid"
In SQL*Plus:
Connect as SCOTT
alter procedure add_department compile;
show errors
Or apply the equivalent sequence for whatever IDE you use to write your code.
I have been using Oracle(10g.2) as a PHP programmer for almost 3 years, but when I gave an assignment, I have tried to use the ref cursors and collection types for the first time. And I
've searched the web, when I faced with problems, and this ora-00932 error really overwhelmed me. I need help from an old hand.
Here is what I've been tackling with,
I want to select rows from a table and put them in a ref cursor, and then with using record type, gather them within an associative array. And again from this associative array, make a ref cursor. Don't ask me why, I am writing such a complicated code, because I need it for more complex assignment. I might be sound confusing to you, thus let me show you my codes.
I have 2 types defined under the types tab in Toad. One of them is an object type:
CREATE OR REPLACE
TYPE R_TYPE AS OBJECT(sqn number,firstname VARCHAR2(30), lastname VARCHAR2(30));
Other one is collection type which is using the object type created above:
CREATE OR REPLACE
TYPE tr_type AS TABLE OF r_type;
Then I create a package:
CREATE OR REPLACE PACKAGE MYPACK_PKG IS
TYPE MY_REF_CURSOR IS REF CURSOR;
PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR);
END MYPACK_PKG;
Package Body:
CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
rcur MYPACK_PKG.MY_REF_CURSOR;
sql_stmt VARCHAR2(1000);
l_rarray tr_type := tr_type();
l_rec r_type;
BEGIN
sql_stmt := 'SELECT 1,e.first_name,e.last_name FROM hr.employees e ';
OPEN rcur FOR sql_stmt;
LOOP
fetch rcur into l_rec;
exit when rcur%notfound;
l_rarray := tr_type( l_rec );
END LOOP;
CLOSE rcur;
--OPEN r_cursor FOR SELECT * FROM TABLE(cast(l_rarray as tr_type) );
END MY_PROC;
END MYPACK_PKG;
I commented out the last line where I open ref cursor. Because it's causing another error when I run the procedure in Toad's SQL Editor, and it is the second question that I will ask.
And lastly I run the code in Toad:
variable r refcursor
declare
r_out MYPACK_PKG.MY_REF_CURSOR;
begin
MYPACK_PKG.MY_PROC(r_out);
:r := r_out;
end;
print :r
There I get the ora-00932 error.
The way you are using the REF CURSOR is uncommon. This would be the standard way of using them:
SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
2 PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
3 BEGIN
4 OPEN r_cursor FOR SELECT e.empno,e.ENAME,null FROM scott.emp e;
5 END MY_PROC;
6 END MYPACK_PKG;
7 /
Corps de package crÚÚ.
SQL> VARIABLE r REFCURSOR
SQL> BEGIN
2 MYPACK_PKG.MY_PROC(:r);
3 END;
4 /
ProcÚdure PL/SQL terminÚe avec succÞs.
SQL> PRINT :r
EMPNO ENAME N
---------- ---------- -
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
[...]
14 ligne(s) sÚlectionnÚe(s).
I'm not sure what you are trying to accomplish here, you're fetching the ref cursor inside the procedure and then returning another ref cursor that will have the same data. I don't think it's necessary to fetch the cursor at all in the procedure. Let the calling app do the fetching (here the fetching is done by the print).
Update: why are you getting the unhelpful error message?
You're using a cursor opened dynamically and I think that's part of the reason you are getting the unhelpful error message. If we use fixed SQL the error message is different:
SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
2 PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
3 TYPE type_rec IS RECORD (qn number,
4 firstname VARCHAR2(30),
5 lastname VARCHAR2(30));
6 lt_record type_rec; /* Record type */
7 lt_object r_type; /* SQL Object type */
8 BEGIN
9 OPEN r_cursor FOR SELECT e.empno,e.ENAME,null FROM scott.emp e;
10 FETCH r_cursor INTO lt_record; /* This will work */
11 FETCH r_cursor INTO lt_object; /* This won't work in 10.2 */
12 END MY_PROC;
13 END MYPACK_PKG;
14 /
Package body created
SQL> VARIABLE r REFCURSOR
SQL> BEGIN
2 MYPACK_PKG.MY_PROC(:r);
3 END;
4 /
BEGIN
*
ERREUR Ó la ligne 1 :
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at "APPS.MYPACK_PKG", line 11
ORA-06512: at line 2
I outlined that currently in 10.2 you can fetch a cursor into a PLSQL record but not in a SQL Object.
Update: regarding the PLS-00306: wrong number or types of arguments
l_rarray is a NESTED TABLE, it needs to be initialized and then extended to be able to store elements. For example:
SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
2 PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
3 lr_array tr_type := tr_type(); /* SQL Array */
4 BEGIN
5 FOR cc IN (SELECT e.empno, e.ENAME, NULL lastname
6 FROM scott.emp e) LOOP
7 lr_array.extend;
8 lr_array(lr_array.count) := r_type(cc.empno,
9 cc.ename,
10 cc.lastname);
11 /* Here you can do additional procedural work on lr_array */
12 END LOOP;
13 /* then return the result set */
14 OPEN r_cursor FOR SELECT * FROM TABLE (lr_array);
15 END MY_PROC;
16 END MYPACK_PKG;
17 /
Corps de package crÚÚ.
SQL> print r
SQN FIRSTNAME LASTNAME
---------- ------------------------------ -----------
7369 SMITH
7499 ALLEN
7521 WARD
[...]
14 ligne(s) sÚlectionnÚe(s).
For further reading you can browse the documentation for PL/SQL collections and records.