Error while compiling cursor in plsql block - oracle

I have a table as employee. I am new to oracle.I am creating the cursor but when I compile,I get error:
DECLARE
CURSOR c_data IS
SELECT distinct dept_id
FROM offc.employee;
tmp_event offc.employee.dept_id%type;
BEGIN
OPEN c_data;
LOOP
FETCH c_data INTO tmp_event;
EXIT WHEN c_data%NOTFOUND;
Dbms_Output.Put_Line(tmp_event.dept_id);
END LOOP;
CLOSE c_data;
END;
/
I got the error as follows:
Error at line 1 ORA-06550: line 15, column 40: PLS-00487: Invalid
reference to variable 'TMP_EVENT' ORA-06550: line 15, column 9:
PL/SQL: Statement ignored
I think there is problem in tmp_event declaration.How to handle this error?

You should use Dbms_Output.Put_Line(tmp_event);
where tmp_event is a variable which is already of type offc.employee.dept_id%type
This link would help for details.

Try Below Query
DECLARE
CURSOR c_data IS
SELECT distinct dept_id
FROM offc.employee;
tmp_event offc.employee.dept_id%type;
BEGIN
OPEN c_data;
LOOP
FETCH c_data INTO tmp_event;
EXIT WHEN c_data%NOTFOUND;
dbms_output.Put_line(tmp_event); --Dont Use Dept id
END LOOP;
CLOSE c_data;
END;
/

The following PL/SQL statement is equivalent to the original statement, but way shorter and thus less prone to programming errors.
DECLARE
CURSOR c_data IS
SELECT DISTINCT dept_id
FROM offc.employee;
BEGIN
FOR r_data IN c_data LOOP
Dbms_Output.Put_Line(r_data.dept_id);
END LOOP;
END;
/

Related

I am getting an error message in Oracle SQL stored procedure

I am trying the following code
CREATE OR REPLACE PROCEDURE sal2
AS
BEGIN
SELECT sal
FROM emp
END
And I'm getting this error
Error at line 7: 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
<< continue close current delete fetch lock
insert open rollback savepoint set sql execute commit forall
merge pipe purge
5. from emp
6. return 1
7. END
What I want to do is to get a sal column from emp table.
There are multiple issues with code as following;
create or replace procedure sal2
AS
Lv_var number; -- added variable for holding select value
BEGIN
select sal
Into lv_var -- into is needed in select
from emp; -- you missed this semicolon
-- you must use where clause as into variable can hold single value
-- so you must restrict this query to return only 1 record.
END; -- you missed this semicolon
/
Cheers!!
First you have to put the semicolon at the end of each line and after the END keyword. Then the SELECT statement is also wrong you have to load the result in a variable.
Here is the solution for multiple rows.
CREATE OR REPLACE PROCEDURE sal2
AS
CURSOR c_salaries IS SELECT salary FROM employees;
TYPE t_salaries IS TABLE OF c_salaries%rowtype INDEX BY BINARY_INTEGER;
v_salaries t_salaries;
BEGIN
OPEN c_salaries;
FETCH c_salaries BULK COLLECT INTO v_salaries;
CLOSE c_salaries;
END;
And one for a single row result.
CREATE OR REPLACE PROCEDURE sal2
AS
v_salary employees.salary%rowtype;
BEGIN
SELECT salary INTO v_salary
FROM employees WHERE employee_id = 100;
END;

Handling ORA-01403: no data found

