Oracle SQL procedure error I can't debug - sql

I created the procedure below successfully, however when I run it, I get ORA-01422: exact fetch returns more than requested number of rows error.
Can anyone help in resolving my issue. Thanks
CREATE OR REPLACE PROCEDURE proc_create_new_user AUTHID CURRENT_USER IS
vc_username VARCHAR2(50);
vc_new_user VARCHAR2(100);
BEGIN
SELECT username
INTO vc_username FROM marketing;
FOR i IN 1..3 LOOP
vc_new_user:=
'CREATE USER '||vc_username||' IDENTIFIED BY password'||(i);
DBMS_OUTPUT.PUT_LINE('USER '||vc_new_user||' HAS BEEN CREATED');
EXECUTE IMMEDIATE vc_new_user;
END LOOP;
END proc_create_new_user;
/
EXECUTE proc_create_new_user;
error: ORA-01422: exact fetch returns more than requested number of rows

Your select is giving you more than one record which you are trying to hold in a variable that can hold only one value. Try using a WHERE clause in your select statement.
SELECT username
INTO vc_username FROM marketing
WHERE userid = '1234';

Related

How to get NO_DATA_FOUND exception to output when using COUNT(*)?

I am trying to determine why my exception output is not returning correctly.
This is for Oracle SQL Developer, practicing with PL/SQL. I can provide the table code if requested.
SET serveroutput on
CREATE OR REPLACE Procedure GetPermissions(user IN VARCHAR, docNum OUT
INTEGER)
IS
BEGIN
SELECT count(*) INTO docNum FROM UserPermissions where UserName=user;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Nothing found for this username');
END;
/
DECLARE
doc_count INTEGER;
BEGIN
doc_count:=0;
GetPermissions('Steve', doc_count);
dbms_output.put_line(' Number of documents: ' || doc_count);
END;
/
I am expecting the exception to return its output (nothing found) when 'Steve' is ran through as that is not a username in the table I created. When running currently is just shows "Number of documents: 0".
COUNT always returns a result, in this case, it returns a single row with 0 in it:
COUNT(*)
--------
0
NO_DATA_FOUND occurs only when the SELECT INTO query doesn't return any row.
For example, NO_DATA_FOUND will be thrown, if you try to select permission for a given user:
SELECT permission
INTO p_permission
FROM UserPermissions
WHERE UserName=user;
In this case, the query will return an empty result.
select into query returns with No_Data_found exception when the out put of the query is no rows. not when it is 0.
Another exception you get with select into clause is too many rows where the query returns more that 1 row and you are trying to assign all those to a variable.

Invalid identifier error while running plsql block

Since my school does not allow me to post the code, hence i had to come back home and put up an example to show the issue i am facing. My school asked me to do a homework on dynamic sql to create a table and later insert one dummy record to it. But while doing it I am facing the below issue. Please find the code below for your reference. Thank you.
Procedure:
create or replace procedure table_creation(table_name in varchar2,col1 varchar2,col2 varchar2)
is
l_stat varchar2(3000);
v_stat varchar2(1000);
a varchar2(10):='1';
b varchar2(10):='Dummy';
begin
l_stat:='create table '||table_name||' ("'||col1||'" varchar2(10),"'||col2||'" varchar2(10))';
execute immediate l_stat;
execute immediate 'insert into '||table_name||'('||col1||','||col2||') values (:x,:y)' using a,b;
end;
/
Plsql Block to call the procedure:
set serveroutput on;
declare
a varchar2(10);
b varchar2(10);
c varchar2(10);
begin
a:='Example';
b:='id';
c:='nm';
table_creation(a,b,c);
dbms_output.put_line('Yes');
end;
/
The procedure is getting created perfectly and while running the above block i am getting the below error .
declare
*
ERROR at line 1:
ORA-00904: "NM": invalid identifier
ORA-06512: at "SYS.TABLE_CREATION", line 9
ORA-06512: at line 9
But when I checked the created table. The table exists with 0 records. The structure of the table is as follows.
Name Null? Type
----------------------------------------- -------- ---------------
ID VARCHAR2(10)
NM VARCHAR2(10)
Any help from your end is much appreciated.
Nick,
Please note that the above procedure will create the column with a double qoutes ("ID","NM") hence the error occurred. Please find the updated code and check if the issue has resolved.
According to oracle=>
Oracle is case sensitive in column and table names. It just converts everything to upper case by default. But if you use names in double quotes, you tell Oracle to create the column in the exact spelling you provided (lower case in the CREATE statement).
Code:
create or replace procedure table_creation(table_name in varchar2,col1 varchar2,col2 varchar2)
is
l_stat varchar2(3000);
v_stat varchar2(1000);
a varchar2(10):='1';
b varchar2(10):='Dummy';
begin
l_stat:='create table '||table_name||' ('||col1||' varchar2(10),'||col2||' varchar2(10))';
execute immediate l_stat;
execute immediate 'insert into '||table_name||'('||col1||','||col2||') values (:x,:y)' using a,b;
end;
/
Note: I have not touched any other logic of the code. Please try and let us know the result.
Only change is
From :
l_stat:='create table '||table_name||' ("'||col1||'" varchar2(10),"'||col2||'" varchar2(10))';
to :
l_stat:='create table '||table_name||' ('||col1||' varchar2(10),'||col2||' varchar2(10))';

