why i am getting no data found error? - oracle

to a void this error i just make to variable so if there record return then do else do
but i am still getting this error anyone can help me to get out of that ?
thats worked at first query but not the query on line 35
can i use sql%rowcount instead ?
declare
cust_id bmh.info.CUSTOMER_ID#prod%type; --get the id of sp number
num number; -- count of records in rated_rejectes_calls_cursor
num1 number; -- count of records in rated_rejectes_calls_cursor
V_CUST_INFO_CUSTOMER_ID FI_MASAAD.FEB_PRD_14_VIEW.CUST_INFO_CUSTOMER_ID#rtx%type;
V_INITIAL_START_TIME_TIMESTAMP FI_MASAAD.FEB_PRD_14_VIEW.INITIAL_START_TIME_TIMESTAMP#rtx%type;
cursor rated_rejectes_calls_cursor is
select S_P_NUM,CALL_START_TIME
from fi_sdine.rejected_calls_87#prod
where UPPER (STATUS)='RATED';
begin
for rated_rejectes_calls_rec in rated_rejectes_calls_cursor
loop
select count(*) into num from bmh.info#prod where dn_num=rated_rejectes_calls_rec.S_P_NUM;
if num <>0 then
select CUSTOMER_ID into cust_id from bmh.info#prod where dn_num=rated_rejectes_calls_rec.S_P_NUM;
dbms_output.put_line('SP number, '||rated_rejectes_calls_rec.S_P_NUM||' ID is, '||cust_id||' and call start time, '||rated_rejectes_calls_rec.CALL_START_TIME);
select count(*) into num1
from FI_MASAAD.MAR_14_VIEW#rtx a
where CUST_INFO_CUSTOMER_ID =cust_id
and INITIAL_START_TIME_TIMESTAMP=rated_rejectes_calls_rec.CALL_START_TIME;
elsif num1 <> 0 then
select CUST_INFO_CUSTOMER_ID, INITIAL_START_TIME_TIMESTAMP into V_CUST_INFO_CUSTOMER_ID,V_INITIAL_START_TIME_TIMESTAMP
from FI_MASAAD.MAR_14_VIEW#rtx a
where CUST_INFO_CUSTOMER_ID =cust_id
and INITIAL_START_TIME_TIMESTAMP=rated_rejectes_calls_rec.CALL_START_TIME
group by CUST_INFO_CUSTOMER_ID,INITIAL_START_TIME_TIMESTAMP;
elsif num1 =0 then
dbms_output.put_line('tickets not found, '||rated_rejectes_calls_rec.S_P_NUM);
elsif num=0 then
dbms_output.put_line('SP number ID not found, '||rated_rejectes_calls_rec.S_P_NUM);
end if;
end loop;
end;
thank you all in advance

Use nested begin blocks..
BEGIN
--statements
BEGIN
select CUSTOMER_ID into cust_id from bmh.info#prod where dn_num=rated_rejectes_calls_rec.S_P_NUM;
EXCEPTION WHEN NO_DATA_FOUND THEN
--Handle Exception for No Data here
END;
EXCEPTION WHEN OTHERS THEN
-- Final Exceptions go here
END;
/

Related

ORA-01403: no data found ORA-06512: at line 8 01403. 00000 - "no data found"

