I'm using Oracle Forms Builder 11.
My code:
declare
type myType is varray(3000) of my_table%rowtype;
myAsset myType:=myType();
i number;
n number;
exNoInvNum exception;
begin
go_block('my_block');
first_record;
i:=1;
loop
myAsset.extend();
myAsset(i).hqId:=:my_block.hqId;
myAsset(i).deptId:=:my_block.deptId;
myAsset(i).invNum:=:my_block.invNum;
exit when :system.last_record='TRUE';
i:=i+1;
next_record;
end loop;
go_block('my_block');
first_record;
loop
if (:my_block.linkedInvNum is not null) then
n:=0;
select count(*) into n
from my_table s
where s.invNum=:my_block.linkedInvNum
and s.hqId=:my_block.hqId
and (s.deptId=:my_block.deptId
or (s.deptId is null and :my_block.deptId is null));
if (n=0) then
for i in myAsset.first .. myAsset.last loop
if (myAsset(i).invNum=:my_block.linkedInvNum
and myAsset(i).hqId=:my_block.hqId
and (myAsset(i).deptId=:my_block.deptId
or (myAsset(i).deptId is null and :my_block.deptId is null))) then
n:=1;
end if;
end loop;
end if;
if (n=0) then
raise exNoInvNum;
else
commit_form;
go_block('my_table');
clear_block(no_validate); set_item_property('my_block.generate_excel',ENABLED,property_true); set_item_property('my_block.process_data',ENABLED,property_false);
end if;
end if;
exit when :system.last_record='TRUE';
next_record;
end loop;
exception
when exNoInvNum then
message('No existing inventory number!');
when others then
null;
end;
end;
I get Error 103 ad line 2, column 1: Encountered the symbol "END"
I checked my code for typo errors, missing semicolumns and similar stuff, but it looks like everything is fine.
Any ideas?
I get Error 103 ad line 2, column 1: Encountered the symbol "END"
Well, you do have an extra END keyword in your PL/SQL block.
end;
end;
The syntax for an anonymous PL/SQL block is:
DECLARE
...
BEGIN
...
EXCEPTION
...
END;
And, this:
when others then
null;
is itself a bug in your code.
A when others is almost always a BUG unless it is immediately followed by a RAISE. Remember, for errors, RAISE –> CATCH –> HANDLE. why do we need an exception handler? To catch the errors, log them(optional), and finally do something about them.
Read WHEN OTHERS THEN NULL – A bug
Related
Trying to handle exception if the input file received has invalid records or no data. The below exception runs in loop even though the input file has only 1 record.
LOOP
BEGIN
UTL_FILE.GET_LINE(a_UIN_input_file,a_UIN_file);
a_rec := substr(a_uin_file,1,9);
EXCEPTION
WHEN NO_DATA_FOUND THEN
a_error_file := utl_file.fopen('TAMUOUT','PWT_TEST5_ERROR.txt','w');
utl_file.put_line(a_error_file,'Bad UIN Read ' ||SQLERRM||'\n');
utl_file.fclose(a_error_file);
-- EXIT;
END;
END LOOP;
FOR rec IN get_details_4_uin_c(a_rec) LOOP
a_pidm :=fwt_get_pidm_from_uin(a_rec);
a_bill_hours := fwt_get_enrolled_hours(a_pidm,in_term_code);
utl_file.put_line(a_out_file,a_parm,
autoflush=>TRUE);
END LOOP;
utl_file.fclose(a_uin_input_file);
UTL_FILE.GET_LINE raises the NO_DATA_FOUND exception when you have reached the end of the file and then keep on trying to read more.
So your exception handler for NO_DATA_FOUND should exit the loop. But within the loop, if you read a line successfully, then run your loop on that.
I believe the code believe will help you get to your solution.
BEGIN
LOOP
BEGIN
UTL_FILE.get_line (a_uin_input_file, a_uin_file);
a_rec := SUBSTR (a_uin_file, 1, 9);
FOR rec IN get_details_4_uin_c (a_rec)
LOOP
a_pidm := fwt_get_pidm_from_uin (a_rec);
a_bill_hours := fwt_get_enrolled_hours (a_pidm, in_term_code);
UTL_FILE.put_line (a_out_file, a_parm, autoflush => TRUE);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
UTL_FILE.fclose (a_uin_input_file);
EXIT;
END;
END LOOP;
END;
I'm running into a behavior where I'm trying to use case-specific exception handlers for several Oracle PL/SQL blocks in a Flyway script and Oracle, apparently contradicting its documented scoping for exception handlers, sends all exceptions to the exception handler for the first block. For example, in this code:
begin
begin
execute immediate '
create table "test" (
"id" number not null,
"name" varchar2(100) not null,
constraint "test_pk" primary key ("id")
)
';
exception
when others then
if sqlcode != -955 then raise; end if;
end;
begin
execute immediate 'fail to create index "test_name_idx" on "test" ("name")';
exception
when others then
if sqlcode != -6512 then raise; end if;
end;
end;
the ORA-06512 exception is not caught, and the exception raised is tagged as from line 13.
Wrapping the blocks in more blocks doesn't help.
What is going on here? How do I stop this from happening?
This seems to be a bug, which has (so far) been reproduced in 11.2.0.4, 12.1.0.2 and 12.2.0.1. It doesn't seem to require DDL, or any real action in the first sub-block (though just doing null; as a placeholder doesn't trigger it, possibly because the compiler removes it), but it does seem to need the if inside both exception handlers:
begin
begin
dbms_output.put_line('Dummy message');
exception
when others then
dbms_output.put_line('In first exception handler');
if 1=1 then
raise;
end if;
end;
begin
execute immediate 'invalid';
exception
when others then
dbms_output.put_line('In second exception handler');
if 1=1 then
raise;
end if;
end;
end;
/
Dummy message
In second exception handler
ORA-00900: invalid SQL statement
ORA-06512: at line 8
ORA-06512: at line 13
As with your example the exception is thrown by line 13 so should be reported as (re-)raised at line 18; but it's instead it's reported as raised from line 8, which doesn't make sense. (The at line 13 message is only shown in 12.2; in 11.2 and 12.1 it only reports the first ORA-06512, which is rather more confusing. At least in 12 2 you have some clue where the problem really is.)
From the debugs you can see it doesn't actually use the first exception handler, and it does go into the second one. It 'only' seems to be reporting against the wrong line number, rather than executing the wrong code.
It appears that doing real work inside the if, immediately before the raise somehow fixes things - in either exception handling section; this adds a message in the first, which can't be reached:
begin
begin
dbms_output.put_line('Dummy message');
exception
when others then
dbms_output.put_line('In first exception handler');
if 1=1 then
dbms_output.put_line('This avoids the bug somehow');
raise;
end if;
end;
begin
execute immediate 'invalid';
exception
when others then
dbms_output.put_line('In second exception handler');
if 1=1 then
raise;
end if;
end;
end;
/
Dummy message
In second exception handler
ORA-00900: invalid SQL statement
ORA-06512: at line 19
ORA-06512: at line 14
and this in the second:
begin
begin
dbms_output.put_line('Dummy message');
exception
when others then
dbms_output.put_line('In first exception handler');
if 1=1 then
raise;
end if;
end;
begin
execute immediate 'invalid';
exception
when others then
dbms_output.put_line('In second exception handler');
if 1=1 then
dbms_output.put_line('This avoids the bug somehow');
raise;
end if;
end;
end;
/
Dummy message
In second exception handler
ORA-00900: invalid SQL statement
ORA-06512: at line 19
ORA-06512: at line 13
In both cases the reported line number is now correct. Somehow.
It doesn't have to be a dbms_output call, anything seems to work, such as a dummy procedure call or query, even an extra sub-block (e.g. begin execute immediate 'select * from dual'; end;, even though the query isn't executed because there's no into...). Again just using null; doesn't work though.
This is a bit ugly but gives you a way to stop it from happening at least, sort of.
It's clearly weird and unexpected and inconsistent behaviour, and has been around for a while, so it should probably be raised as a service request through My Oracle Support. I can't see any existing reports but I didn't look very hard so there might be one lurking somewhere.
This question is not duplicate. (i m using oracle 10g)
I searched a lot but my problem seems to be diffrent
I have following cursor
DECLARE
-- Some declarations
--
CURSOR C1 IS
-- some select statements
Begin
for r in c1 loop
-- Insert queries
DBMS_OUTPUT.PUT_LINE('INSERTED records');
End loop;
EXCEPTION WHEN others THEN
dbms_output.put_line('error' || SQLERRM);
END;
As per the above cursor, whenever error occures during insert , error is printed on output and execution stops.
whereas It should continue looping.
I tried adding exception block inside loop but still not working
Then you have to use another begin - exception - end within de loop.
Something like this.
DECLARE
-- Some declarations
--
CURSOR C1 IS
-- some select statements
Begin
for r in c1 loop
BEGIN
-- Insert queries
DBMS_OUTPUT.PUT_LINE('INSERTED records');
EXCEPTION
WHEN OTHERS
THEN
dbms_output.put_line('error in LOOP' || SQLERRM);
END;
End loop;
EXCEPTION WHEN others THEN
dbms_output.put_line('error' || SQLERRM);
END;
getting an error "ORA-00905 missing keyword" from the inner exception Begin and end;Any idea ?
passing all the table name based on the deptno (dyanmically)
Inner begin is throwing that error.
getting an error "ORA-00905 missing keyword" from the inner exception Begin and end;Any idea ?
passing all the table name based on the deptno (dyanmically)
Inner begin is throwing that error.
enter code here
declare
type deptcursor is ref cursor;
c1 deptcursor;
v_records abc%rowtype;
begin
if deptno=10
v_table=abc;
v_table1=abc1;
elsif deptno=20
v_table=xyz;
v_table1=xyz1;
end if;
v_cursor= 'select * from '||v_table||'';
begin
-- issue loop
OPEN C1 FOR v_cursor;
LOOP
FETCH C1
INTO v_records.column1,v_records.column2,v_records.column3;
EXIT WHEN C1%NOTFOUND;
BEGIN -- begin start
v_select:='select sum(NVL(salary,0)) ,sum(NVL(salary1,0))
INTO v_sal ,v_sal1
from '||v_table1||'
where col1 ='''||v_records.column1||'''
and col2 ='''||v_records.column2||'''
and col3 IN (select col3
from XXYYZZ
where column1 = '''||newvariable passing from procedure||'''
and column2 = '''||v_records.column2||''')';
--DBMS_OUTPUT.PUT_LINE(v_select);
EXECUTE IMMEDIATE v_select;
exception
when others then
DBMS_OUTPUT.PUT_LINE(sqlerrm);
end; -- end
end loop;
end;
One problem is that you have if deptno=10 without a following then. Another is that the elsif in the same if statement also lacks a then. In PL/SQL an if statement should generally be:
IF condition THEN
block_of_code;
ELSIF condition2 THEN
another_block_of_code;
ELSE
yet_another_block_of_code;
END IF;
Documentation here
In addition v_cursor= 'select * from '||v_table||''; should be
v_cursor := 'select * from '||v_table||'';
This is because the assignment operator in PL/SQL is :=, not = as it is in C, C++, Java, C#, etc.
Finally, it appears you're missing one END statement at the end of your code.
Share and enjoy.
I think, in your code:
if deptno=10
v_table=abc;
v_table1=abc1;
elsif deptno=20
v_table=xyz;
v_table1=xyz1;
end if;
The assignments should be ":=" instead of just "=". ALso, assuming "abc", "abc1" etc are literals and not variables, try enclosing in single-quotes:
if deptno=10
v_table:='abc';
v_table1:='abc1';
elsif deptno=20
v_table:='xyz';
v_table1:='xyz1';
end if;
I have a few SQL (Select/Update/Insert) syntax that I will run inside PL/SQL one after another
is there any way to check if each syntax completed correctly and if there is some error it will not halt the whole PL/SQL, it will just return "OK" or "Not OK" to a variable so I can use it with IF?
UPDATE
I came up with this function, but it dose not seems to work, it returns 0 all time!
create or replace
FUNCTION EXECUTE_SQL(
V_SQL IN VARCHAR2 )
RETURN NUMBER
AS
V_RESULTS NUMBER := 1;
BEGIN
BEGIN
EXECUTE IMMEDIATE V_SQL;
EXCEPTION
WHEN OTHERS THEN
-- the following line is just for debugging!
dbms_output.put_line(SQLERRM);
V_RESULTS:= 0;
END;
RETURN V_RESULTS;
END EXECUTE_SQL;
what is wrong wit it (if any)!
cheers
if sql%rowcount > 0 then
-- insert or update statement affected sql%rowcount rows
end if;
As for the correct syntax: if the syntax is wrong, it won't even compile. If there's a data consistency error (such as divide by 0 error, or primary key violation) an exception will be thrown. Such exception can be caught in exception handlers
In the exception handler, you can then check sqlerrm for more details:
begin
update t set x = ...
exception when others then
dbms_output.put_line(SQLERRM);
end;
There are also a few predefined exceptions that you can check on:
begin
update t set x = ...
exception
when DUP_VAL_ON_INDEX
-- primary key or unique key violation
when OTHERS
-- other kind of exception
end;
If the syntax is not correct the entire block will be invalid, so you'll not be able to run it.
If you want to run all statements, despite that one can raise an exception, you can:
BEGIN
BEGIN
statement1;
EXCEPTION
when exception1 then
some commands or null;
when exception2 then
some commands or null;
END;
BEGIN
statement2;
EXCEPTION
when exception3 then
some commands or null;
when exception4 then
some commands or null;
END;
etc.
END;
Write show errors
begin
update t set x = ...
exception
when DUP_VAL_ON_INDEX
-- primary key or unique key violation
when OTHERS
-- other kind of exception
end;
/
show errors
It will show errors if any.