How do you update a SQL record with ORDSYS.ORDImage in a procedure

I'm trying to create a procedure that will update a column in my table with an ORDSYS.ORD Image. The code I have is bellow and it keeps telling me errors when I'm trying to use it. Can some please help? Thank you
Procedure code:
create or replace
PROCEDURE Inserting_Images (REST_ID NUMBER, RESTImage ORDSYS.ORDImage) AS
ctx RAW(64):=NULL;
BEGIN
UPDATE restaurant_table
Set RESTImage = RESTImage
WHERE REST_id = REST_ID;
COMMIT;
EXCEPTION
WHEN others THEN
BEGIN
ROLLBACK;
dbms_output.put_line(sqlerrm);
END;
--Error Handling.
END;
--Ends the procedure.
Using Procedure:
BEGIN
inserting_images(52, 'YUSKIN.jpeg');
END;
The function Inserting_Images accepts an argument of ORDSYS.ORDImage, whereas what you are actually sending it is a VARCHAR, to get the behaviour you want, you need to initialize the ORDImage object first like so:
CREATE OR REPLACE DIRECTORY FILE_DIR as '/mydir/work';
GRANT READ ON DIRECTORY FILE_DIR TO 'user';
inserting_images(52, ORDSYS.ORDImage.init('FILE', 'FILE_DIR','speaker.jpg'));
(Quoted from docs.oracle.com)

How to return multiple row by pl/sql stored function?

I search for this issue and finally I found a solution on this website but I get a strange error. I searched for the error but because I know very basic of pl/sql I was not able to solve it. here is my function which is trying to return name of the table:
CREATE OR REPLACE Function FF(BSB_NUMBER IN BANK.BSB#%TYPE) RETURN SYS_REFCURSOR
IS
C_RESULT SYS_REFCURSOR;
BEGIN
OPEN C_RESULT for
select * from bank where bank.bsb# = BSB_NUMBER;
return C_RESULT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Error ! There is no such account');
END FF;
/
AFTER i RUN=
Function created.
AFTER EXEC
SELECT * FROM TABLE(FF(012878));
ERROR:
ERROR at line 1:
ORA-22905: cannot access rows from a non-nested table item
Normally ref cursors are passed to client programs, such as JDBC Result Sets. However, it's easy enough to call a ref cursor in SQL:
select FF(012878) from dual;

how to access an Oracle procedure's OUT parameter when calling it?

If I write a simple function doSomething, I can get its result by executing :
select doSomething() from dual;
But, if I wish to call a procedure that has an OUT cursor being passed to it (along with another int parameter), how do I call that procedure inside a query and access the result of the cursor ?
Calling it inside a query is not compulsory.. its just that I want to access the results of that procedure
You can create a procedure like
CREATE OR REPLACE PROCEDURE your_procedure(out_cursor OUT sys_refcursor)
IS
BEGIN
OPEN out_cursor FOR
SELECT employee_name
FROM employees;
END;
/
Once you create your procedure wrap the procedure in a function which returns a cursor like the following
CREATE OR REPLACE FUNCTION your_function
RETURN sys_refcursor
AS
o_param sys_refcursor;
BEGIN
o_param := NULL;
your_procedure(o_param);
RETURN o_param;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- raise
WHEN OTHERS
THEN
-- raise
END your_function;
/
To see the results from sql do as
select your_function from dual;
Update 1
To see result in SQL Developer
Step 1
Double click on your results in SQL Developer
[Results][1]
Step 2 Single Click on the button with dots. That will pop up the values
[Grid][2]
You can Do Something Like This
select doSomething(cursor (select int_col from your_table)) colname from dual
Hope this Help