Keep getting compilation error while creating the following procedure - oracle

Create a procedure named 'select_city' which accepts one input parameter user_id of type number and one output parameter city_details of type varchar. This procedure is used to display the city_details of user.If the user is from bangalore then display the city_details as 'User is from Bangalore',or if the user is from chennai then display the city_details as 'User is from Chennai', else display the city_details as 'User is from other cities'.
CREATE PROCEDURE select_city ( user_id IN user_details.id%type,
city_details OUT VARCHAR2(255) )
AS
BEGIN
SELECT CASE
WHEN city = 'Bangalore' THEN 'User is from Bangalore'
WHEN city = 'Chennai' THEN 'User is from Chennai'
ELSE 'User is from other cities'
END tmp_status INTO city_details
FROM contact cnt
WHERE cnt.id = user_id;
END;

OUT parameter shouldn't have size. Remove it.
Also (probably not related to error you got), consider using CREATE OR REPLACE because any subsequent CREATE will fail as the procedure - although invalid - already exists so you'd have to drop it first.
Sample table:
SQL> create table contact as
2 select 'Bangalore' city, 1 id from dual;
Table created.
Procedure:
SQL> create or replace procedure select_city
2 (user_id in number,
3 city_details out varchar2 --> no size here
4 )
5 as
6 begin
7 select case
8 when city = 'Bangalore' then
9 'User is from Bangalore'
10 when city = 'Chennai' then
11 'User is from Chennai'
12 else
13 'User is from other cities'
14 end tmp_status
15 into city_details
16 from contact cnt
17 where cnt.id = user_id;
18 end;
19 /
Procedure created.
Testing:
SQL> set serveroutput on;
SQL> declare
2 l_citydet varchar2(255);
3 begin
4 select_city(1, l_citydet);
5 dbms_output.put_line(l_citydet);
6 end;
7 /
User is from Bangalore
PL/SQL procedure successfully completed.
SQL>

Related

How can i correct this error(The package is configured with translation errors)?

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.

How to call a variable inside a procedure in plsql?

