CREATE or REPLACE PROCEDURE SP_Projects is
Cursor C_proj is SELECT PROJECTID FROM PROJECT
ORDER BY PROJECTID;
R_proj C_proj%ROWTYPE;
BEGIN
OPEN c_proj;
LOOP
FETCH c_proj into r_proj;
EXIT when c_proj%NOTFOUND;
DBMS_OUTPUT.Put_line(c_proj.ProjectID);
END LOOP;
CLOSE c_proj;
END;
SET SERVEROUTPUT ON;
EXEC SP_Projects;
LINE/COL ERROR
17/1 PLS-00103: Encountered the symbol "SET"
Errors: check compiler log
You need to end procedure with slash /:
END;
/
Related
I am trying to run a pl/sql procedure which I have attatched below, and am getting the following error when running my script
DBMS_OUTPUT.ENABLE;
create or replace procedure grade_point212
is
cursor c1 is
----Cursor declaration--
SELECT student.student_id, student.first_name, student.last_name, course.course_id, course.course_name, class.grade
FROM CLASS
JOIN STUDENT
ON student.student_id = class.student_id
JOIN course
ON course.course_id = class.course_id
order by 1;
----Variable declation--
v_student_id student.student_id%type;
v_first_name student.first_name%type;
v_last_name student.last_name%type;
v_course_id course.course_id%type;
v_course_name course.course_name%type;
v_grade class.grade%type;
--3 additional varriables--
prev_student student.student_id%type;
course_count number(3);
grade_point_total number(3);
----mainline--
begin
open c1;
loop
--Get the first row in the cursor--
fetch c1
into v_student_id,v_first_name ,v_last_name,v_course_id,v_course_name,v_grade;
exit when c1%notfound;
--Set the prev_student to the cursor’s student id--
prev_student:=v_student_id;
--Set the grade_point _total to 0--
grade_point_total:=0;
--Set the course_count to 0--
course_count:=0;
--If the prev_studentis NOT equal to cursor’s student id--
IF prev_student!=v_student_id THEN
--Print out the grade point average which is grade_point_total divided by course_count--
DBMS_OUTPUT.PUT_LINE(grade_point_total/course_count);
--Set prev_student to the cursor’s student id--
prev_student:=v_student_id;
--Set the grade_point_total to 0--
grade_point_total:=0;
--Set the course_count to 0--
course_count:=0;
END IF;
--Add the grade point of the cursor’s grade to grade_point_total--
grade_point_total:=grade_point_total+GradePoint(v_grade);
--Add 1 to the course_count--
course_count:=course_count+1;
--Print out the current row--
DBMS_OUTPUT.PUT_LINE(v_student_id||' '||v_first_name||' '||v_last_name||' '||v_course_id||' '||v_course_name||' '||v_grade);
--Fetch a new row--
fetch c1
into v_student_id,v_first_name ,v_last_name,v_course_id,v_course_name,v_grade;
end loop;
--Close the cursor--
close c1;
--Print out the grade point average which is grade_point_total divided by course_count--
DBMS_OUTPUT.PUT_LINE(grade_point_total/course_count);
end;
set serveroutput on;
begin
grade_point212;
end;
"Error starting at line : 1 in command -
DBMS_OUTPUT.ENABLE
Error report -
Unknown Command
Procedure GRADE_POINT212 compiled
LINE/COL ERROR
--------- -------------------------------------------------------------
65/1 PLS-00103: Encountered the symbol "SET"
Errors: check compiler log
"
The "/" is correct. As a follow up, what tool you are using to send your scripts to the database?
SQL*Plus uses the standalone "/" line as the indicator that the sequence of strings is complete and therefore can be sent to the database for compilation and execution. If you don't provide the "/" you will get errors that on closer read will indicate that some compilation has failed because the sequence you send will actually be composed of multiple SQL, SQL*Plus, and PLSQL blocks.
The execute keyword, BTW, as in:
exec dbms_output.enable;
is SQLPlus syntactic sugar that gets converted by SQLPlus into:
begin dbms_output.enable; end;
Try exec in front of your dbms..
exec dbms_output.enable;
Remove the first line (DBMS_OUTPUT.ENABLE;) entirely. set serveroutput on (before you're about to execute the procedure) will enable it.
Or, encapsulate it into the procedure or the anonymous PL/SQL block itself, e.g.
SQL> begin
2 dbms_output.enable;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL>
You missed the trailing "/" to execute the "CREATE OR REPLACE" statement. The ";" As explained here, the semi-colon ends your pl/sql statement but you need the slash to execute it.
The error "Encountered the symbol "SET" Errors: check compiler log " refers to the "SET" string from the "set serveroutput on" statement.
...
DBMS_OUTPUT.PUT_LINE(grade_point_total/course_count);
end;
/ <<< Add this
set serveroutput on;
begin
grade_point212;
end;
/ <<< Add this
I am trying to use EXCEPTION WHEN OTHERS to catch non-existent tables that I try to DROP, as follows:
begin
execute immediate 'drop table X';
exception when others then null;
end;
If table x exists and I run this, the table is dropped and all is well. If I run it again, there is no table to be dropped, but the EXCEPTION thing results in the script proceeding happily. So far, so good.
The problem appears if I try to do this more than once.
If I run this script to drop tables X and Y:
begin
execute immediate 'drop table X';
exception when others then null;
execute immediate 'drop table Y';
exception when others then null;
end;
I get the following error information:
Error starting at line : 1 in command -
begin
execute immediate 'drop table X';
exception when others then null;
execute immediate 'drop table Y';
exception when others then null;
end;
Error report -
ORA-06550: line 6, column 1:
PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:
( begin case declare end exit for goto if loop mod null
pragma raise return select update when while with
<< continue close current delete fetch lock
insert open rollback savepoint set sql execute commit forall
merge pipe purge
ORA-06550: line 7, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
What am I missing here? If I removed the second EXCEPTION WHEN statement, the script fails if table Y doesn't exist... I need to catch this error...
I found my answer here:
Two PLSQL statements with begin and end, run fine separately but not together?
Apparently I need
begin
begin
some stuff
end;
begin
some other stuff
end;
end;
or to put a / after each of the two inner block END; 's...
exception when others then null; applies to a single Begin/End block. It's not really valid to have multiples in a single block. You can get around this by having multiple blocks that are individually caught.
begin
execute immediate 'drop table X';
exception when others then null;
end;
/
begin
execute immediate 'drop table Y';
exception when others then null;
end;
/
I am getting an error in the code below. I have added an arror <------ where the problem is.
The error message says that a THEN is expected, but when I use THEN, then it says that a BEGIN is expected.
Error(27,6): PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following: then and or The symbol "then" was substituted for "BEGIN" to continue.
Error(30,6): PLS-00103: Encountered the symbol "END" when expecting one of the following: , ; return returning
What am I doing wrong?
create or replace PROCEDURE "sp_updateUserPassword"(newUserPwd IN VARCHAR2, curIsoUserUID IN NUMBER)
IS
curUserID NUMBER;
userDateCreated DATE;
oldUserPwd VARCHAR2(255);
BEGIN
SELECT ISOUID INTO curUserID FROM ISOUSERS WHERE ISOUID=curIsoUserUID;
SELECT DATECREATE INTO userDateCreated FROM ISOUSERS WHERE ISOUID=curIsoUserUID;
SELECT PASSWORD INTO oldUserPwd FROM ISOUSERS WHERE ISOUID=curIsoUserUID;
IF(newUserPwd = oldUserPwd)
THEN
raise_application_error(-20000, 'The new password must be different from the previous password');
RETURN;
END IF;
IF NOT EXISTS
(
SELECT ISOUID
FROM OLDUSERPASSWORDS
WHERE ISOUID=curIsoUserUID
)
BEGIN <------------ Error is here
INSERT INTO OLDUSERPASSWORDS(ISOUID, DATECREATE, DATELASTCHANGE, CURRENTPASS, OLDPASS)
VALUES(curUserID, userDateCreated, SYSDATE, newUserPwd, oldUserPwd)
END;
/*raise_application_error(-20000, 'TEST');*/
END "sp_updateUserPassword";
Update
Corrected the code, so it now looks like this:
IF NOT EXISTS
(
SELECT ISOUID
FROM OLDUSERPASSWORDS
WHERE ISOUID=curIsoUserUID
)
THEN
BEGIN
INSERT INTO OLDUSERPASSWORDS(ISOUID, DATECREATE, DATELASTCHANGE, CURRENTPASS, OLDPASS)
VALUES(curUserID, userDateCreated, SYSDATE, newUserPwd, oldUserPwd)
END;
END IF;
I am getting this error:
Error(30,7): PL/SQL: ORA-00933: SQL command not properly ended
Error(31,7): PLS-00103: Encountered the symbol "IF" when expecting one of the following: ; <an identifier> <a double-quoted delimited-identifier>
Perhaps it's just a minor error that I am missing?
PL/SQL Syntax Error for IF THEN ELSE
Correct syntax is:
IF condition THEN
statements
END IF;
Your code is effectively:
IF condition THEN
BEGIN
statements
END;
Corrected
IF NOT EXISTS
(
SELECT ISOUID
FROM OLDUSERPASSWORDS
WHERE ISOUID=curIsoUserUID
)
THEN
BEGIN <------------ Error is NOT here
INSERT INTO OLDUSERPASSWORDS(ISOUID, DATECREATE, DATELASTCHANGE, CURRENTPASS, OLDPASS)
VALUES(curUserID, userDateCreated, SYSDATE, newUserPwd, oldUserPwd);
END;
END IF;
You are getting your first error because you need to add a THEN clause before the BEGIN block to make the syntax of the ID statement complete and correct.
You are getting the second error:
Error(30,7): PL/SQL: ORA-00933: SQL command not properly ended
because you have not completed your INSERT statement. Terminate it with a semicolon and that should fix that error.
IF NOT EXISTS
(
SELECT ISOUID
FROM OLDUSERPASSWORDS
WHERE ISOUID=curIsoUserUID
)
THEN
BEGIN
INSERT INTO OLDUSERPASSWORDS(ISOUID, DATECREATE, DATELASTCHANGE, CURRENTPASS, OLDPASS)
VALUES(curUserID, userDateCreated, SYSDATE, newUserPwd, oldUserPwd);
END;
END IF;
You forgot the THEN before the BEGIN, that goes with the IF NOT EXISTS.
Created a procedure as below :
create or replace
PROCEDURE TEST AS
BEGIN
DECLARE
c_service process_state.service%type;
c_tr_source process_state.tr_source%type;
CURSOR c_process_state is
SELECT service, tr_source FROM process_state;
OPEN c_process_state;
LOOP
FETCH c_process_state into c_service, c_tr_source;
insert into process_state_archive values (c_service, c_tr_source);
commit;
EXIT WHEN c_process_state%notfound;
END LOOP;
CLOSE c_process_state;
END TEST;
After compiling i ran into some errors:
Error(33,4): PLS-00103: Encountered the symbol "FETCH" when expecting one of the following: constant exception table long double ref char time timestamp interval date
Error(44,4): PLS-00103: Encountered the symbol "CLOSE" when expecting one of the following: end not pragma final instantiable volgorde overriding static member constructor map
Can anyone one please explain the problem? I am beginner and learning SQL.
1) You should declare cursor before BEGIN but not after and EXIST WHEN should be immediately after FETCH
create or replace
PROCEDURE TEST AS
c_service process_state.service%type;
c_tr_source process_state.tr_source%type;
CURSOR c_process_state is
SELECT service, tr_source FROM process_state;
BEGIN
OPEN c_process_state;
LOOP
FETCH c_process_state into c_service, c_tr_source;
EXIT WHEN c_process_state%notfound;
insert into process_state_archive values (c_service, c_tr_source);
commit;
END LOOP;
CLOSE c_process_state;
END TEST;
2) You task seems can be solved in one statement instead of a lot of code with cursor:
INSERT INTO process_state_archive select service, tr_source FROM process_state;
I'm getting some error with a proc I have created. The proc body is :-
CREATE OR REPLACE PROCEDURE suppress_termination_charge(v_curr_date IN DATE)
IS
TYPE suppress_term_cust_type IS RECORD (id NUMBER(11),pev NUMBER(11),piv NUMBER(11));
TYPE cur_suppress_term_cust IS REF CURSOR RETURN suppress_term_cust_type;
v_count NUMBER(4);
v_serv_item suppress_term_cust_type;
v_serv_itm_pev service_item.price_excluding_vat%TYPE;
v_serv_itm_piv service_item.price_including_vat%TYPE;
BEGIN
v_count:=0;
IF NULL=v_curr_date THEN
SELECT sysdate INTO v_curr_date FROM dual;
END IF;
OPEN cur_suppress_term_cust FOR
SELECT id AS id,price_excluding_vat AS pev,price_including_vat AS piv FROM service_items;
LOOP
FETCH cur_suppress_term_cust INTO v_serv_item;
EXIT WHEN cur_suppress_term_cust%NOTFOUND;
v_comment := 'Price changed from ('||v_serv_item.pev||', '||v_serv_item.piv||') to (0,0) (PEV, PIV) on '||v_curr_date||' for managed cease';
UPDATE service_items
SET price_including_vat=0, price_excluding_vat=0 , comments= v_comment
WHERE id = v_serv_item.id;
v_count:=v_count+1;
IF v_count=5000 THEN
COMMIT;
v_count:=0;
END IF;
END LOOP;
CLOSE cur_suppress_term_cust;
END;
/
The errors are as follows:-
SQL> SHOW ERROR;
Errors for PROCEDURE SUPPRESS_TERMINATION_CHARGE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
19/30 PLS-00103: Encountered the symbol "IS" when expecting one of the
following:
. ( % ; for
23/2 PLS-00103: Encountered the symbol "FETCH" when expecting one of
the following:
constant exception <an identifier>
<a double-quoted delimited-identifier> table LONG_ double ref
char time timestamp interval date binary national character
nchar
LINE/COL ERROR
-------- -----------------------------------------------------------------
41/2 PLS-00103: Encountered the symbol "CLOSE" when expecting one of
the following:
end not pragma final instantiable order overriding static
member constructor map
I see errors but not the ones you reported:
SELECT sysdate INTO v_curr_date FROM dual;
v_curr_date is an input parameter and can't be used as a target of SELECT or FETCH.
OPEN cur_suppress_term_cust FOR...
FETCH cur_suppress_term_cust INTO v_serv_item;
EXIT WHEN cur_suppress_term_cust%NOTFOUND.
cur_suppress_term_cust is a TYPE, not a cursor variable.
v_comment := ...
v_comment is not declared.
Try fixing these issues and see if things improve.
Share and enjoy.