PLS-00103: Encountered the symbol "END" - oracle

I'm new to the Oracle PL/SQL and I'm getting error mentioned in the title, exactly at line 30, when I try to run this code in Oracle APEX.
Here's the code:
CREATE OR REPLACE PROCEDURE enter_student_grade
(p_num_grade IN class_assessments.numeric_grade%TYPE,
p_class_assessment_id IN class_assessments.class_assessment_id%TYPE,
p_class_id IN class_assessments.class_id%TYPE,
p_stu_id IN class_assessments.stu_id%TYPE,
p_assessment_id class_assessments.assessment_id%TYPE,
p_date_turned_in IN DATE := SYSDATE) IS
v_max_id class_assessments.class_assessment_id%TYPE := 0;
v_max_attempts NUMBER(1,0):= 0;
BEGIN
SELECT max(class_assessment_id)+1 INTO v_max_id
FROM class_assessments;
SELECT count(stu_id) INTO v_max_attempts FROM class_assessments WHERE stu_id = p_stu_id AND assessment_id = p_assessment_id
IF v_max_attempts < 3 THEN
INSERT INTO class_assessments
(class_assessment_id,date_turned_id,numeric_grade,letter_grade,class_id,stu_id,assessment_id)
VALUES
(v_max_id,p_date_turned_in,p_num_grade,convert_grade(p_num_grade),p_class_id,p_stu_id,p_assessment_id);
commit;
ELSE
dbms_output.put_line('ERROR: Current student has reached maximum number of attempts for this assessment');
END IF;
END enter_student_grade;
I have no idea, where can be the source of this error.
Any help is appreciated.
Thanks

Symbol ; is missing after second SELECT statement (before IF).

Related

how can i resolve this pl/sql declare error?

