01403. 00000 - "no data found" - sql

I'm updating my docmeta table but i get the
ORA-01403: no data found
ORA-06512: at line 25
01403. 00000 - "no data found" error
Below is the query. How can i get rid of this error?
DECLARE
varPayTerm varchar2(300);
BEGIN
FOR X IN(
SELECT
d.did, d.xproject_id
FROM
revisions r,
(SELECT DDOCNAME, MAX(DID) mDID
FROM
REVISIONS REV
WHERE
dcreatedate >='01-Jan-14'
GROUP BY
DDOCNAME
) RevLatestID,
docmeta d
--temp_project p
WHERE
RevLatestID.mdid = r.did
and d.did = r.did
)
loop
select paymentterm
into varPayTerm
from project where pid = X.xproject_id and paymentterm is not null;
update docmeta
set xpaymentterm= varPayTerm
where did=X.dID
and xproject_id = X.xproject_id;
END LOOP;
END ;

The SELECT...INTO statements is returning no rows
If it is valid for no rows to be returned, and you want to continue you can catch and ignore the NO_DATA_FOUND exception like this:
...
BEGIN
SELECT ... INTO...;
EXCEPTION
WHEN NO_DATA_FOUND THEN
paymentterm := 0;
-- or ant msg you want
then return 'no data here';
END;
...

Related

Bulk Collect with Sum function

I am trying to use Bulk all and Forall in Oracle database:
Original code from Procedure is as below:
IF NVL(v_mc,0) != 0 THEN
FOR rec IN
(SELECT a.testid,
SUM(pct * NVL(cap,0))/v_mc lead1
BULK COLLECT INTO testids1, testids2
FROM testtable a
WHERE a.id = n_id
AND a.type =n_type
GROUP BY a.testid;
)
LOOP
UPDATE testtable
SET LEAD1 =ROUND(testids2(i),2)
WHERE tid = n_id
AND type = n_type
AND testid =testids1(i);
END LOOP;
END IF;
So In select statement , I am using Sum function and also using aliasing here .
Code , I have written which use Bulk collect and Forall is as follows:
PROCEDURE test
IS
TYPE test1Tab IS TABLE OF sh_rpt_temp_peer_wip.test1%TYPE;
TYPE test2Tab IS TABLE OF testtable.lead1%TYPE;
testids1 testidTab; --Error 1 and Error 2
testids2 LeadTab;
BEGIN
IF NVL(v_mc,0) != 0 THEN
SELECT testid,
SUM(pct * NVL(cap,0))/v_mc lead1
BULK COLLECT INTO testids1, testids2
FROM testtable a --Error 3
WHERE a.id = n_id
AND a.type =n_type
GROUP BY a.testid ORDER BY a.testid;
FORALL i IN testids1.FIRST..testids1.LAST
UPDATE testtable
SET LEAD1 =ROUND(testids2(i),2)
WHERE tid = n_id --Error 3
AND type = n_type
AND testid =testids1(i);
END IF;
END;
But while I am compiling procedure , I am getting multiple errors. I am very new to PL/SQL. Please let me know if I can retrieve calculated value as a Column in Bulk Collect?
I am getting below errors in procedure:
Error 1) PL/SQL: Item ignored
Error 2) component 'LEAD' must be declared
Error 3) expression is of wrong type
Please let me know what is wrong here
Thanks
As I identified that the collection type that you are referring is not in scope in the procedure, might be you have declared globally. I modified your code get a try it once, hopefully, it works for you.
PROCEDURE test
IS
TYPE test1Tab IS TABLE OF testtable.testid%TYPE;
TYPE test2Tab IS TABLE OF number;
testids1 test1Tab; //Error 1 and Error 2
testids2 test2Tab;
BEGIN
IF NVL(v_mc,0) != 0 THEN
SELECT testid,
SUM(pct * NVL(cap,0))/v_mc lead
BULK COLLECT INTO testids1, testids2
FROM testtable a //Error 3
WHERE a.id = n_id
AND a.type =n_type
GROUP BY a.testid ORDER BY a.testid;
FORALL i IN testids1.FIRST..testids1.LAST
UPDATE testtable
SET LEAD = ROUND(testids2(i),2)
WHERE tid = n_id //Error 3
AND type = n_type
AND testid = testids1(i);
END IF;
END;

Informe de error ORA-01422: exact fetch returns more than requested number of rows

