Alert message from PLSQL in Oracle apex - oracle-apex-5.1

I want to display an alert message from PLSQL if a certain condition is met. However it's not working.
Please check my PLSQL code which I wrote in dynamic action when clicking a checkbox.
declare
var_hire DATE ;
tenure_dt DATE;
i number;
TENURE EXCEPTION;
BEGIN
SELECT HIREDATE INTO var_hire from employee where empno=107;
-- APEX_APPLICATION.G_F01(1);
SELECT var_hire+ INTERVAL '1' YEAR INTO tenure_dt FROM DUAL;
IF SYSDATE < to_Date(tenure_dt,'DD-MON-YY') THEN
/* APEX_ERROR.ADD_ERROR (
p_message => 'The employee cannot be deleted',
p_display_location => apex_error.c_inline_in_notification );*/
apex_application.g_global_notification( 'The employee cannot be deleted');
END IF ;
END ;
declare
var_hire DATE ;
tenure_dt DATE;
i number;
TENURE EXCEPTION;
BEGIN
SELECT HIREDATE INTO var_hire from employee where empno=107;
-- APEX_APPLICATION.G_F01(1);
SELECT var_hire+ INTERVAL '1' YEAR INTO tenure_dt FROM DUAL;
APEX_ERROR.ADD_ERROR (
p_message => 'The employee cannot be deleted',
p_display_location => apex_error.c_inline_in_notification );
EXCEPTION
WHEN TENURE THEN
RAISE_APPLICATION_ERROR(-20000,'CANNOT BE DELETED');
END ;

