Forms on procedure in apex - plsql

I want to create form on procedure in APEX
this is my code
create or replace procedure "RESERVER2"
(numo_place in number,CATGE IN varchar,NOM_EQUIP1 IN VARCHAR2,NOM_EQUIP2 IN VARCHAR)
is
V_MAX CLIENT1.MAXIMUM%TYPE;
V_MIN CLIENT1.MINIMUM%TYPE;
V_CATG CLIENT1.CATG%TYPE;
V_NOM_EQUIPE1 CLIENT.NOM_EQUIPE1%TYPE;
V_NOM_EQUIPE2 CLIENT.NOM_EQUIPE2%TYPE;
V_num reservation.num_place%type;
CURSOR C1 IS
select CATG,NOM_EQUIPE1,NOM_EQUIPE2 from client1;
begin
open C1;
LOOP
FETCH C1 into V_CATG,V_NOM_EQUIPE1,V_NOM_EQUIPE2;
EXIT WHEN C1%notfound;
select CATG into V_CATG from CLIENT1;
if CATGE=V_CATG THEN
INSERT INTO RESERVATION(CATEG)values(CATGE);
select NOM_EQUIPE1 into V_NOM_EQUIPE1 from CLIENT1;
if NOM_EQUIP1=V_NOM_EQUIPE1 THEN
INSERT INTO RESERVATION(NOM_MATCH)values(NOM_EQUIP1);
if CATGE='A'AND numo_place<20 then
select NOM_EQUIPE2 into V_NOM_EQUIPE2 from CLIENT1;
if NOM_EQUIP2=V_NOM_EQUIPE2 THEN
INSERT INTO RESERVATION(NOM_MATCH2)values(NOM_EQUIP2);
if CATGE='A'AND numo_place<20 then
INSERT INTO RESERVATION(NUM_PLACE) values(numo_place);
else
DBMS_OUTPUT.PUT_LINE('ERREUR');
end if;
end if;
end if;
end if;
end if;
end loop;
close C1;
end;
When I run my form and I start fill the text field after I click in submit
this error appears:
ORA-01422: exact fetch returns more than requested number of rows
Any advice?

Related

returning value to cursor plsql