DECLARE
COUNTING1 NUMBER(1);
BEGIN
SELECT COUNT(VACATION_REMAINING_COUNT)
INTO COUNTING1
FROM VACATION
WHERE NAME = :P0_VNAME;
IF COUNTING1 > 0 THEN
SELECT VACATION_REMAINING_COUNT
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY CREATED DESC) ROW_ID,
V.VACATION_REMAINING_COUNT
FROM VACATION V
WHERE NAME = :P0_VNAME
)
WHERE ROW_ID = 1;
ELSE
SELECT USER_YEAR_VACATION FROM VA_USER WHERE NAME = :P0_VNAME;
END IF;
END;
ORA-06550: line 1, column 114: PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following: ( - + case mod new not null continue avg count current exists max min prior sql stddev sum variance execute forall merge time timestamp interval date pipe
I wrote this sql code. but An error has occurred.
please help me..
You are missing the INTO clause for your second and third SELECT statements.
However, I would skip using the first COUNT statement and just try to find the latest row and catch a NO_DATA_FOUND exception if it occurs:
DECLARE
p_vacation_remaining VACATION.VACATION_REMAINING_COUNT%TYPE;
BEGIN
BEGIN
SELECT vacation_count_remaining
INTO p_vacation_remaining
FROM vacation
WHERE name = :P0_VNAME
ORDER BY created DESC
FETCH FIRST 1 ROW ONLY;
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT USER_YEAR_VACATION
INTO p_vacation_remaining
FROM VA_USER
WHERE NAME = :P0_VNAME;
END;
-- Do something with p_vacation_remaining
DBMS_OUTPUT.PUT_LINE( p_vacation_remaining );
END;
/

PLS-00103 error while trying to compare numbers

Is this prcedure syntaxically wrong? It seems that there is a problem with my if than block. I kepp getting
PLS-00103: Encountered the symbol ")" when expecting one of the
following:
(
CREATE OR REPLACE PROCEDURE Verif(TAB VARCHAR2) IS
MAX NUMBER;
TEMP NUMBER;
BEGIN
FOR i IN (SELECT * FROM CLIENTS1_1 WHERE NOT REGEXP_LIKE (COL2, (SELECT REGULAREXPR FROM REGULAREXPRES WHERE CATEGORY='ABR'))) LOOP
MAX:=0;
FOR j IN (SELECT * FROM ABR) LOOP
SELECT UTL_MATCH.JARO_WINKLER_SIMILARITY(i.Col2, j.ABR) INTO TEMP FROM DUAL;
IF (TEMP >= MAX) THEN
DBMS_OUTPUT.PUT_LINE(TEMP);
end if;
END LOOP;
END LOOP;
END;
/
I did all the tests. All select queries return real values.
Thanks for your help.
It was a stupid mistake. Just needed to replace MAX (which is a key word) by another var name.
Thanks to Barbaros Ozhan.

PLSQL ignore compilation error which is not an error

I came accross interesting error where I am not sure about best way how to fix it. Given following block:
DECLARE
v_column_exists number := 0;
host_column_exists number := 0;
i number;
BEGIN
Select count(*) into v_column_exists from user_tab_cols where column_name = 'CONNECTIONDESCRIPTION' and table_name = 'NODES';
if (v_column_exists = 1) then
Select count(*) into host_column_exists from user_tab_cols where column_name = 'HOST' and table_name = 'NODES';
if (host_column_exists = 0) then
execute immediate 'alter table NODES add (Host varchar2(255))';
for item in (select connectiondescription, code from nodes) loop
... LOOP STUFF ...
end loop;
end if;
end if;
END;
I get following result:
PL/SQL: ORA-00904: "CONNECTIONDESCRIPTION": invalid identifier
ORA-06550: line 40, column 20: PL/SQL: SQL Statement ignored
ORA-06550: line 41, column 20: PLS-00364: loop index variable 'ITEM'
use is invalid
any ideas how to get rid of this error? Problem is occuring when column NODES.CONNECTIONDESCRIPTION is not present in database, however in such case for loop won't execute in runtime. I would need to disable these errors, but haven't found any way to do it. I have tried using ALTER SESSION SET PLSQL_WARNINGS='DISABLE:00904', but it had no effect.
Thanks
Correct approach was to use another dynamic query which bulk collects items to an array and then loop through this array.

PLS-00103: Encountered the symbol "1" when expecting one of the following: (

Wrote the following PLSQL script to produce a report and am getting the error messages
Error at line 5
ORA-06550: line 61, column 18:
PLS-00103: Encountered the symbol "1" when expecting one of the following:
(
I've been through the code many times and I cannot find the error. Any help would be greatly appreciated.
I'm currently working in Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
SET serveroutput ON size 1000000;
DECLARE
TYPE TITLE_RECORD_TYPE IS RECORD
(id number(19),
gaid varchar2(20),
artist_legal_name varchar2(510),
artist_display_title varchar2(510),
display_title varchar2(510),
category varchar2(255),
type varchar2(255),
sub_type varchar2(255));
TITLE_RECORD TITLE_RECORD_TYPE;
v_title varchar2(510);
v_artist varchar2(510);
v_total_rows_error number(20) := 0;
v_row_count number(10) := 0;
v_error_desc varchar2(200) := NULL;
v_error_code number(19);
CURSOR ARTIST_TITLE_CURSOR is
select track_artist,track_title
from asset_artist_title;
CURSOR QUERY_CURSOR is
select distinct g1.gaid,g2.legal_name,g1.artist_display_title,
g1.display_title,g1.category,g1.type,g1.sub_type
from gcdm_app_rpt.rpt_asset g1,
gcdm_app_rpt.rpt_artist g2
where g1.artist_id = g2.id
and g1.is_deleted <> 'Y'
and g1.is_core = 'Y'
and g2.is_core = 'Y'
and g1.title like v_title||'%'
and g1.artist_display_title like v_artist||'%';
BEGIN
OPEN ARTIST_TITLE_CURSOR;
LOOP
FETCH ARTIST_TITLE_CURSOR into v_artist,v_title;
EXIT WHEN ARTIST_TITLE_CURSOR%NOTFOUND or ARTIST_TITLE_CURSOR%NOTFOUND IS NULL;
SELECT count(*)
INTO v_row_count
FROM gcdm_app_rpt.rpt_asset g1,
gcdm_app_rpt.rpt_artist g2
WHERE g1.artist_id = g2.id
AND g1.is_core = 'Y'
AND g1.is_deleted <> 'Y'
AND g2.is_core = 'Y'
AND g1.title like v_title||'%'
AND g1.artist_display_title like v_artist||'%';
IF v_row_count < 1 THEN
v_error_desc := 'Matching Asset record for '||v_artist||' - '||v_title||' not found';
DBMS_OUTPUT.PUT_LINE('Error: '||v_error_desc||'.');
v_row_count := 0;
v_total_rows_error := v_total_rows_error + 1;
ELSE
OPEN QUERY_CURSOR
FOR i in 1..ARTIST_TITLE_CURSOR
LOOP
FETCH QUERY_CURSOR into TITLE_RECORD;
EXIT WHEN QUERY_CURSOR%NOTFOUND or QUERY_CURSOR%NOTFOUND IS NULL;
DBMS_OUTPUT.PUT_LINE(title_record.id,title_record.gaid,title_record.artist_legal_name,title_record.artist_display_name,
title_record.display_title,title_record.category,title_record.type,title_record.sub_type);
END LOOP;
CLOSE QUERY_CURSOR;
v_row_count := 0;
END IF;
END LOOP;
CLOSE ARTIST_TITLE_CURSOR;
DBMS_OUTPUT.PUT_LINE(chr(0));
IF v_total_rows_error > 0 THEN
DBMS_OUTPUT.PUT_LINE('Total Rows in error: '||v_total_rows_error);
END IF;
DBMS_OUTPUT.PUT_LINE(CHR(0));
EXCEPTION
WHEN OTHERS THEN
v_error_desc := SQLERRM;
v_error_code := SQLCODE;
DBMS_OUTPUT.PUT_LINE('Error: '||v_error_desc||' - '||v_error_code);
END;
It's line 67 in what you've posted, not 61, but still; this line is not right:
FOR i in 1..ARTIST_TITLE_CURSOR
You're trying to loop over a range of numbers - perhaps you wanted the number of records returned by the cursor, which you can't get - but your end 'number' is a cursor, so not legal in that context.
But it seems to be completely out of place anyway as you're looping over the QUERY_CURSOR records, so I wouldn't think the ARTIST_TITLE_CURSOR is relevant at this point. And you aren't attempting to use i. It looks like you can just remove that line.
More importantly, the previous line is missing a semi-colon:
OPEN QUERY_CURSOR;
Because it doesn't have one it's seeing the FOR and expecting a cursor query.
Following up on comments about why you have that FOR 1..v_row_count, it's still a bit redundant. You're limiting the number of fetches you do to match the count you got previously, from essentially the same query as you have in the cursor, which means you don't quite ever hit the EXIT WHEN QUERYCURSOR%NOTFOUND condition - that would come from the v_row_count+1 loop iteration. Normally you wouldn't know how many rows you expect to see before you loop over a cursor.
You don't really need to know here. The count query is repetitive - you're querying the same data you then have to hit again for the cursor, and you have to maintain the query logic in two places. It would be simpler to forget the count step, and instead keep a counter as you loop over the cursor; then handle the zero-rows condition after the loop. For example:
DECLARE
...
BEGIN
OPEN ARTIST_TITLE_CURSOR;
LOOP
FETCH ARTIST_TITLE_CURSOR into v_artist,v_title;
EXIT WHEN ARTIST_TITLE_CURSOR%NOTFOUND;
-- initialise counter for each ARTIST_TITLE
v_row_count := 0;
OPEN QUERY_CURSOR;
LOOP
FETCH QUERY_CURSOR into TITLE_RECORD;
EXIT WHEN QUERY_CURSOR%NOTFOUND;
-- increment 'found' counter
v_row_count := v_row_count + 1;
DBMS_OUTPUT.PUT_LINE(title_record.id
||','|| title_record.gaid
||','|| title_record.artist_legal_name
||','|| title_record
||','|| artist_display_name
||','|| title_record.display_title
||','|| title_record.category
||','|| title_record.type
||','|| title_record.sub_type);
END LOOP;
CLOSE QUERY_CURSOR;
-- now check if we found anything in the QUERY_CURSOR loop
IF v_row_count < 1 THEN
v_error_desc := 'Matching Asset record for '||v_artist||' - '||v_title||' not found';
DBMS_OUTPUT.PUT_LINE('Error: Matching Asset record for '
|| v_artist || ' - ' || v_title || ' not found.');
v_total_rows_error := v_total_rows_error + 1;
END IF;
END LOOP;
CLOSE ARTIST_TITLE_CURSOR;
--DBMS_OUTPUT.PUT_LINE(chr(0));
-- presumably this was meant to put out a blank line; use this instead
DBMS_OUTPUT.NEW_LINE;
IF v_total_rows_error > 0 THEN
DBMS_OUTPUT.PUT_LINE('Total Rows in error: '||v_total_rows_error);
END IF;
--DBMS_OUTPUT.PUT_LINE(CHR(0));
DBMS_OUTPUT.NEW_LINE;
END;
I've also taken out the exception handler because it isn't really adding anything; you'd see the code and message without it, even if you didn't have server output on; and catching WHEN OTHERS is a bad habit to get into.
You also don't need to declare your record type. You could use an implicit cursor anyway and avoid the type and variable completely, but even with the cursor definition you have, you could put this afterwards instead:
TITLE_RECORD QUERY_CURSOR%ROWTYPE;
There are various ways to open and loop over cursors, and you're using one of the more explicit ones - which isn't a bad thing for learning about them, but be aware of the options too.

Error on creating stored procedure under Oracle - PLS-00103

Im trying to create a stored procedure that calls another a number of times. This is done so by using a for each loop. All the development is under oracle sql developer Version 3.0.04.
CREATE OR REPLACE PROCEDURE Z_INBILLABILITYSERV
IS BEGIN
DECLARE
ano VARCHAR2(4);
BEGIN
select EXTRACT(YEAR FROM sysdate) into ano from dual;
FOR dat IN (SELECT * FROM Z_FECHOMES WHERE MES <=
(select EXTRACT(MONTH FROM sysdate) from dual )and ANO = ano)
LOOP
call z_insertbillability(dat.periodo_inicio,dat.periodo_fim,
dat.ano,dat.mes);
END LOOP;
END;
END;
Im having the following error:
Error(9,12): PLS-00103: Encountered the symbol "Z_INSERTBILLABILITY" when expecting one of the following: := . ( # % ; The symbol ":=" was substituted for "Z_INSERTBILLABILITY" to continue.
If anyone have an idea or a tip i would be glad to now and would appreciate a lot.
You do not need the word call; just do:
LOOP
z_insertbillability(dat.periodo_inicio,dat.periodo_fim,
dat.ano,dat.mes);
END LOOP;
The error message is perhaps a bit unhelpful, but it's to be trying to show all the ways it could try to interpret the word call, since it doesn't recognise it as a keyword. And showing what it would expect to see next for each: as a variable name (which would be followed by := for assignment; or a schema name (which would be followed by .); or a function/procedure name (which would be followed by ( for the parameter list), etc.

Resources