Errors while executing Procedure - sql

I've been struggling to work out why my procedure isn't working for a while. So can anyone help me, Sorry I'm still very new to sql. It it should lookup the course_number based on the course name. if it does not find a match, it defaults the course number to ****. it then inserts a new record into the student_course table. Here is a copy of the database I'm using https://www.dropbox.com/s/cmqmzggiygxbkth/dissertation_database.txt
https://www.dropbox.com/s/hm90jga9zsaawnt/course_procedure.txt
CREATE OR REPLACE PROCEDURE upda_course
( name IN VARCHAR2 )
IS
course_id VARCHAR2;
cursor c1 is
SELECT course_id
FROM courses
WHERE name = name;
BEGIN
open c1;
fetch c1 into course_id;
if c1%notfound then
course_id := 9999;
end if;
INSERT INTO course_modules
( course_id, module_id
)
VALUES
( name,
course_id );
commit;
close c1;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END upda_course;
/
SHOW ERRORS;
EXECUTE upda_course('business computing systems');
SHOW ERRORS;
Error Displayed when Executed
*
ERROR at line 1:
ORA-20001: An error was encountered - -6502 -ERROR- ORA-06502: PL/SQL: numeric
or value error: character to number conversion error
ORA-06512: at "INS2014_106.UPDA_COURSE", line 29
ORA-06512: at line 1

Please try,
Procedure is taking a parameter(Name) as an input:
EXECUTE upda_course 'somename';

Try this:
EXECUTE upda_course('some course');

Specify the input value for input parameter
EXECUTE upda_course 'somename';

I belive course_id column in course_modules table is also a number . You are trying to insert a varchar2 to the column which is Number Hence the error. Also use your input variable as something like v_nameas your query below will return all rows from the table as variable name is same as column name. Same with course_id variable inside the procedure.
SELECT course_id
FROM courses
WHERE name = name;

Related

Handling a "too many values" exception in PLSQL

I need to handle the "too many values" exception in a PLSQL program.
The table is:
Table structure of emptest
But I am not able to handle the exception and the program always shows a pre-defined error.
Anybody has any ideas?
I tried like this:
enter image description here
Not getting the user defined message.
The issue is that, in your table you have only four columns.
ENO
ENAME
ESAL
DEPTNAME
but you are tying to insert five column values.
insert into emptest values(v_eno, v_ename, v_esal, v_deptname, v_deptno);
Why are you inserting v_deptno when it is not present in the table?
Either alter your table and add one more column or update the code to insert four column value only.
What you are trying will not work. The pl/sql block will not compile because the sql statement is invalid - it has too many values.
I think you want to trap the error and show your own error message. But, you need to use EXECUTE IMMEDIATE in order to allow invalid sql in pl/sql.
To trap a specific oracle error with a custom message, use EXCEPTION_INIT
Here is an example:
create table testa (col1 NUMBER);
set serveroutput on size 999999
clear screen
DECLARE
-- unnamed system exception
too_many_values EXCEPTION;
PRAGMA EXCEPTION_INIT (too_many_values, -00913);
c_too_many_values VARCHAR2(512) := 'Dude, too many values !';
BEGIN
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO testa VALUES (1,2)';
EXCEPTION WHEN too_many_values THEN
dbms_output.put_line(c_too_many_values);
END;
END;
/
Dude, too many values !
PL/SQL procedure successfully completed.
In you table you only have four columns, but you try to insert five column so error is generated error.
v_deptno is not your table
change your query as per following
Insert Into emptest values(v_eno, v_ename, v_esal, v_deptname);
or add one more column to your table
ALTER TABLE emptest ADD DEPTNO Number(4);

Oracle stored procedure not working PLS-00306