I want to handle no data found. Whenever this exception is raised I want the program to continue, without stopping on error. Below is code snippet
BEGIN
OPEN C_TABLE_PARTITON_LIST;
LOOP
FETCH C_TABLE_PARTITON_LIST INTO TABLE_PARTITION_LIST;
EXIT WHEN C_TABLE_PARTITON_LIST%NOTFOUND;
SELECT COLUMN_NAME INTO PARTITION_COLUMN_NAME from ALL_PART_KEY_COLUMNS
sqlstring :='SELECT ( '|| PARTITION_COLUMN_NAME ||'from test';
EXECUTE IMMEDIATE sqlstring INTO F_RESULT;
exception when no_data_found then
dbms_output.put_line('no data found.');
DBMS_OUTPUT.put_line( F_RESULT);
END LOOP;
CLOSE C_TABLE_PARTITON_LIST;
END;
When I add Exception, my code is breaking with below error
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 while with
<<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
json_exists json_value json_query json_object json_array
ORA-06550: line 29, column 3:
PLS-00103: Encountered the symbol "CLOSE" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
You have to enclose offending part of the script into its own BEGIN-EXCEPTION-END block, e.g.
BEGIN
OPEN C_TABLE_PARTITON_LIST;
LOOP
FETCH C_TABLE_PARTITON_LIST INTO TABLE_PARTITION_LIST;
EXIT WHEN C_TABLE_PARTITON_LIST%NOTFOUND;
begin --> you need this ...
SELECT COLUMN_NAME INTO PARTITION_COLUMN_NAME from ALL_PART_KEY_COLUMNS
sqlstring :='SELECT ( '|| PARTITION_COLUMN_NAME ||'from test';
EXECUTE IMMEDIATE sqlstring INTO F_RESULT;
exception when no_data_found then
dbms_output.put_line('no data found.');
DBMS_OUTPUT.put_line( F_RESULT);
end; --> ... and this
END LOOP;
CLOSE C_TABLE_PARTITON_LIST;
END;
Note that I just showed the way to do that. Code you posted
is incomplete (misses the DECLARE section)
is invalid (SELECT statement lacks semi-colon, and probably a WHERE clause
SQLSTRING variable won't work; 'from test' should have a leading space, otherwise that statement will be invalid
I suggest you first DBMS_OUTPUT the SQLSTRING to make sure it is correct; then execute it.

DBMS_OUTPUT.PUT_LINE returning error

I am attempting to write a basic PL/SQL For Loop and keep getting an error. My statement is:
begin
for tab_x in
(select unique table_name from all_tables
where owner like 'MSGCENTER_DBO%'
and table_name like 'MSG_DETAIL%')
loop
DBMS_OUTPUT.PUT_LINE(tab_x);
end loop;
end;
/
The error message is
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
ORA-06550: line 6, column 7:
PL/SQL: Statement ignored
I am probably missing something VERY obvious but have not been able to get this to work. I appreciate any help!
You want to access tab_x.table_name instead.
begin
for tab_x in
(select unique table_name from all_tables
where owner like 'MSGCENTER_DBO%'
and table_name like 'MSG_DETAIL%')
loop
DBMS_OUTPUT.PUT_LINE(tab_x.table_name );
end loop;
end;
/

Error trying to print Collection variable by index

Can anyone identify what is wrong with the following code. specifically the first dbms_output line. The second one prints fine. But first one gives this error:
Error at line 2
ORA-06550: line 15, column 53:
PLS-00201: identifier 'MYCOLL' must be declared
ORA-06550: line 15, column 1:
PL/SQL: Statement ignored
DECLARE
CURSOR c1
IS
SELECT sub_provider_address_id sub_id, phone, extension
FROM sub_provider_address;
TYPE coll_type IS TABLE OF c1%ROWTYPE;
my_coll coll_type;
BEGIN
OPEN c1;
FETCH c1
BULK COLLECT INTO my_coll;
dbms_output.put_line(' my_coll first row id has '|| mycoll(1).phone );
dbms_output.put_line(' my_coll now has '|| my_coll.last );
END;
You're declaring the variable as my_coll:
my_coll coll_type;
And on the line that's erroring you're referring to it as mycoll:
dbms_output.put_line(' my_coll first row id has '|| mycoll(1).phone );
So you're just missing an underscore, and it should be:
dbms_output.put_line(' my_coll first row id has '|| my_coll(1).phone );
Your coll_type is not an associated array type.
you have to use something like this:
TYPE coll_type IS TABLE OF c1%ROWTYPE index by pls_integer;
Use this as an example:
declare
cursor c1 is
select 1 id from dual
;
type coll_type is table of c1%ROWTYPE index by pls_integer;
l_coll_type coll_type;
begin
open c1;
fetch c1 bulk collect into l_coll_type;
close c1;
dbms_output.put_line('Output:' || l_coll_type(1).id);
end;
Output:1

PL/SQL Printing Cursor Elements

I tried several ways and looked lots of codes, but I couldn't do it. I have 2 tables
Declare
v_ay varchar2(32);
cursor c_clone_time is
select beko_user_ref
from user_role;
begin
open c_clone_time;
fetch c_clone_time into v_ay
WHILE c_clone_time%FOUND LOOP
dbms_output.put_line (v_ay);
end while;
end;
I'm just trying to print the cursor values, but it is always failing. Can anyone help me ?
There are several spots(syntactical, semantical, and logical errors) in your code needed attention:
Minor one. The fetch c_clone_time into v_ay statement not terminated by semicolon ;.
You end while as any other loop statement with end loop; clause, not end while or end for as you might think.
To be able to print the contents of the cursor and successfully get out of the loop, you need to fetch from that cursor inside the loop as well, otherwise you are stuck with a never-ending loop:
Having said that your code might look look this:
declare
v_ay varchar2(32);
cursor c_clone_time is
select beko_user_ref
from user_role;
begin
open c_clone_time;
fetch c_clone_time into v_ay;
while c_clone_time%found loop
dbms_output.put_line (v_ay);
fetch c_clone_time into v_ay;
end loop;
end;
Test case:
create table user_role(
beko_user_ref varchar2(100)
);
insert into user_role(beko_user_ref)
select dbms_random.string('l', 7)
from dual
connect by level <= 7;
commit;
Print the cursor:
set serveroutput on;
clear screen;
declare
v_ay varchar2(32);
cursor c_clone_time is
select beko_user_ref
from user_role;
begin
open c_clone_time;
fetch c_clone_time into v_ay;
while c_clone_time%found loop
dbms_output.put_line (v_ay);
fetch c_clone_time into v_ay;
end loop;
end;
Result:
anonymous block completed
kcjhygy
cgunlmt
ofxaspd
qwqvnxx
nxjdrli
luevaqk
xvdocpr

Resources