Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
By using the bulk collect into, how you can detect when a query that does not return results to prevent an exception is thrown when trying to loop through the results?
An example from documentation:
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/tuning.htm#BABCCJCB
OPEN c1;
LOOP
FETCH c1 BULK COLLECT INTO names, sals LIMIT v_limit;
EXIT WHEN names.COUNT = 0;
print_results();
END LOOP;
CLOSE c1;
You can use this code:
open rc for select descr from hardware;
loop
fetch rc bulk collect into l_rows limit l_fetch_sizes(i);
exit when rc%notfound;
end loop;
close rc;
Exit When finalize the loop.
To catch exception for bulk collect DML operations you could you SQL%BULK_EXCEPTIONS:
BEGIN
-- DML operations
EXCEPTION
WHEN operation_erros THEN
l_error := SQL%BULK_EXCEPTIONS.count;
FOR ind IN 1 .. l_error LOOP
DBMS_OUTPUT.put_line('Error: ' || ind || ' Array Index: ' || SQL%BULK_EXCEPTIONS(ind).ERROR_INDEX || ' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(ind).ERROR_CODE));
END LOOP;
END;
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I'm trying this code for some test and i got this error ORA-06550
I tried to modify column with set and many things still the same result
CODE :
declare
cursor cur is select comm from emp where comm is not null ;
enreg emp.comm%type;
moyene number;
somme number;
begin
open cur;
loop
fetch cur into enreg;
if emp.comm=enreg.com then
ALTER TABLE emp
set columun
emp.comm := enreg.com*100/emp.comm ;
end if ;
exit when cur%notfound;
end loop;
end;
the expected result is to change every emp.comm with the 10% of it but i got this error
Error :
ORA-06550: line 12, column 1:
PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:
( begin case declare 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
1. declare
2. cursor cur is select comm from emp where comm is not null ;
3. enreg emp.comm%type;
In SQL, you use an UPDATE statement to change values in a table. ALTER TABLE is used to change the structure of a table, such as by adding columns, etc. You could rewrite your code as follows:
declare
cursor cur is select comm from emp where comm is not null;
enreg emp.comm%type;
moyene number;
somme number;
begin
open cur;
loop
fetch cur into enreg;
exit when cur%notfound;
if emp.comm = enreg then
update emp
set emp.comm = enreg * 100 / emp.comm;
end if ;
end loop;
commit;
end;
Best of luck.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 1 year ago.
Improve this question
Explanation with example of syscursor.
When to use syscursor in plsql procedure? I have go through websites but didn't get how and when to use this.
SYS_REFCURSOR are used by PL/SQL procedures to return recordsets.
Example - lets get all table details for a given schema and return through sys_refcursor
CREATE OR REPLACE PROCEDURE GET_TABLE_DETAILS(schemaName IN VARCHAR2,
table_details OUT SYS_REFCURSOR) IS
BEGIN
OPEN table_details FOR
select table_name, column_name, data_type from ALL_TAB_COLUMNS where OWNER = schemaName;
END GET_TABLE_DETAILS;
Here table_details out parameter will contain the result data of the select query, it can be retrieved as below.
DECLARE
table_details_cursor SYS_REFCURSOR;
tab_name ALL_TAB_COLUMNS.table_name%TYPE;
col_name ALL_TAB_COLUMNS.column_name%TYPE;
data_type ALL_TAB_COLUMNS.data_type%TYPE;
BEGIN
GET_TABLE_DETAILS (schemaName => 'DUMMY',
table_details => table_details_cursor);
LOOP
FETCH table_details_cursor
INTO tab_name, col_name, data_type;
EXIT WHEN table_details_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(tab_name || ' | ' || col_name || ' | ' || data_type);
END LOOP;
CLOSE table_details_cursor;
END;
However, you need to get through the Oracle documentation for detailed explanation - Oracle - Cursors Documenatation
As far as I know there is nothing like "syscursor" in Oracle. May be you are referring to SYS_REFCURSOR
The following url should help you in understanding how and when to use it.
https://oracle-base.com/articles/misc/using-ref-cursors-to-return-recordsets
This question already has an answer here:
PL/SQL ORA-01422: exact fetch returns more than requested number of rows
(1 answer)
Closed 6 years ago.
This is my code:
declare
name1 varchar2(25);
code number(3):=1;
begin
while(code<10)
loop
select attrname into name1 from catregionmap where attrtype=code;
dbms_output.put_line('The name for' || name1 || 'ways' );
code:= code+1;
end loop;
end;
But I get this error:
"ORA-01422: exact fetch returns more than requested number of rows"
How can I fix this?
You can always use a Cursor. The main reason why a cursor is used is in order to avoid the problem / issue faced by you. For the code from which you have received the oracle error "Too many" We can simply re write the code by using a simple cursor as given below (You have hard coded the value of attrtype between 1 and 10).
DECLARE
name1 VARCHAR2(25);
code NUMBER(3) := 1;
CURSOR c1 IS
SELECT attrname
FROM catregionmap
WHERE attrtype <= 10;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO name1;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.put_line('The name for' || name1 || 'ways');
code := code + 1;
END LOOP;
CLOSE c1;
END;
Please make a note of yourself that cursors are effectively used when number of records are being fetched from the select query. The code given by my friend XING is also correct as BULK collect is a way of avoiding cursor usage. I would suggest you to read the PLSQL manual better and gain knowledge in cursor and Bulk collect options.
Hope this would help you out. Thanks.!!!
The issue states that your select statement is returning more than 1 rows and you are trying to store many rows to a single variable name1 . In that case you need a collection to store your values.
Use this way:
DECLARE
type name11 is table of catregionmap.attrname%type index by pls_integer;
name1 name11;
code NUMBER (3) := 1;
BEGIN
WHILE (code < 10)
LOOP
SELECT attrname
BULK COLLECT INTO name1
FROM catregionmap
WHERE attrtype = code;
for rec in 1..name1.count
loop
DBMS_OUTPUT.put_line ('The name for' || name1(rec) || 'ways');
end loop;
code := code + 1;
END LOOP;
END;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm looking for a way to return one case-insensitive varchar2 from a table given as a parameter.
The database is configured to have as the first column the one I'll look into.
This is what I got to:
create or replace function generic_return(nam varchar2, table_n varchar2)
return varchar2
as
case_insensitive varchar2(300);
case_ins varchar2(300);
colu varchar2(30);
t_nam varchar2(30):=upper(table_n);
cursor point is execute inmediate select colu from t_nam;
cursor col is select column_name from cols where table_name=t_nam;
non_existent_table exception;
begin
case_ins:=upper(rtrim(ltrim(nam)));
open col;
fetch col into colu;
close col;
select column_name from cols where table_name=upper(table_n);
if colu is null then
raise non_existent_table;
end if;
open point;
loop
fetch point into case_insensitive;
exit when point%notfound;
if upper(case_insensitive)=case_ins then
return case_insensitive;
end if;
end loop;
close point;
return null;
end;
/
The function receives what to look for, and the name of the table to look into, then the first variables are to compare them, t_nam is to use the uppercased version of the second parameter... and from that there's the huge mess: I get the column name from the table in col, from cols, and then I try to make a cursor that goes around checking if what the tuple, going by the same modifications, is the first parameter, or not, if it happens to be, then it should return the unmodified version of the one in the table. Otherwise, it should return "null", which I'll treat differently on each procedure that uses it.
By null I mean nothingness, not the string.
Yes, you are right. That's a pretty huge mess. :-)
For starters, you cannot declare an explicit cursor as an execute immediate statement.
Next, if you want the first column in the table, you need to specify
WHERE column_id = 1
and then you can just grab it via a SELECT-INTO, no need for an explicit cursor.
Then you could try something like:
my_cur SYS_REFCURSOR;
BEGIN
...
OPEN my_cur FOR 'SELECT ' || first_col || ' FROM ' || t_name;
LOOP
FETCH my_cur INTO case_insensitive;
EXIT WHEN my_cur%NOTFOUND;
... logic for match ....
END LOOP;
CLOSE my_cur;
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
Is the usage of CASE wrong in the code below?
I am getting an error:
"PLS-00103: Encountered the symbol ";" when expecting one of the
following:
case The symbol "case" was substituted for ";" to continue. "
Code is :
create or replace PROCEDURE MIK_3PL_ITEM_ERRORS_PROC_1 IS
i_error_code varchar2(5);
i_desc varchar2(200);
CURSOR c_3pl_error IS
SELECT mie.client_item_id, mie.message_id,
mie.error_desc, mis.process_flag
FROM mik_3pl_item_error_etl mie,
dummy_staging mis
WHERE mie.client_item_id = mis.client_item_id
AND mie.message_id = mis.message_id;
BEGIN
dbms_output.put_line ('hello');
for i in c_3pl_error
loop
dbms_output.put_line ('in loop');
DECLARE
-- L_relations_exist VARCHAR2(1);
L_error_message VARCHAR2(255) := NULL;
L_return BOOLEAN := FALSE;
BEGIN
select error_code
into i_error_code
from mik_3pl_error_desc
where description = i.error_desc;
-- dbms_output.put_line(i_error_code);
CASE i_error_code
WHEN 'E2' THEN dbms_output.put_line ('in case');
END; -- end of CASE */
END; /*End of begin */
end loop;
END MIK_3PL_ITEM_ERRORS_PROC_1;
It needs to be:
...
CASE i_error_code
WHEN 'E2' THEN dbms_output.put_line ('in case');
END CASE; -- end of CASE */
END;
It's trying to treat the END; as the end of the block - matching that END with the BEGIN - and it knows the case is still open.
The documentation for the CASE statement shows that. (Not to be confused with a CASE expression, which does just have END. Ahem. Thank you Nicholas!)