Hi I have a procedure which return a recordset using cursor in output what am trying to do is i use cursor to get the data and same have to return it to output cursor .I can do like below
PROCEDURE test(value_one IN someTabel.somecolumn%TYPE,
valu_two IN someTabel.somecolumn%TYPE,
Outputcursor OUT SYS_REFCURSOR) IS
mydeclaration goes here
output_value_one sometable.somecolumn%Type;
---
cursor test_select is
select statement
begin
for val in test_select loop
fetch test_select into output_value_one; -- I want my cursor outputcursor to be return instead of output_value_one
end loop;
end;
You send the deptno the cursor return the query where you can handle from frontend.
create or replace Procedure Transproc(p_deptno IN emp.deptno%TYPE,
Outputcursor Out Sys_Refcursor,
p_recordset Out Varchar)
Is
Vquery varchar2(200);
Begin
Vquery:='select * from emp where deptno='|| p_deptno ||'';
Open Outputcursor For Vquery;
OMessage:='Success';
Exception
When others then
OMessage:='Fail';
End;
OR try below one as per your requriement.
CREATE OR REPLACE PROCEDURE get_emp_rs (p_deptno IN emp.deptno%TYPE,
p_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN p_recordset FOR
SELECT ename,
empno,
deptno
FROM emp
WHERE deptno = p_deptno
ORDER BY ename;
END GetEmpRS;
/
To test :-
SET SERVEROUTPUT ON SIZE 1000000
DECLARE
l_cursor SYS_REFCURSOR;
l_ename emp.ename%TYPE;
l_empno emp.empno%TYPE;
l_deptno emp.deptno%TYPE;
BEGIN
get_emp_rs (p_deptno => 30,
p_recordset => l_cursor);
LOOP
FETCH l_cursor
INTO l_ename, l_empno, l_deptno;
EXIT WHEN l_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(l_ename || ' | ' || l_empno || ' | ' || l_deptno);
END LOOP;
CLOSE l_cursor;
End;
/

Raise Exception when record not found

I have a table that includes customer ID and order ID and some other data.
I want to create a procedure that takes customer ID as input and look inside the table.
if that customer exists then print the order details for that customer and
if customer does not exist then raise an exception "Customer not found."
I have this code, but it's not working properly, or maybe I have the wrong approach to this question.
CREATE OR REPLACE PROCEDURE order_details(customer NUMBER)
IS
CURSOR order_cursor IS
SELECT ORDER_ID, ORDER_DATE, TOTAL, CUSTOMER_ID
FROM PRODUCT_ORDER
WHERE CUSTOMER_ID = customer ;
order_row order_cursor%ROWTYPE ;
customer_error EXCEPTION ;
BEGIN
FOR order_row IN order_cursor
LOOP
IF order_cursor%FOUND THEN
dbms_output.put_line ('order id = ' || order_row.ORDER_ID) ;
ELSE
RAISE customer_error ;
END IF;
END LOOP;
EXCEPTION
WHEN customer_error THEN
dbms_output.put_line ('no customer' ) ;
END;
So if I run the procedure with this line
BEGIN
order_details(103);
END;
I get two results because order exists for this customer.
and if I run the procedure with this line
BEGIN
order_details(101);
END;
I don't get anything (not even the error ) because there is no order for that customer.
Table Data
You must use an "Explicit Cursor" instead of "Cursor FOR LOOP". Because the latter just enter the code between LOOP and END LOOP when the query returns more than one record.
CREATE OR REPLACE PROCEDURE order_details(customer NUMBER)
IS
CURSOR order_cursor IS
SELECT ORDER_ID, ORDER_DATE, TOTAL, CUSTOMER_ID
FROM PRODUCT_ORDER
WHERE CUSTOMER_ID = customer ;
order_row order_cursor%ROWTYPE ;
customer_error EXCEPTION ;
BEGIN
OPEN order_cursor;
LOOP
FETCH order_cursor INTO order_row;
EXIT WHEN order_cursor%NOTFOUND;
dbms_output.put_line ('order id = ' || order_row.ORDER_ID);
END LOOP;
IF order_cursor%rowcount = 0 THEN
RAISE customer_error;
END IF;
CLOSE order_cursor;
EXCEPTION
WHEN customer_error THEN
dbms_output.put_line ('no customer' ) ;
END;
Regards

PL/SQL Cursor just check if value is greater than a value

I want
to make a procedure check if exist empno from table employees
with emno greater than 100. If exist at least one, i want
to exit from the loop.
How can I modify the following code ?
Is it problem I don;t use %NOTFOUND , %ROWCOUNT ?
CREATE OR REPLACE procedure check_value
IS
cursor c1 is
select *
from employess;
c1_values c1%ROWTYPE;
BEGIN
open c1;
fetch c1 into c1_values;
loop
if c1_values.EMPNO > 100 then
DBMS_OUTPUT.put_line ('Found row with empno > 100');
end if;
end loop;
close c1;
END;
If you just need to check if you have a record which has empno over 100 you can use EXISTS statement e.g.
DECLARE
CURSOR c1 IS
SELECT
CASE
WHEN EXISTS (
SELECT
1
FROM
employees
WHERE
empno > 100
) THEN 1
ELSE 0
END AS empno_exists
FROM
dual;
ln_empno_exists PLS_INTEGER;
BEGIN
OPEN c1;
FETCH c1 INTO ln_empno_exists;
CLOSE c1;
DBMS_OUTPUT.PUT_LINE('Empno over 100 exists: '||CASE WHEN ln_empno_exists = 1 THEN 'TRUE' ELSE 'FALSE' END);
END;
/
EDIT: If you want to fetch the rows with some conditions, you simply need to adjust your WHERE clause in your SELECT statement. Here you have an example with some ways to iterate through the records fetched:
DECLARE
CURSOR c1 IS
SELECT
emp.*
FROM
employees emp
WHERE
empno > 100
;
lr_c1_rec c1%ROWTYPE;
BEGIN
-- Using FOR loop
DBMS_OUTPUT.PUT_LINE('START: Printing employees records where empno > 100');
FOR rec IN c1
LOOP
DBMS_OUTPUT.PUT_LINE('empno = '||rec.empno);
END LOOP;
DBMS_OUTPUT.PUT_LINE('END: Printing employees records where empno > 100');
-- Using a LOOP with EXIT clause
DBMS_OUTPUT.PUT_LINE('START: Printing employees records where empno > 100');
OPEN c1;
LOOP
FETCH c1 INTO lr_c1_rec;
-- exit the loop when your cursor doesn't have any more records to be returned
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('empno = '||lr_c1_rec.empno);
END LOOP;
DBMS_OUTPUT.PUT_LINE('END: Printing employees records where empno > 100');
-- Using WHILE loop
DBMS_OUTPUT.PUT_LINE('START: Printing employees records where empno > 100');
OPEN c1;
FETCH c1 INTO lr_c1_rec;
-- As long as cursor returns any values, iterate through the records returned
WHILE c1%FOUND
LOOP
DBMS_OUTPUT.PUT_LINE('empno = '||lr_c1_rec.empno);
END LOOP;
DBMS_OUTPUT.PUT_LINE('END: Printing employees records where empno > 100');
END;
/
Just add an EXIT statement after you've found your value:
CREATE OR REPLACE procedure check_value IS
cursor c1 is
select *
from employess;
c1_values c1%ROWTYPE;
BEGIN
open c1;
loop
fetch c1 into c1_values;
IF c1%NOTFOUND THEN EXIT;
if c1_values.EMPNO > 100 then
DBMS_OUTPUT.put_line ('Found row with empno > 100');
EXIT;
end if;
end loop;
-- The EXIT statement will drop you out of the loop and leave you here
close c1;
END;
Note that I moved the fetch inside the loop and added a %NOTFOUND check. Without the %NOTFOUND the code would never know the cursor was out of data and would probably go into an infinite loop.
Why to define cursor and then open and fetch when it can be done by just
SQL But if it is required so then use FOR loop and EXIT condition
as mentioned
below. Hope it helps
CREATE OR REPLACE PROCEDURE check_value
IS
BEGIN
FOR I IN
(SELECT * FROM employess
)
LOOP
IF I.EMPNO > 5 THEN
DBMS_OUTPUT.put_line ('Found row with empno > 100');
EXIT;
END IF;
END LOOP;
END;

How to insert nextval to trigger inside for loop

Here is a code for trigger and it have a for loop. When trigger is fired (INSERT OR UPDATE) there's another table data must include it is MICL_SUP
OPEN projMgrsCursor;
LOOP
FETCH projMgrsCursor INTO projMgr;
select micl_sup_id_seq.nextval into SUPID from dual;
insert into MICL_SUP VALUES ((SUPID), (SELECT SYSDATE FROM DUAL), :NEW.ENTRYADDEDBY_EMP_NO, 3000, 0,projMgr, NULL,:NEW.EMP_NO);
END LOOP;
CLOSE projMgrsCursor;
This is the table structure. Sup_ID primary and unique key . I can't make any changes to table structure
SUP_ID -primary key
ASSIGNED_DATE
ASSIGNED_BY_EMP_NO
AMOUNT_LIMIT
IS_OVVERRIDDEN
SUP_EMP_NO
RTD_EMP
EMP_NO
To enter sup_ID I use select micl_sup_id_seq.nextval into SUPID from dual;
but when I run this code there's an error "RA-00001: unique constraint violated" (this is not a compilation error ) Is there any other way to add sup_ID? Where have I gone wrong?
This question is related with this trigger PlSQL trigger error ORA-0000 ORA-06512:
Why not including calculation of micl_sup_id_seq.nextval into your cursor?
cursor projMgrsCursor is
select b.BU_MEMBER_ID, micl_sup_id_seq.nextval SUPID
from ...
Try rewriting your code as:
DECLARE
nSupid NUMBER;
projMgr VARCHAR2(32767);
BEGIN
OPEN projMgrsCursor;
LOOP
FETCH projMgrsCursor INTO projMgr;
EXIT WHEN projMgrsCursor%NOTFOUND;
select micl_sup_id_seq.nextval into nSUPID from dual;
insert into MICL_SUP
(SUPID, ASSIGNED_DATE, ASSIGNED_BY_EMP_NO, AMOUNT_LIMIT,
IS_OVERRIDDEN, SUP_EMP_NO, RTD_EMP, EMP_NO)
VALUES
(nSupid, SYSDATE, :NEW.ENTRYADDEDBY_EMP_NO, 3000,
0, projMgr, NULL, :NEW.EMP_NO);
END LOOP;
CLOSE projMgrsCursor;
DBMS_OUTPUT.PUT_LINE('Successful completion');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Exception: ' || SQLCODE || ' ' || SQLERRM);
RAISE;
END;
Share and enjoy.

TOAD displaying cursor recordset returned by stored procedure

How I could print recorset result from the returning cursor, please.
Down below executes fine but I need to see result.
This is block in TOAD, calling package sp AMD_NEEDMSG:
DECLARE
RETURN_RECORDSET CTI_MATRIX.AMD.REF_CURSOR;
BEGIN
CTI_MATRIX.AMD.AMD_NEEDMSG ( '88888888885', RETURN_RECORDSET );
END;
This package spec:
CREATE OR REPLACE PACKAGE CTI_MATRIX.AMD AS
TYPE REF_CURSOR IS REF CURSOR;
PROCEDURE AMD_NEEDMSG (v_CRN IN VARCHAR2, return_recordset OUT REF_CURSOR);
END AMD;
This is package body:
CREATE OR REPLACE PACKAGE BODY CTI_MATRIX.AMD AS
PROCEDURE AMD_NEEDMSG (v_CRN IN VARCHAR2, return_recordset OUT REF_CURSOR) IS
return_flag INTEGER;
row_cnt INTEGER;
number_of_days INTEGER;
var_DATE DATE;
CURSOR ACCNTSEARCH (P_CRN IN VARCHAR2) IS
SELECT DISTINCT COUNT(*) , AMD.MSG_DATE
FROM TBL_AMD_NEEDMSG AMD
WHERE AMD.PHONE_NUMBER = P_CRN AND ROWNUM = 1;
BEGIN
OPEN ACCNTSEARCH(v_CRN);
FETCH ACCNTSEARCH INTO row_cnt, var_DATE;
CLOSE ACCNTSEARCH;
IF (row_cnt = 0)
THEN
INSERT INTO TBL_AMD_NEEDMSG (PHONE_NUMBER, MSG_DATE) VALUES (v_CRN , SYSDATE);
return_flag := 1;
ELSE
SELECT SYSDATE-var_DATE INTO number_of_days FROM dual;
IF (number_of_days>7)
THEN
UPDATE TBL_AMD_NEEDMSG SET MSG_DATE = SYSDATE WHERE PHONE_NUMBER = v_CRN;
return_flag := 1;
ELSE
return_flag := 0;
END IF;
END IF;
COMMIT;
OPEN return_recordset FOR
SELECT return_flag AS ReturnFLag FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END AMD_NEEDMSG;
END AMD;
/
Bottom line is to return to client a value of return_flag in the form of record set.
To return the return_flag, which is int=1 or 0 you need function that returns a single value, not recordset. Below are general recordset examples - hope this helps:
DECLARE
TYPE empcurtyp IS REF CURSOR;
emp_cv empcurtyp;
--
TYPE namelist IS TABLE OF scott.emp.ename%TYPE;
TYPE sallist IS TABLE OF scott.emp.sal%TYPE;
names namelist;
sals sallist;
BEGIN
OPEN emp_cv FOR
SELECT ename, sal FROM scott.emp
WHERE job = 'MANAGER' ORDER BY sal DESC;
--
FETCH emp_cv BULK COLLECT INTO names, sals;
CLOSE emp_cv;
-- loop through the names and sals collections
FOR i IN names.FIRST .. names.LAST LOOP
DBMS_OUTPUT.PUT_LINE
('Name = ' || names(i) || ', salary = ' || sals(i));
END LOOP;
END;
/
-- SYS_REFCURSOR example --
DECLARE
p_rc_type SYS_REFCURSOR;
emp_rec scott.emp%ROWTYPE;
--
PROCEDURE p_Emp_Info (p_cur_var OUT SYS_REFCURSOR)
IS
BEGIN
OPEN p_cur_var FOR
SELECT ename, job FROM scott.emp WHERE job = 'MANAGER';
LOOP
FETCH p_cur_var INTO emp_rec.ename, emp_rec.job;
EXIT WHEN p_cur_var%NOTFOUND;
dbms_output.put_line(emp_rec.ename ||' '|| emp_rec.job);
END LOOP;
CLOSE p_cur_var;
END p_Emp_Info;
--
BEGIN
p_Emp_Info(p_rc_type);
END;
/

Resources