I want to enter the variables inside the table INFORME_VENTA.
Below is my code:
VARIABLE B_ANIO VARCHAR2(8);
EXECUTE :B_ANIO := '042018';
DECLARE
V_CLIENTE_ID CLIENTES.CLIENTE_ID%TYPE;
V_NOMBRE_CIA CLIENTES.NOMBRE_CIA%TYPE;
V_NRO_BOLETA BOLETAS.NRO_BOLETA%TYPE;
BEGIN
LOOP
SELECT C.CLIENTE_ID , C.NOMBRE_CIA , B.NRO_BOLETA
INTO V_CLIENTE_ID , V_NOMBRE_CIA , V_NRO_BOLETA
FROM BOLETAS B JOIN ORDENES O JOIN CLIENTES C
ON (C.CLIENTE_ID = O.ORDEN_ID)
ON (B.NRO_BOLETA = O.ORDEN_ID);
INSERT INTO INFORME_VENTA
VALUES(:B_ANIO , V_CLIENTE_ID , V_NOMBRE_CIA , V_NRO_BOLETA);
END LOOP;
END;
I want to put the variables inside the informe_venta table but I get the following error
Informe de error -
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 11
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
Why do you use PL/SQL? A simple INSERT is capable of doing the whole job:
insert into informe_venta
select :b_anio, c.cliente_id , c.nombre_cia , b.nro_boleta
from boletas b join ordenes o
on b.nro_boleta = o.orden_id
join clientes c
on c.cliente_id = o.orden_id;
(In SQL*Plus you'd reference the B_ANIO variable with ampersand, &b_anio).
If it has to be PL/SQL, enclose the above INSERT into BEGIN-END and run it. Once again: you don't need a loop.
One more remark: I'd suggest you to name columns you're inserting into, such as
insert into informe_venta (anio, cliente_id, nombre_cia, nro_boleta)
select ...
Instead of SELECT INTO statement use CURSOR against ORA-01422 error, as in the following block :
VARIABLE B_ANIO VARCHAR2(8);
EXECUTE :B_ANIO := '042018';
DECLARE
V_CLIENTE_ID CLIENTES.CLIENTE_ID%TYPE;
V_NOMBRE_CIA CLIENTES.NOMBRE_CIA%TYPE;
V_NRO_BOLETA BOLETAS.NRO_BOLETA%TYPE;
BEGIN
FOR R IN
(
SELECT C.CLIENTE_ID , C.NOMBRE_CIA , B.NRO_BOLETA
FROM BOLETAS B JOIN ORDENES O JOIN CLIENTES C
ON (C.CLIENTE_ID = O.ORDEN_ID)
ON (B.NRO_BOLETA = O.ORDEN_ID);
)
LOOP
V_CLIENTE_ID := R.CLIENTE_ID;
V_NOMBRE_CIA := R.NOMBRE_CIA;
V_NRO_BOLETA := R.NRO_BOLETA;
INSERT INTO INFORME_VENTA
VALUES(:B_ANIO , V_CLIENTE_ID , V_NOMBRE_CIA , V_NRO_BOLETA);
END LOOP;
END;

Invalid identifier in Oracle SQL

I haven't created any columns(PAYMENTTERM) in tables with double quotes but
still I'm getting following Error:
Error(26,9): PL/SQL: SQL Statement ignored
Error(27,29): PL/SQL: ORA-00904: "P"."PAYMENTTERM": invalid identifier
Please point out what wrong am i doing and what needs to be corrected:
CREATE OR REPLACE
PROCEDURE PAYTERMUPDATE
IS
RecordCount INT;
BEGIN
SELECT
count(1) INTO RecordCount
FROM
docmeta d
INNER JOIN temp_pay_term p ON d.XPROJECT_ID = p.PID
WHERE
lower(d.PAYMENTTERM) <> lower(p.PAYMENTTERM);
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('There were '
|| to_char(RecordCount)
|| ' records where payment term is mismatch.');
DBMS_OUTPUT.PUT_LINE('');
FOR X IN (
SELECT p.PID, p.PAYMENTTERM
FROM docmeta d, temp_pay_term p
WHERE d.XPROJECT_ID = p.PID AND d.PAYMENTTERM <> p.PAYMENTTERM)
LOOP
UPDATE docmeta
SET d.PAYMENTTERM = p.PAYMENTTERM
WHERE XPROJECT_ID = X.PID;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-1000,
'Error occured, No payment term were updated');
END PAYTERMUPDATE;
In this line:
UPDATE docmeta
SET d.PAYMENTTERM = p.PAYMENTTERM
WHERE XPROJECT_ID = X.PID ;
You must add an alias on docmeta (d) and the p.PAYMENTTERM alias must be X
So, change in this way your query:
UPDATE docmeta d
SET d.PAYMENTTERM = X.PAYMENTTERM
WHERE XPROJECT_ID = X.PID ;
Use loop variable as alias to PAYMENTTERM that is X in you case, also declare alias for DOCMETA as d.
Try this?
LOOP
UPDATE docmeta d
SET d.PAYMENTTERM = p.PAYMENTTERM
WHERE XPROJECT_ID = X.PID ;
END LOOP;