I'm trying to calling 2 variables inside another procedure that should give me the min and max in a column like this:
create or replace procedure ClassEnrollmentReport
(p_CLASSNAME in class.classname%TYPE)
as
begin
dbms_output.put_line('Max gpa:');
StudentWithGivenGPA(MinMaxGPA.p_maxStudentGPA(p_CLASSNAME));
dbms_output.put_line('Min gpa:');
StudentWithGivenGPA(MinMaxGPA.p_minStudentGPA(p_CLASSNAME));
end ClassEnrollmentReport;
Which gives me an error message like this:
6/5 PL/SQL: Statement ignored
6/35 PLS-00225: subprogram or cursor 'MINMAXGPA' reference is out of scope
8/5 PL/SQL: Statement ignored
8/35 PLS-00225: subprogram or cursor 'MINMAXGPA' reference is out of scope
Here's how the minmaxgpa procedure look like:
create or replace procedure MinMaxGPA
(
p_CLASSNAME in class.classname%type,
p_maxStudentGPA OUT student.gpa%type,
p_minStudentGPA OUT student.gpa%type
)
as
maxStudentGPA student.gpa%type;
minStudentGPA student.gpa%type;
begin
select max(gpa) into maxStudentGPA
from student
where classno = (select classno from class where upper(classname) = upper(p_CLASSNAME));
select min(gpa) into minStudentGPA
from student
where classno = (select classno from class where upper(classname) = upper(p_CLASSNAME));
p_maxStudentGPA := maxStudentGPA;
p_minStudentGPA := minStudentGPA;
end MinMaxGPA;
I know how to do this with a function, but having no idea how can I get this with procedure. Can you help me with this?
With really simple sample tables (just to make the procedure compile):
SQL> create table class as select 'abc' classname, 100 clasno from dual;
Table created.
SQL> create table student as select 1 gpa, 100 classno from dual;
Table created.
Procedure code (I didn't change it):
SQL> create or replace procedure MinMaxGPA
2 (
3 p_CLASSNAME in class.classname%type,
4 p_maxStudentGPA OUT student.gpa%type,
5 p_minStudentGPA OUT student.gpa%type
6
7 )
8 as
9 maxStudentGPA student.gpa%type;
10 minStudentGPA student.gpa%type;
11 begin
12 select max(gpa) into maxStudentGPA
13 from student
14 where classno = (select classno from class where upper(classname) = upper(p_CLASSNAME));
15
16
17 select min(gpa) into minStudentGPA
18 from student
19 where classno = (select classno from class where upper(classname) = upper(p_CLASSNAME));
20
21 p_maxStudentGPA := maxStudentGPA;
22 p_minStudentGPA := minStudentGPA;
23 end MinMaxGPA;
24 /
Procedure created.
Your "new" ClassEnrollmentReport should then look like this: you have to follow the MinMaxGPA procedure's description - it accepts 3 parameters (one in, two out):
SQL> create or replace procedure ClassEnrollmentReport
2 (p_CLASSNAME in class.classname%TYPE)
3 as
4 v_mingpa number;
5 v_maxgpa number;
6 begin
7 minmaxgpa(p_classname, v_mingpa, v_maxgpa);
8 dbms_output.put_line('Max gpa: ' || v_maxgpa);
9 dbms_output.put_line('Min gpa: ' || v_mingpa);
10 end ClassEnrollmentReport;
11 /
Procedure created.
If we test it:
SQL> set serveroutput on
SQL> exec classenrollmentreport('abc');
Max gpa: 1
Min gpa: 1
PL/SQL procedure successfully completed.
SQL>

Getting error while compiling this PL/SQL block

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>

Create procedure with if in oracle sql

I need to create a procedure that search an email in a table, and if it doesn´t exists the procedure creates a new record with this email.
Something like this:
CREATE PROCEDURE check_email (in #email varchar2(99)) AS
BEGIN
IF SELECT email FROM user u WHERE u.email:=email
dbms_output.put_line('This email exists');
ELSE
BEGIN
INSERT INTO user (id, name, surname, city, address, age, email) VALUES (id_user.nextval,'David','Alcatraz','Sevilla', 'Avd miguel de unamuno', 23, email || '#gmail.com')
END
Take this in consideration:
A variable to store the counter of email from the table.
You must close each statement with semicolon.
An input variable is defined with its type without length.
It would look like
CREATE PROCEDURE check_email (p_email in varchar2 ) AS
v_counter pls_integer;
BEGIN
SELECT count(*) into v_counter FROM user WHERE upper(email) = upper(p_email);
if v_counter = 1
then
dbms_output.put_line('This email exists');
ELSE
INSERT INTO user (id, name, surname, city, address, age, email) VALUES
(id_user.nextval,'David','Alcatraz','Sevilla', 'Avd miguel de unamuno', 23, p_email ||
'#gmail.com');
commit;
END IF;
exception when others then raise;
END;
Why bother? Let the database handle that.
Here's how: as e-mail addresses have to be unique, create a unique key constraint on that column:
SQL> create table t_user
2 (id number constraint pk_user primary key,
3 name varchar2(20) not null,
4 e_mail varchar2(30) not null,
5 --
6 constraint uk_user_mail unique (e_mail)
7 );
Table created.
Sequence will be used for the ID column values.
SQL> create sequence tseq;
Sequence created.
Procedure: if there's unique key violation, simply don't do anything. Other errors, if any, will be automatically raised by Oracle. You can handle them, if you want.
SQL> create or replace procedure p_user
2 (par_name in t_user.name%type,
3 par_email in t_user.e_mail%type)
4 is
5 begin
6 insert into t_user (id, name, e_mail)
7 values (tseq.nextval, par_name, par_email);
8 exception
9 when dup_val_on_index then null;
10 end;
11 /
Procedure created.
Testing:
SQL> exec p_user('Little', 'lf#mail.com');
PL/SQL procedure successfully completed.
SQL> exec p_user('Foot' , 'lf#mail.com');
PL/SQL procedure successfully completed.
SQL> exec p_user('Victor', 'victor#mail.com');
PL/SQL procedure successfully completed.
SQL> select * From t_user;
ID NAME E_MAIL
---------- -------------------- ------------------------------
1 Little lf#mail.com
3 Victor victor#mail.com
SQL>
As you can see, Foot never entered the table as its e-mail address already exists in the table.

ora-06575 package or function is in an invalid state pl sql

I am new to pl sql and i am trying to call a procedure but i am getting the error ora-06575 package or function is in an invalid state.
What do you think i am doing wrong? Thanks
select * from NB_tfr_USERS; --previous table created
create or replace procedure nb_tfr_add_user
(
i_user_name in nb_tfr_users.name%type,
i_address in nb_tfr_users.address%type,
i_birthdate in nb_tfr_users.birthdate%type,
o_userid out nb_tfr_users.id%type,
o_errm out varchar2
) AS
--Variables
l_user_id number;
--Parameters invalid exception
error_params exception;
BEGIN
--validate parameters
--- name can not be empty
--- birthdate can be empty
if i_user_name is null or length(i_user_name) = 0 then
raise error_params;
end if;
--initialize variables
l_user_id := nb_seq_tfr_user_id.nextval;
--insert new user
insert into NB_tfr_USERS (id, name, address, birthdate)
values (l_user_id, i_user_name, i_address, i_birthdate);
--deal with exceptions
exception
when error_params then
o_errm := 'Invalid Parameters!';
dbms_output.put_line(o_errm);
when others then
dbms_output.put_line('Error: '||sqlerrm);
o_errm:=substr(1,150,sqlerrm);
raise;
END NB_tfr_ADD_USER;
call
nb_tfr_add_user(54,'tf','lx',12121989);
So when i try to call the procedure i get the error.
Well, it looks OK - apart from the fact that you incorrectly called the procedure.
Here's a test case.
SQL> create table nb_tfr_users
2 (id number, name varchar2(10), address varchar2(10), birthdate date);
Table created.
SQL> create sequence nb_seq_tfr_user_id;
Sequence created.
The procedure:
SQL> create or replace procedure nb_tfr_add_user
2 (
3 i_user_name in nb_tfr_users.name%type,
4 i_address in nb_tfr_users.address%type,
5 i_birthdate in nb_tfr_users.birthdate%type,
6 o_userid out nb_tfr_users.id%type,
7 o_errm out varchar2
8 ) AS
9 --Variables
10 l_user_id number;
11 --Parameters invalid exception
12 error_params exception;
13 BEGIN
14 --validate parameters
15 --- name can not be empty
16 --- birthdate can be empty
17 if i_user_name is null or length(i_user_name) = 0 then
18 raise error_params;
19 end if;
20
21 --initialize variables
22 l_user_id := nb_seq_tfr_user_id.nextval;
23
24 --insert new user
25 insert into NB_tfr_USERS (id, name, address, birthdate)
26 values (l_user_id, i_user_name, i_address, i_birthdate);
27
28 --deal with exceptions
29 exception
30 when error_params then
31 o_errm := 'Invalid Parameters!';
32 dbms_output.put_line(o_errm);
33
34 when others then
35 dbms_output.put_line('Error: '||sqlerrm);
36 o_errm:=substr(1,150,sqlerrm);
37 raise;
38 END NB_tfr_ADD_USER;
39 /
Procedure created.
SQL>
Testing - it shows how you should have called it. As there are 3 IN and 2 OUT parameters, that's what you should have done as well.
SQL> set serveroutput on
SQL> declare
2 l_userid nb_tfr_users.id%type;
3 l_Errm varchar2(200);
4 begin
5 nb_tfr_add_user(i_user_name => 'tf',
6 i_address => 'lx',
7 i_birthdate => sysdate,
8 o_userid => l_userid,
9 o_errm => l_errm);
10 dbms_output.put_Line(l_userid ||' '||l_errm);
11 end;
12 /
PL/SQL procedure successfully completed.
SQL> select * from nb_tfr_users;
ID NAME ADDRESS BIRTHDAT
---------- ---------- ---------- --------
1 tf lx 09.09.19
SQL>
If you got the error, it - obviously - means that there's something wrong. I don't know what, but - maybe you forgot to create the sequence.
Anyway: after creating stored procedures, check whether everything is OK by running (in SQL*Plus) show err, e.g.
SQL> create or replace procedure p_test is
2 begin
3 insert into abc (id) values (seq_does_not_exist.nextval);
4 end;
5 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE P_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/3 PL/SQL: SQL Statement ignored
3/15 PL/SQL: ORA-00942: table or view does not exist
SQL>
Or, query user_source:
SQL> select line, text, attribute from user_errors where name = 'P_TEST';
LINE TEXT ATTRIBUTE
----- -------------------------------------------------- ---------
3 PL/SQL: ORA-00942: table or view does not exist ERROR
3 PL/SQL: SQL Statement ignored ERROR
SQL>
I suggest you do the same and see what's wrong with the procedure.

Resources