You can create a Ajax callback process with your PL/SQL CODE. For example create the Ajax callback process as MyQuery
declare
var_hire DATE ;
tenure_dt DATE;
i number;
TENURE EXCEPTION;
BEGIN
SELECT HIREDATE INTO var_hire from employee where empno=107;
SELECT var_hire+ INTERVAL '1' YEAR INTO tenure_dt FROM DUAL;
IF SYSDATE < to_Date(tenure_dt,'DD-MON-YY') THEN
HTP.P('The employee cannot be deleted');
END IF ;
END ;
And then create a Dynamic Action ('Execute javascript Code) on your check box with below javascript code
apex.server.process('MyQuery', { },
{
dataType: "text",
success: function(pData) {
if (pData != "") {
apex.message.alert(pData);
}
}
});

Related

How to print an output message in SQL oracle if a condition within a function is not met

How can I add an output message to a function if a reimbursement request is not approved?
This is the code of my function:
create or replace FUNCTION reimbursement_check(CREATIONDATE DATE)
RETURN DATE
IS
M_DATE DATE ;
BEGIN
SELECT UpdateDate
INTO M_DATE
FROM REIMBURSEMENTREQUEST
WHERE ReimbursementStatus = 'APPR'
AND UpdateDate = CREATIONDATE;
M_DATE := CREATIONDATE + 7;
RETURN M_DATE;
END;
Did you try something like:
CREATE OR REPLACE FUNCTION reimbursement_check(p_creation_date DATE)
RETURN DATE
IS
l_date DATE;
l_status REIMBURSEMENTREQUEST.ReimbursementStatus%TYPE;
BEGIN
BEGIN
SELECT UpdateDate, ReimbursementStatus
INTO l_date, l_status
FROM REIMBURSEMENTREQUEST
WHERE UpdateDate = p_creation_date;
EXCEPTION WHEN no_data_found THEN
NULL; --or however it should be handled
END;
IF l_status = 'NOTA' THEN
apex_error.add_error(
p_message => 'Not approved for receiving a reimbursement check',
p_display_location => apex_error.c_inline_in_notification);
END IF;
RETURN p_creation_date + 7;
END;
/

loop condition return value in pl/sql

I am creating a procedure in pl.sql and I want the return is true and false with the condition if the colums end_date is less then today and return false if then today then return true on each record. This is my procedure code
create or replace procedure GET_REGIS_LIMIT(V_CURSOR out SYS_REFCURSOR) is
PR_END_DATE DATE;
begin
BEGIN
FOR myDATE in(SELECT END_DATE INTO PR_END_DATE FROM REGISTER_LIMIT T WHERE T.STATUS='U')
LOOP
PR_END_DATE:=myDATE.END_DATE;
OPEN V_CURSOR FOR
SELECT T.*, (SELECT CASE WHEN PR_END_DATE > SYSDATE THEN 'TRUE' ELSE 'FALSE' END FROM DUAL END) RESULTS
FROM REGISTER_LIMIT T WHERE T.STATUS='U';
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN -- catches all 'no data found' errors
OPEN V_CURSOR FOR
SELECT 'EMPTY' RESULTS FROM DUAL ;
end;
end GET_REGIS_LIMIT;
The column i mark should return true but all of them are return false or it depends on the last row
You don't need a loop. Just open a ref cursor which returns the result set you need.
create or replace procedure get_regis_limit(v_cursor out sys_refcursor) is
begin
open v_cursor for
select t.*
, case when end_date > sysdate then 'TRUE' else 'FALSE' end as results
from register_limit t
where t.status='u';
end get_regis_limit;```

Passing data when query returns value and No "EXCEPTION WHEN NO_DATA_FOUND THEN" (Oracle 11g)

I have created a procedure for updating my t_ritm table. First I have select rrcd_qnty (which is my product quantity) of a product id from t_rrcd table. Then I update the rrcd_qnty value in t_ritm table.
Here is my procedure:
procedure update_ritm_new_rate(p_oid in varchar2, p_ritm_rate in varchar2, p_euser in varchar2)
is
nrate varchar2(4);
begin
SELECT rrcd_rate into nrate
FROM (select oid, t_rrcd.rrcd_rate
from t_rrcd
where rrcd_ritm= p_oid
ORDER BY oid DESC )
WHERE rownum <= 1
ORDER BY rownum DESC ;
EXCEPTION
WHEN NO_DATA_FOUND THEN nrate := 0;
update t_ritm
set ritm_rate = nrate, euser = p_euser, edat = sysdate
where oid = p_oid;
commit;
end update_ritm_new_rate;
Some of my product id Quantity was null. so I was getting No_Data_Found error. But when and which product id has Quantity value they were successfully updating. For avoiding No_Data_Found I used EXCEPTION WHEN NO_DATA_FOUND THEN nrate := 0; which solved my no_Data_Found error. But when product id has quantity value they were not updating.
I had search lot of for this issue but not get good solution. What should be the best practice for avoiding No_Data_Found error? Could I pass my value if I don't get any No_Data_Found error?
thank in advance
That's because - if your SELECT returns something, it never reaches UPDATE as it is hidden behind the EXCEPTION handler.
Therefore, enclose it (SELECT) into its own BEGIN-END block, and put UPDATE out of it so that it is executed with whichever NRATE value is used.
PROCEDURE update_ritm_new_rate (p_oid IN VARCHAR2,
p_ritm_rate IN VARCHAR2,
p_euser IN VARCHAR2)
IS
nrate VARCHAR2 (4);
BEGIN
BEGIN --> this
SELECT rrcd_rate
INTO nrate
FROM ( SELECT oid, t_rrcd.rrcd_rate
FROM t_rrcd
WHERE rrcd_ritm = p_oid
ORDER BY oid DESC)
WHERE ROWNUM <= 1
ORDER BY ROWNUM DESC;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
nrate := 0;
END; --> this
UPDATE t_ritm
SET ritm_rate = nrate, euser = p_euser, edat = SYSDATE
WHERE oid = p_oid;
COMMIT;
END update_ritm_new_rate;
I have fixed the issue by adding EXCEPTION WHEN NO_DATA_FOUND THEN nrate := 0; after the update query.
procedure update_ritm_new_rate(p_oid in varchar2, p_ritm_rate in varchar2, p_euser in varchar2)
is
nrate varchar2(4);
begin
SELECT rrcd_rate into nrate FROM (select oid, t_rrcd.rrcd_rate from t_rrcd where rrcd_ritm= p_oid ORDER BY oid DESC )
WHERE rownum <= 1 ORDER BY rownum DESC ;
update t_ritm set ritm_rate = nrate, euser = p_euser, edat = sysdate where oid = p_oid;
commit;
EXCEPTION WHEN NO_DATA_FOUND THEN nrate := 0;
end update_ritm_new_rate;

What considerations Do You have about my PLSQL package?

I had a little doubts about my code but yesterday I finally understood some points about to how to start coding my final package project. I share this code with the purpose if You want suggest me some change to perform or anything about my package I will appreciate you.
CREATE OR REPLACE PACKAGE BODY emp_upd_pkg IS
-- Function to update commission of employee --
FUNCTION comm_upd(
p_empid employees.employee_id%TYPE)
RETURN employees.commission_pct%TYPE
IS
v_oldcomm employees.commission_pct%TYPE;
v_newcomm employees.commission_pct%TYPE;
BEGIN
-- Valid parameter --
SELECT commission_pct
INTO v_oldcomm
FROM employees
WHERE employee_id = p_empid;
IF
v_oldcomm IS NOT NULL THEN
UPDATE employees
SET commission_pct = commission_pct * 1.1
WHERE employee_id = p_empid
RETURNING commission_pct
INTO v_newcomm;
RETURN v_newcomm;
ELSE
/*UPDATE employees
SET commission_pct = 0.1
WHERE employee_id = p_empid
RETURNING commission_pct
INTO v_newcomm;
RETURN v_newcomm;*/
RETURN (0);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN (0);
END comm_upd;
-- Function to update salary of employee --
FUNCTION sal_upd(
p_empid employees.employee_id%TYPE)
RETURN employees.salary%TYPE
IS
v_oldsal employees.salary%TYPE;
v_newsal employees.salary%TYPE;
BEGIN
-- Valid parameter --
SELECT salary
INTO v_oldsal
FROM employees
WHERE employee_id = p_empid;
IF
v_oldsal IS NOT NULL THEN
UPDATE employees
SET salary = salary + 100
WHERE employee_id = p_empid
RETURNING salary
INTO v_newsal;
RETURN v_newsal;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN (0);
END sal_upd;
-- Procedure to update comm and sal using package functions --
PROCEDURE commsal_upd(
p_empid employees.employee_id%TYPE)
IS
v_newcomm employees.commission_pct%TYPE;
v_newsal employees.salary%TYPE;
BEGIN
-- Call package functions to update sal and comm of all employees --
DBMS_OUTPUT.PUT_LINE(comm_upd(p_empid));
DBMS_OUTPUT.PUT_LINE(sal_upd(p_empid));
-- Query for final inform --
SELECT commission_pct, salary
INTO v_newcomm, v_newsal
FROM employees
WHERE employee_id = p_empid;
DBMS_OUTPUT.PUT_LINE('THE NEW COMMISSION FOR EMPLOYEE' || p_empid ||
' IS ' || v_newcomm || ' AND THE NEW SALARY IS ' || v_newsal);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('NO EXISTE EMPLEADO INGRESADO');
END commsal_upd;
END emp_upd_pkg;
Also, I have a little question: When I do use of a function within a procedure, Can I restringe the "RETURN" sentence of the function with the propuse of only send to call Procedure information?
SET SERVEROUTPUT ON
DECLARE
CURSOR cur_empid IS
SELECT employee_id
FROM employees;
TYPE empid_rec IS RECORD(
p_empid employees.employee_id%TYPE);
empid empid_rec;
BEGIN
FOR empid IN cur_empid LOOP
emp_upd_pkg.commsal_upd(empid.employee_id);
EXIT WHEN cur_empid%NOTFOUND;
END LOOP;
END;
/
When I use a simple record to update all employees I receive in console information about RETURN info of functions and info about DBMS... of procedure. Can I change my code to receive only Procedure information on console? Thanks!.
0
24100
THE NEW COMMISSION FOR EMPLOYEE100 IS AND THE NEW SALARY IS 24100
0
17100
THE NEW COMMISSION FOR EMPLOYEE101 IS AND THE NEW SALARY IS 17100
0
17100
THE NEW COMMISSION FOR EMPLOYEE102 IS AND THE NEW SALARY IS 17100
0
9100

Exact fetch returns more than requested number of rows

I'm trying to create a procedure to pass in the customer number and return the number of purchases and total value for purchases within the last year. If there are no purchases, return zero for number and total and also return the number of contacts the salesmen had with that customer in the last year.
I'm calling it as follows:
DECLARE
a_Var NUMBER;
b_Var NUMBER;
C_Var NUMBER;
D_Var NUMBER;
BEGIN
three_pr(001116,a_Var, b_Var);
IF a_Var > 0 THEN
DBMS_OUTPUT.PUT_LINE('the number of purchases :' || a_Var);
DBMS_OUTPUT.PUT_LINE('the total value of purchase :' || b_Var);
ELSE
SELECT ContactID,Count(contactID)
INTO
C_Var,D_Var
FROM DD_Contacts
WHERE DateofContact between to_date ('2012/01/01', 'yyyy/mm/dd')
AND to_date ('2012/12/31', 'yyyy/mm/dd')
Group By ContactID;
DBMS_OUTPUT.PUT_LINE (C_Var||D_Var);
END IF;
END;
/
When using the above code I get the error:
ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at line 16
and here's the procedure:
CREATE or REPLACE PROCEDURE three_pr
(par_CustomerID IN NUMBER, par_sumpurchase OUT Number,par_totalvalue OUT Number)
IS
BEGIN
SELECT
COUNT(O.OrderID),SUM(Price*Quantity)
INTO par_sumpurchase,par_totalvalue
FROM DD_Orders O JOIN DD_OrderLine OL ON O.OrderID = OL.OrderID
WHERE DatePurchase between to_date ('2012/01/01', 'yyyy/mm/dd')
AND to_date ('2012/12/31', 'yyyy/mm/dd')
AND CustomerID = par_CustomerID;
END;
/
The procedure three_pr does not correctly handle the NO_DATA_FOUND exception when the query does not return results.
CREATE or REPLACE PROCEDURE three_pr
(par_CustomerID IN NUMBER, par_sumpurchase OUT Number,par_totalvalue OUT Number)
IS
BEGIN
BEGIN
SELECT
COUNT(O.OrderID),SUM(Price*Quantity)
INTO par_sumpurchase,par_totalvalue
FROM DD_Orders O JOIN DD_OrderLine OL ON O.OrderID = OL.OrderID
WHERE DatePurchase between to_date ('2012/01/01', 'yyyy/mm/dd')
AND to_date ('2012/12/31', 'yyyy/mm/dd')
AND CustomerID = par_CustomerID;
EXCEPTION
WHEN NO_DATA_FOUND THEN
par_sumpurchase := 0;
par_totalvalue := 0;
END;
END;
/

Resources