Normally this basic If statement should return data but I don't understand, where I have made a mistake. (CustNo is char(8).) I think the problem occurs because of V_Id. In an usual select statement with this Custno='C2388597', I can have the data.But when it is in If statement, It gives the ORA-01403 Error code.
Thank you in advance for your Support...
Declare
V_Id Deneme_Customer.Custno%type;
V_Custbal Deneme_Customer.Custbal%Type;
v_situation Deneme_Customer.Custbal_Situation%type;
Begin
Select Custno, Custbal, Custbal_Situation Into V_Id, V_Custbal, V_Situation
From Deneme_Customer Where V_Id ='&no';
If (V_Custbal>=20 And V_Custbal<=100) Then
V_Situation:='Es tut mir sehr leid';
Elsif (V_Custbal>=101 And V_Custbal<=1000) Then
V_Situation:='Guuuut';
Elsif (V_Custbal>1000) Then
V_Situation:='Sehr Guuuut';
Else Dbms_Output.Put_Line('Falsche Eingabe');
End If;
update Deneme_Customer set Custbal_Situation=v_situation where Custno=V_Id;
end;`
I suppose v_id,which is a local variable, is Custno,which is a column of your table, on the 8th line.
An exception handling might still be needed for non-matching values for Custno vs. '&no' such as
Begin
Select Custno, Custbal, Custbal_Situation Into V_Id, V_Custbal, V_Situation
From Deneme_Customer
Where Custno = '&no';
Exception When no_data_found then null;
End;
Instead of using PL/SQL to determine what custbal_situation should be set to, you can do it easily with a simple update statement like this one:
UPDATE deneme_customer
SET custbal_situation =
CASE
WHEN custbal >= 20 AND custbal <= 100 THEN 'Es tut mir sehr leid'
WHEN custbal >= 101 AND custbal <= 1000 THEN 'Guuuut'
WHEN custbal > 1000 THEN 'Sehr Guuuut'
END
WHERE custbal >= 20;
If you want to modify it to only affect one customer, just add that to the where clause.
Then to see any customers that would not have their value set, you can find them with a query like this one
SELECT custno, custbal, custbal_situation
FROM deneme_customer
WHERE custbal < 20;
looks like you may not have any row matching Where V_Id ='&no', just to test it do a select count from the table Where V_Id ='&no'and check the count.
ALso is your V_Id a unique column, if not then you need to handle in your error handler the case when you fine more than one row matching your where clause.
exception
when no_data_found then
<handle apppropriately>
when TOO_MANY_ROWS then
<handle apppropriately>
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE
('Unknown error');
end

Subquery In if Statement (plsql)

I want to find if p_param2 is in subquery then do some operations according to this result. This subquery returns more than 1 row.
if p_param1 = 1
and p_param2 in (select code from x_table where code is not null) then
--..Some operations..
end if;
But I get PLS-00405 error. How can write this code effectively?
You need to get the needed value before IF..THEN statement within a seperate SQL query, while the current case is not possible. Try such a method which uses COUNT() aggregation without need of exception handling :
DECLARE
p_param1 ...
p_param2 ...
p_exists INT;
BEGIN
SELECT SIGN( COUNT(*) )
INTO p_exists
FROM x_table
WHERE code IS NOT NULL
AND code = p_param2;
IF p_param1 = 1 AND p_exists = 1 THEN
-- some operations
END IF;
END;
/
Declare a var v_dummy number. Then:
begin
select 1
into v_dummy
from x_table
where code = p_param2;
exception
when no_data_found then
v_dummy := 0;
end;
if p_param1 = 1 and v_dummy = 1 then
.
.
.
end if;
If x_table.code can contain duplicate values, you have to decide what to do when more than one occurrence of p_param2 is found.

NO DATA FOUND oracle using cursor

I have been searching online using different solution suggestion to handle no data in this code but to no avail. how can I handle the exception if no data is found. How can I solve this problem. I am not an expert in oracle though!
DECLARE
nCheckOption INT;
no_data_found EXCEPTION;
CURSOR TYPE_cursor IS
SELECT
D_NAL_REF.TRANS
, D_NAL_REF.INJ
, D_NAL_REF.REF
FROM D_NAL_REF D_NAL_REF
WHERE D_NAL_REF.REF IN
(SELECT AG_REF.REF
FROM AG_REF A_REF
WHERE A_REF.DESCEND_REF = 10
);
BEGIN
FOR rec IN TYPE_cursor
LOOP
nCheckOption := 0;
SELECT 1
INTO nCheckOption
FROM PERSON_TYPE WHERE TRANS = rec.TRANS AND INJ = rec.INJ;
IF nCheckOption = 1 THEN
UPDATE PERSON_TYPE
SET PERSON_TYPE.TYPE = rec.REF
WHERE TRANS = rec.TRANS
AND PERSON_TYPE.INJ = rec.INJ;
END IF;
EXCEPTION
WHEN no_data_found
THEN
DBMS_OUTPUT.PUT_LINE ('Trapped the error!?');
END LOOP;
END;
/
Rewrite your code to eliminate the inner SELECT, which is the only place in your code where I can see that a NO_DATA_FOUND exception could possibly be raised:
BEGIN
FOR rec IN (SELECT d.TRANS,
d.INJ,
d.REF
FROM D_NAL_REF d
WHERE d.REF IN (SELECT a.REF
FROM AG_REF a
WHERE a.DESCEND_REF = 10) AND
(d.TRANS, d.INJ) IN (SELECT DISTINCT TRANS, INJ
FROM PERSON_TYPE))
LOOP
UPDATE PERSON_TYPE
SET TYPE = rec.REF
WHERE TRANS = rec.TRANS AND
INJ = rec.INJ;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Trapped the error!?');
END;
I think you need to find if cursor contains any record or not. If cursor is empty then it must return that error message written in exception block.
Or you want to print error message if update statement do not find any record to update.
Here is the pseudo code.
Declare
ncheckoption number := 0;
Cursor type_cursor is ....
Begin
For rec in type_cursor loop
ncheckoption := ncheckoption + 1;
Update ...
If sql%rowcount = 0 then
Dbms_output.put_line('error message, if you want here in case no record found in table to update');
-- loop will continue
-- if you want loop to break then issue exit statement here
End if;
End loop;
If ncheckoption = 0 then
Dbms_output.put_line('error message you want to print in case cursor is empty');
End if;
End;
/
Cheers!!

Oracle PL/SQL function: if parameter not in table column => continue program

Please see my code below. If the parameter p_cust_id is not in the column cust_id I want "0" to be printed out (which means not logged in). If it is in cust_id I want oracle to continue the second part of the code (the part below the empty row).
I have tried to solve this by inserting the values of column cust_id in a cursor and then inserting it in the variable v_cust_id. Perhaps this results in unnecessarily much code?
My problem is that the program does not seem to run the second part even if p_cust_id is in cust_id. It just prints out "0" even though the customer ID and the password are correct.
Before I added the cursor the program worked as it was supposed to, unless the parameter p_cust_id didn't match any value in the cust_id column. If this was the case nothing was printed out.
create or replace function log_in(
p_cust_id in customer.cust_id%type,
p_passwd in customer.passwd%type)
return varchar2
as
cursor c_cust_id is select cust_id from customer;
v_cust_id customer.cust_id%type;
v_passwd customer.passwd%type;
v_logged_in number(1);
v_not_logged_in number(1);
begin
v_logged_in := 1;
v_not_logged_in := 0;
if not c_cust_id%isopen then
open c_cust_id;
end if;
loop
fetch c_cust_id
into v_cust_id;
exit when c_cust_id%notfound;
end loop;
if p_cust_id not in(v_cust_id) then
return v_not_logged_in;
end if;
close c_cust_id;
select passwd
into v_passwd
from customer
where cust_id = p_cust_id;
if v_passwd = p_passwd then
return v_logged_in;
else
return v_not_logged_in;
end if;
end;
I could see, you don't need a cursor at all, to check if the cust_id is in the table. Just search for the cust_id in the table, and attempt to fetch the password. If it exists, you get the value, and NO_DATA_FOUND exception otherwise which means not logged in.
BEGIN
select passwd
into v_passwd
from customer
where cust_id = p_cust_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
return v_not_logged_in;
END;
Full code will be:
create or replace function log_in(
p_cust_id in customer.cust_id%type,
p_passwd in customer.passwd%type)
return varchar2
as
v_cust_id customer.cust_id%type;
v_passwd customer.passwd%type;
v_logged_in number(1);
v_not_logged_in number(1);
begin
v_logged_in := 1;
v_not_logged_in := 0;
BEGIN
select passwd
into v_passwd
from customer
where cust_id = p_cust_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
return v_not_logged_in;
END;
if v_passwd = p_passwd then
return v_logged_in;
else
return v_not_logged_in;
end if;
end;

How to find number of rows in cursor

I would like to find the number of rows in a cursor. Is there a keyword that can help? Using COUNT, we have to write a query. Any help will be greatly appreciated.
The cursor_variable.%ROWCOUNT is the solution. But its value will be 0 if you check it after opening. You need to loop through all the records, to get the total row count. Example below:
DECLARE
cur sys_refcursor;
cur_rec YOUR_TABLE%rowtype;
BEGIN
OPEN cur FOR
SELECT * FROM YOUR_TABLE;
dbms_output.put_line(cur%rowcount);--returning 0
LOOP
FETCH cur INTO cur_rec;
EXIT WHEN cur%notfound;
dbms_output.put_line(cur%rowcount);--will return row number beginning with 1
dbms_output.put_line(cur_rec.SOME_COLUMN);
END LOOP;
dbms_output.put_line('Total Rows: ' || cur%rowcount);--here you will get total row count
END;
/
You must open the cursor and then fetch and count every row. Nothing else will work.
You can also use BULK COLLECT so that a LOOP is not needed,
DECLARE
CURSOR c
IS SELECT *
FROM employee;
TYPE emp_tab IS TABLE OF c%ROWTYPE INDEX BY BINARY_INTEGER;
v_emp_tab emp_tab;
BEGIN
OPEN c;
FETCH c BULK COLLECT INTO v_emp_tab;
DBMS_OUTPUT.PUT_LINE(v_emp_tab.COUNT);
CLOSE c;
END;
/
Edit: changed employee%ROWTYPE to c%ROWTYPE
You can use following simple single line code to print cursor count
dbms_output.put_line(TO_CHAR(cur%rowcount));
This should work for you
DECLARE
CURSOR get_data_ IS
SELECT *
FROM table_abc_
WHERE owner = user_; -- your query
counter_ NUMBER:= 0;
BEGIN
FOR data_ IN get_data_ LOOP
counter_ := counter_ + 1;
END LOOP;
dbms_output.put_line (counter_);
END;
DECLARE #STRVALUE NVARCHAR(MAX),
#CREATEDDATE DATETIME,
#STANTANCEVALUE NVARCHAR(MAX),
#COUNT INT=0,
#JOBCODE NVARCHAR(50)='JOB00123654',
#DATE DATETIME=GETDATE(),
#NAME NVARCHAR(50)='Ramkumar',
#JOBID INT;
CREATE TABLE #TempContentSplitValue (ITEMS NVARCHAR(200))
SELECT #JOBID = i.Id FROM JobHeader_TBL i WHERE Id=1201;
IF EXISTS (SELECT 1 FROM JobHeader_TBL WHERE Id=#JOBID)
BEGIN
SELECT #STRVALUE= Description from ContentTemplate_TBL where Id=1
INSERT INTO #TempContentSplitValue SELECT * FROM dbo.split(#STRVALUE, '_')
SET #STRVALUE=''
DECLARE db_contentcursor CURSOR FOR SELECT ITEMS FROM #TempContentSplitValue
OPEN db_contentcursor
FETCH NEXT FROM db_contentcursor
INTO #STANTANCEVALUE
WHILE (##FETCH_STATUS = 0)
BEGIN
SET #STRVALUE += #STANTANCEVALUE + 'JOB00123654'
SET #COUNT += 1
SELECT #COUNT
FETCH NEXT FROM db_contentcursor INTO #STANTANCEVALUE
END
CLOSE db_contentcursor
DEALLOCATE db_contentcursor
DROP TABLE #TempContentSplitValue
SELECT #STRVALUE
END
Here I am trying to count the total number of customers with age greater than 25. So store the result in the cursor first. Then count the size of the cursor inside the function or in the main begin itself.
DECLARE
cname customer24.cust_name%type;
count1 integer :=0;
CURSOR MORETHAN is
SELECT cust_name
FROM customer24
where age>25;
BEGIN
OPEN MORETHAN;
LOOP
FETCH MORETHAN into cname;
count1:=count1+1;
EXIT WHEN MORETHAN%notfound;
END LOOP;
-- dbms_output.put_line(count1);
dbms_output.put_line(MORETHAN%ROWCOUNT);
CLOSE MORETHAN;
END;
There is a possible work around that may be useful/needed because of the overhead of accessing a database server over a network (e.g., when using Ajax calls)
Consider this:
CURSOR c_data IS
SELECT per_first_name , null my_person_count
FROM person
UNION
SELECT null as per_first_name , count( distinct per_id ) as my_person_count
FROM person
order by my_person_count ;
The first row fetched has the count of records. One MUST add specific columns fetched (the use of the * does not work), and one can add additional filters.
Try this:
print(len(list(cursor)))
I always read that people loop through results. Why not using a count(*)?
An example from my production code:
PROCEDURE DeleteStuff___(paras_ IN Parameters_Type_Rec)
IS
CURSOR findEntries_ IS
select * from MyTable
where order_no = paras_.order_no;
counter_ NUMBER;
CURSOR findEntries_count_ IS
SELECT COUNT(*) from MyTable
where order_no = paras_.order_no;
BEGIN
OPEN findEntries_count_;
FETCH findEntries_count_ INTO counter_;
CLOSE findEntries_count_;
dbms_output.put_line('total records found: '||counter_);
IF (counter_ = 0) THEN
-- log and leave procedure
RETURN;
END IF;
FOR order_rec_ IN findEntries_ LOOP
EXIT WHEN findEntries_%NOTFOUND OR findEntries_%NOTFOUND IS NULL;
-- do stuff - i.e. delete a record.
API_Package.Delete(order_rec_);
END LOOP;
END DeleteStuff___;
If the query is small, that is my prefered way.
In this example, I just want to know (and log) how many entries I'll delete.
p.s. Ignore the three underlines. In IFS, this is used when you want private procedures or functions.
You can’t have cursor count at start. For that you need to fetch complete cursor; that is the way get cursor count.
declare
cursor c2 is select * from dept;
var c2%rowtype;
i number :=0;
begin
open c2;
loop
fetch c2 into var;
exit when c2%NOTFOUND;
i: = i+1;
end loop;
close c2;
dbms_output.put_line('total records in cursor'||i);
end;
You can use %ROWCOUNT attribute of a cursor.
e.g:
DECLARE
CURSOR lcCursor IS
SELECT *
FROM DUAL;
BEGIN
OPEN lcCursor ;
DBMS_OUTPUT.PUT_LINE(lcCursor%ROWCOUNT);
CLOSE lcCursor ;
END;

Resources