i have this questions i am trying to solve and find below what i have solved so far. although the stored procedure haveno error but calling it i get this error :
ERROR at line 2: ORA-06550: line 2, column 3: PLS-00306: wrong
number or types of arguments in call to 'PUB_JOB_COUNT' ORA-06550:
line 2, column 3: PL/SQL: Statement ignored
Requirement:
Create a stored PL/SQL procedure object in the database. The procedure
should insert the publisher’s name, city, telephone number and the
number (count) of jobs he/she requested in the table PublisherDetails
for each Publisher who requested less than three print jobs otherwise
the procedure should display on the screen the publisher name followed
by job number, job start date and job completion date for each job
he/she requested. Screen output (hint: use the concatenation operator
‘||’) should be in the following format:
Please someone help me out please?
Publisher Name: Addison-Wesley
JobNo Start Date Completion Date
12 17-JAN-14 25-JAN-14
14 28-FEB-14 01-APR-14
Finally, a NO-DATA-FOUND exception should be catered for in the
EXCEPTION section and a message displayed on the screen (hint: use
DBMS_OUTPUT.put_line procedure provided by Oracle) informing the user
if such an error arises. Note that in order for DBMS_OUTPUT.put_line
to work in SQL*Plus, you should set SERVEROUTPUT on first. You should
check if the procedure executes properly by invoking the procedure and
checking the content of the PublisherDetails table. Do the following:
a) Create a script file with the necessary code to create the table
PublisherDetails and the PL/SQL procedure in the database; b) Create a
second script file with the following: • An SQL statement that clears
the content of the table PublisherDetails; • A PL/SQL anonymous block
statement to invoke (execute) the PL/SQL procedure; • A SELECT
statement to select all the records in PublisherDetails table.
my tables
publisher(publisherName, publisherCity, phoneNo)
pk
printJob(JobNo, startDate, complitionDate, publisherName)
pk fk(publisher)
publisherdetails(publisherName, publisherCity, phoneNo, JobNo)
pk
Code:
CREATE OR REPLACE PROCEDURE PUB_JOB_COUNT (
JOBNO IN NUMBER
) AS
PUBLISHERNAME PRINTJOB.PUBLISHERNAME%TYPE;
NOTFOUND EXCEPTION;
CURSOR PUBCURSOR IS
SELECT PUBLISHER.PUBLISHERNAME,
PUBLISHER.PUBLISHERCITY,
PUBLISHER.PHONENO,
PRINTJOB.STARTDATE,
PRINTJOB.COMPLETIONDATE,
SUM(JOBNO) AS NUMOFJOBS
FROM PUBLISHER
INNER JOIN PRINTJOB ON PUBLISHER.PUBLISHERNAME = PRINTJOB.PUBLISHERNAME
GROUP BY PUBLISHER.PUBLISHERNAME,
PUBLISHER.PUBLISHERCITY,
PUBLISHER.PHONENO,
PRINTJOB.STARTDATE,
PRINTJOB.COMPLETIONDATE;
PUBREC PUBCURSOR%ROWTYPE;
BEGIN
OPEN PUBCURSOR;
FOR PRINTJOB IN PUBCURSOR LOOP
PUBLISHERNAME := PRINTJOB.PUBLISHERNAME;
DBMS_OUTPUT.PUT_LINE('Publisher Name : ' || PRINTJOB.PUBLISHERNAME);
LOOP
FETCH PUBCURSOR INTO PUBREC;
EXIT WHEN PUBCURSOR%NOTFOUND;
IF PUBREC.NUMOFJOBS <= 3 THEN INSERT INTO PUBLISHERDETAILS VALUES (
PUBREC.PUBLISHERNAME,
PUBREC.PUBLISHERCITY,
PUBREC.PHONENO,
PUBREC.NUMOFJOBS
);
ELSE DBMS_OUTPUT.PUT_LINE(PUBREC.NUMOFJOBS
|| ' '
|| PUBREC.STARTDATE
|| ' '
|| PUBREC.COMPLETIONDATE);
END IF;
END LOOP;
END LOOP;
CLOSE PUBCURSOR;
COMMIT;
EXCEPTION
WHEN NOTFOUND THEN DBMS_OUTPUT.PUT_LINE('Record Not Found');
END;
Gleaned from comments below, the code being used to execute the procedure:
BEGIN
pub_Job_Count;
End;
Your program is expecting an input, a number.
But when you call it, you're not providing said number.
So, the database gets upset and issues this:
PLS-00306: wrong number or types of arguments in call to 'PUB_JOB_COUNT'
To fix it,
BEGIN
pub_Job_Count(1); -- your number is added here, either explicitley or via a variable you add in a DECLARE
END;
/
A basic example
clear screen
create or replace procedure so_missing_inputs (x in integer, y in date) is
begin
dbms_output.put_line('X is: ' || x);
dbms_output.put_line('Y is: ' || to_char(y, 'MM-DD-YYYY HH24:MI:SS'));
end;
/
set serveroutput on
declare
a integer := 2;
b date := sysdate;
begin
-- so_missing_inputs(); -- missing 2 inputes
-- so_missing_inputs(1); -- missing 1 inputs
-- so_missing_inputs(sysdate, 2); -- right number of inputs, but not right data types
so_missing_inputs(x => a, y => b); -- let's be explicit about inputs vs coutning on right order
end;
/
If I run this -
If you were to uncomment one of the previous lines, you'd see the PLS-00306 creep back in.
One final note, on DBMS_OUTPUT. It's a good way to see what things are happening while 'debugging' your code, but it's not a good way to communicate things outside the PL/SQL program.

PL/SQL error: exact fetch returns more than requested number of rows ORA-06512:

I am trying to enter a student id from the students table to get the decision of whether they passed or failed from the module_grades table but i keep getting that error when i enter the student id can anyone help, thanks
Here is my code:
set serverouput on
DECLARE
Student Students.Sid%type:='&sid';
decision MODULE_GRADES.MDECISION%type;
BEGIN
SELECT MDECISION INTO decision FROM MODULE_GRADES
WHERE Sid = Student;
IF
(decision = 'Pass')
Then
DBMS_OUTPUT.PUT_LINE('You got'||Decision||' congratulations');
END IF;
END;
You're getting the error because the SELECT INTO returns at least two rows. In PL/SQL a SELECT INTO must return exactly one row, no more, no less.
When using SELECT INTO, you should query the table by a combination of conditions that guarantees uniqueness -- usually a primary key. In your case you are probably missing a filter or you have an anomaly in the data.
If you're expecting cases where there could be more than one row, you should either:
use a loop:
FOR cc IN (SELECT DECISION FROM MODULE_GRADES WHERE Sid = Student) LOOP
-- do something
END LOOP;
or catch the exception
BEGIN
SELECT MDECISION INTO decision
FROM MODULE_GRADES
WHERE Sid = Student;
-- do something
EXCEPTION
WHEN TOO_MANY_ROWS THEN
-- do something else
END;

PLS-00103 error with anonymous procedure

I got an error
PLS-00103: Encountered the symbol "end-of-file" when expecting one of
the following: [...]
when running an anonymous procedure (with Oracle):
BEGIN
DECLARE
seq number(12);
pk number(12);
BEGIN
loop
select mod_sdemol.nextval into seq from dual;
select idn_demol into pk from demol where demol.idn_demol=seq;
exit when pk is null;
end loop;
INSERT INTO "T_MOD"."DEMOL" (IDN_DEMOL, COD_MOL, PATH, IND_BLOK) VALUES (seq, '13000501', 'V', 'S');
END;
What I am trying to do is iterate through a sequence to prevent conflicts with existing data.
According to the answers in this question, a PL/SQL procedure should do something with selected data, but all my SELECTs have INTOs.
What am I doing wrong or what am I missing?
You don't need the first BEGIN. Each BEGIN keyword must match an END keyword.

PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ;

I am running the following script -
BEGIN
select department_name
from egpl_department
where department_id in (select department_id
from egpl_casemgmt_activity);
END ;
And got the Error -
PLS-00103: Encountered the symbol "end-of-file" when
expecting one of the following:
;
In a PL/SQL block select statement should have an into clause:
DECLARE
v_department egpl_department.department_name%type;
BEGIN
select department_name
into v_department
from egpl_department
where department_id in (select department_id from egpl_casemgmt_activity);
-- Do something useful with v_department
END;
PLS-00103 always means the compiler has hurled because we have made a syntax error. It would be really neat if the message text said: You have made a syntax error, please check your code but alas it doesn't.
Anyway, in this case the error is that in PL/SQL select statements must populate a variable. This is different from the behaviour of say T-SQL. So you need to define a variable which matches the projection of your query and select INTO that variable.
Oracle's documentation is comprehensive and online. You can find the section on integrating SQL queries into PL/SQL here. I urge you to read it, to forestall your next question. Because once you have fixed the simple syntax bloomer you're going to hit TOO_MANY_ROWS (assuming you have more than one department).
In PL/SQL you cannot just select some data. Where is the result supposed to go?
Your options are:
Remove BEGIN and END and run the SELECT with SQL*plus or some other tool that can run a SQL statement and present the result somewhere.
Use SELECT department_name INTO dep_name to put the result into a PL/SQL variable (only works if your SELECT returns a single row)
Use SELECT department_name BULK COLLECT INTO dep_name_table to put the result into a PL/SQL table (works for several rows)
Or maybe you can describe what you're trying to achieve and in what environment you want to run the SQL or PL/SQL code.
To avoid the too_many_rows problem, you could use a cursor, something like this (I haven't tested this, but along these lines )
DECLARE
v_department egpl_department.department_name%type;
cursor c_dept IS
select department_name
into v_department
from egpl_department
where department_id in (select department_id from egpl_casemgmt_activity)
order by department_name;
BEGIN
OPEN c_dept;
FETCH c_dept INTO v_department;
CLOSE c_dept;
-- do something with v_department
END;
This will put the first value it finds in the table into v_department. Use the ORDER BY clause to make sure the row returned would be the one you required, assuming there was the possibility of 2 different values.
Most people would not consider the call to be the issue,
but here's an amusing bug in Oracle Sql Developer that may emulate the issue..
exec dbowner.sp1 ( p1, p2, p3); -- notes about the fields
Error report -
ORA-06550: line 1, column 362:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
begin case declare end exception exit for goto if loop mod
null pragma raise return select update while with
<< close current delete fetch lock insert
open rollback savepoint set sql execute commit forall merge
pipe
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
exec dbowner.sp1 ( p1, p2, p3);
-- notes about the fields
PL/SQL procedure successfully completed.
DECLARE is only used in anonymous PL/SQL blocks and nested PL/SQL blocks.
You do not need to use the DECLARE key word before you 'introduce' a new variable in a Procedure block, unless .... the procedure is a nested PL/SQL block.
This is an example of how you would declare a variable without the 'DECLARE' Key word below.
eg.;
CREATE OR REPLACE PROCEDURE EXAMPLE( A IN NUMBER, B OUT VARCHAR2 )
IS
num1 number;
BEGIN
num1:=1;
insert into a (year) values(7);
END;
This question/answer explains it better
create procedure in oracle