IF EXISTS condition not working with PLSQL

I am trying to print the TEXT when condition is TRUE. The select code is perfectly working fine. It's showing 403 value when i only run select code. But I have to print some text when condition exists. What's the problem with following code.
BEGIN
IF EXISTS(
SELECT CE.S_REGNO FROM
COURSEOFFERING CO
JOIN CO_ENROLMENT CE
ON CE.CO_ID = CO.CO_ID
WHERE CE.S_REGNO=403 AND CE.COE_COMPLETIONSTATUS = 'C' AND CO.C_ID = 803
)
THEN
DBMS_OUTPUT.put_line('YES YOU CAN');
END;
Here is the error report:
Error report:
ORA-06550: line 5, column 1:
PLS-00103: Encountered the symbol "JOIN" when expecting one of the following:
) , with group having intersect minus start union where
connect
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
IF EXISTS() is semantically incorrect. EXISTS condition can be used only inside a SQL statement. So you might rewrite your pl/sql block as follows:
declare
l_exst number(1);
begin
select case
when exists(select ce.s_regno
from courseoffering co
join co_enrolment ce
on ce.co_id = co.co_id
where ce.s_regno=403
and ce.coe_completionstatus = 'C'
and ce.c_id = 803
and rownum = 1
)
then 1
else 0
end into l_exst
from dual;
if l_exst = 1
then
DBMS_OUTPUT.put_line('YES YOU CAN');
else
DBMS_OUTPUT.put_line('YOU CANNOT');
end if;
end;
Or you can simply use count function do determine the number of rows returned by the query, and rownum=1 predicate - you only need to know if a record exists:
declare
l_exst number;
begin
select count(*)
into l_exst
from courseoffering co
join co_enrolment ce
on ce.co_id = co.co_id
where ce.s_regno=403
and ce.coe_completionstatus = 'C'
and ce.c_id = 803
and rownum = 1;
if l_exst = 0
then
DBMS_OUTPUT.put_line('YOU CANNOT');
else
DBMS_OUTPUT.put_line('YES YOU CAN');
end if;
end;
Unfortunately PL/SQL doesn't have IF EXISTS operator like SQL Server. But you can do something like this:
begin
for x in ( select count(*) cnt
from dual
where exists (
select 1 from courseoffering co
join co_enrolment ce on ce.co_id = co.co_id
where ce.s_regno = 403
and ce.coe_completionstatus = 'C'
and co.c_id = 803 ) )
loop
if ( x.cnt = 1 )
then
dbms_output.put_line('exists');
else
dbms_output.put_line('does not exist');
end if;
end loop;
end;
/

Getting an error in sql, when executing code below.How to declare a table type in plsql. Am a beginner . Please suggest

create or replace procedure BAS_NUM_UPD is
cursor cur is
select distinct o.oi_b,mpr.pa_ke_i,ltrim(substr(convert_171_to_711(cp.p_t_num),1,7),'0') bs_nbr
from t_obj o, mat_pa_rel mp, cor_pa cp
where o.ob_t = 'something'
and o.oi_b = mp.oi_b
and mp.pa_ke_i = cp.pa_ke_i;
l_ba_num_at_i number(10) := get_attribute_id('Ba timber');
flag1 VARCHAR2(10);
type t1 is table of varchar2(10);
par_k t1;
BEGIN
for x in cur loop
BEGIN
select pa_ke_i into par_k from mat_pa_rel where oi_b=x.oi_b ;
if par_k.count=null then
insert into cs_val (oi_b, at_i, value, flag, ) values (x.oi_b, l_ba_num_at_i, null, 1);
end if;
select flag into flag1 from cs_val where at_i = l_ba_num_at_i and oi_b = x.oi_b
and value = x.bs_nbr;
EXCEPTION
when NO_DATA_FOUND THEN
insert into cs_val (oi_b, at_i, value, flag, )
values (x.oi_b, l_ba_num_at_i, x.bs_nbr, 1);
flag1 :='Nothing';
when OTHERS
then
raise_application_error(-20011,'Unknown Exception in PROCEDURE');
END;
end loop;
end BAS_NUM_UPD;
error:
PLS-00642: local collection types not allowed in SQL statements
You should get it running if you do a bulk collect
select pa_ke_i bulk collect into par_k from mat_pa_rel where oi_b=x.oi_b ;
Then I think the if is not right. I think you need to do
if par_k.count = 0 then
But to be honest you might just make a count
select count(*) into l_cnt from mat_pa_rel where oi_b=x.oi_b;
If l_cnt = 0 then ...
Of course l_cnt has to be defined.
You should create type t1 in the schema and not in the pl/sql block.