Oracle APEX PL/SQL dynamic Action Function Body - oracle

Any help with this pl/sql and I would very much appreciate it. First off some basic info. I am using APEX 4.2 and have a Interactive report and form. I am interested in building a dynamic action on the form so that when the LEAVE_DATE is changed a PL/SQL function body (dynamic action) calculates whether the person has left within 12 month of their start date. Here are the columns in play and what I have attempted. The two calculations and be two separate dynamic actions. The first would be a calculation that results in a new date if the person left within 12 months of their BILL_READY DATE and the second returns 'Early Leaver' if within 12 months. Would be great if they could be in the same calculation though.
:P24_LEAVE_DATE (DATE)
:P24_BILL_READY (DATE)
:p24_NEW_LEAVE_DATE (DATE) CALULATED
:P24_MESSAGE (VARCHAR 255) --This would display 'Early Leaver' if within 12 months else null.
begin
case when :P24_LEAVING_DATE between :P24_BILL_READY AND (:P24_BILL_READY + 365) THEN (:P24_LEAVING_DATE - 30)
ELSE :P24_LEAVING_DATE
END CASE;
END;
Thanks for your help,

You need to create a dynamic action of type "change" on item P24_LEAVE_DATE. The action will be a set value action of type PLSQL function body. The code would be something along these lines:
declare
l_date date;
begin
if :p24_leaving_date between :p24_bill_ready and (:p24_bill_ready + 365)
then
l_date := :p24_leaving_date - 30;
else
l_date := :p24_leaving_date;
end if;
return l_date;
end;
The only thing I'm not sure off is how APEX handles date values. If they are handled as string values you need to add some string to date code in there.

Related

Oracle Forms 6i : assign a text field T ('3+11+7') to a number field N (:N := to_number(:T);) gives error ora-01722

I am using Forms 6i with oracle 11g R2. I have a text field T that have value = '3+11+7'. I want sum of text field. when i assign T to a number field N (:N := to_number(:T)). It gives ora-01722. I want total of text field that is 21 to the next field that is number field. plz suggest, how can i do this.
Thanks
This is the illustration :
Forms isn't particularly good at executing some commands; its PL/SQL engine is oldfashioned, but - it can call a stored function which runs in the database.
SQL> create or replace function f_result (par_value in varchar2)
2 return number
3 is
4 retval number;
5 begin
6 select to_number(xmlquery(par_value returning content))
7 into retval
8 from dual;
9
10 return retval;
11 end;
12 /
Function created.
Testing:
SQL> select f_result('3+11-2') result from dual;
RESULT
----------
12
SQL>
In Forms, I created a simple control block with two fields: one accepts numeric operations you want, another one displays the result. How? By executing the WHEN-VALIDATE-ITEM trigger on the 1st field. Its code is as simple as
:result := f_result(:values);

Checking Date in PL/SQL

I'm setting up a win auto job to accrue paid time off.
However, for personal time they only get a lump sum every year.
So I'm working on a pl/sql statement to check the date, but I can't get it to work.
I'm not sure what I'm doing wrong!!!
IF to_char(sysdate, 'MM/dd') = '01/01' THEN
PTO.personal_time := 8;
END IF;
update: to clarify. I want to check the date and if it is January first, to update the amount of personal time to 8 hours. I'm not getting any errors, but the amount of personal time isn't changing. There is no roll over and everyone gets one personal day, so i just set in on January 1st.
TABLE is a keyword and you cannot use it as a variable; however, if you replace table with the name of your variable then your code works perfectly (assuming that the variables of the appropriate names/types already exists):
DECLARE
-- declare a type which has a field names "field"
TYPE item_type IS RECORD(
field NUMBER
);
-- declare an "item" variable
item item_type;
BEGIN
-- start of your code
IF to_char(sysdate, 'MM/dd') = '04/25' THEN
item.field := 8;
END IF;
-- end of your code
DBMS_OUTPUT.PUT_LINE( item.field );
END;
/
which outputs:
8
db<>fiddle here

difficulties creating a pl/sql procedure

trying to create a procedure but i keep getting an error. here is the code
create or replace procedure HK.PURGE_LAN_DOTS
AS
batchsize number := 15000;
deleteline timestamp := current_timestamp - 365;
counter number := 0;
BEGIN
loop
DELETE FROM LAN.DOTS
WHERE rownum <= batchsize
AND TIMESTAMP < deleteline;
COMMIT;
counter:=counter + SQL%rowcount;
exit when batchsize > SQL%rowcount;
end loop;
HK.PURGE_LAN_DOTS;
END
this is the error iam getting
Error(36,12): PLS-00103: Encountered the symbol "." when expecting one of the following: ;
Probably just typos. This version ought to work (as long as HK has access to LAN.DOTS).
PL/SQL scripts are treated differently from standalone SQL in that they require both the trailing semicolon as well as a forward slash on a new line.
Slash vs. semicolon semantics in SQL*Plus is a bit odd; here's another question asked about precisely this:
When do I need to use a semicolon vs a slash in Oracle SQL?
Finally, you have included HK.PURGE_LAN_DOTS; before the END statement, when you probably intended to use END PURGE_LAN_DOTS;.
Note that you can't include the schema name in this closing tag, and the named closing tag is entirely optional (you can use just END;).
create or replace procedure HK.PURGE_LAN_DOTS
AS
batchsize number := 15000;
deleteline timestamp := current_timestamp - 365;
counter number := 0;
BEGIN
loop
DELETE FROM LAN.DOTS
WHERE rownum <= batchsize
AND TIMESTAMP < deleteline;
COMMIT;
counter:=counter + SQL%rowcount;
exit when batchsize > SQL%rowcount;
end loop;
END PURGE_LAN_DOTS;
/
The end of the code you posted has this:
end loop;
HK.PURGE_LAN_DOTS;
END
The END is missing a semicolon; but the previous line calls this procedure, which would cause infinite recursion (which Oracle would kill eventually).
I think you've corrupted this while posting and you actually have:
end loop;
END HK.PURGE_LAN_DOTS;
and now the error makes sense (although the report line and columns numbers don't quite).
Although the create statement takes an optional schema prefix:
create or replace procedure HK.PURGE_LAN_DOTS
the matching END does not. The overall statement can sort of be thought of as a mix of SQL and PL/SQL - not to the same extent that a trigger is, but here the effect is similar. The statement really does several things - it creates a procedure-type object called PURGE_LAN_DOTS under that schema, and compiles and stores the PL/SQL part of the code with the same name. The HK. bit is not part of the object name, and is not relevant to the PL/SQL engine - and the END is pure PL/SQL. If you look at the all_source view you'll see that the stored source will be PROCEDURE PURGE_LAN_DOTS AS ... without either the create or replace or the HK. prefix - the owner will be set to HK, though.
So, the END should only reference the PL/SQL object name, and cannot have a schema prefix:
create or replace procedure HK.PURGE_LAN_DOTS
...
end loop;
END PURGE_LAN_DOTS;
Not related, but:
deleteline timestamp := current_timestamp - 365;
will cause the current_timestamp value to be converted to a date to have 365 days subtracted, and that will then be converted back to a timestamp; which is more conversion than necessary, and loses the fractional seconds. You probably don't really care about that in this scenario, but sometimes it matters. To avoid both you could do either of these:
deleteline timestamp := current_timestamp - interval '365' day;
deleteline timestamp := current_timestamp - 365 * interval '1' day;
Once you switch to an interval you might be tempted to change that to current_timestamp - interval '1' year, but that will error with ORA-01839 if you run it on February 29th...
Also make sure you really do want current_timestamp and not systimestamp.

How to use checkbox in a report in oracle apex to insert values in a table

I have a table call OUTGOING which has many fields but the ones to be populated in this situation is:
FILENUMBER
OUTGOINGDATE
DEPARTMENT
now i have a report which whas an sql
SELECT APEX_ITEM.CHECKBOX2(1,registry.filenumber) "Select",
INCOMINGREQUESTNOTIFICATION.REQUESTEDFILE as REQUESTEDFILE,
INCOMINGREQUESTNOTIFICATION.FILENUMBER as FILENUMBER,
INCOMINGREQUESTNOTIFICATION.REQUESTEDDEPARTMENT as REQUESTEDDEPARTMENT,
INCOMINGREQUESTNOTIFICATION.REQUESTDATE as REQUESTDATE,
REGISTRY.STATUS as STATUS
from REGISTRY REGISTRY,
INCOMINGREQUESTNOTIFICATION INCOMINGREQUESTNOTIFICATION
where REGISTRY.FILENUMBER(+) =INCOMINGREQUESTNOTIFICATION .FILENUMBER
and INCOMINGREQUESTNOTIFICATION.STATUS ='PENDING'
which is fine .. what i need is for
INCOMINGREQUESTNOTIFICATION.FILENUMBER as FILENUMBER
INCOMINGREQUESTNOTIFICATION.REQUESTEDDEPARTMENT as REQUESTEDDEPARTMENT
and sysdate
to be inserted in the outgoing table under the relevant names of course.
I have a pl/sql
DECLARE
L_FILENUMBER WWV_FLOW_GLOBAL.VC_ARR2;
BEGIN
L_FILENUMBER := APEX_APPLICATION.G_F01;
FOR IDX IN 1 .. L_FILENUMBER.COUNT
LOOP
IF L_FILENUMBER(IDX) IS NOT NULL THEN
INSERT INTO OUTGOING
(FILENUMBER,OUTGOINGDATE,DEPARTMENT)
VALUES
((to_number(APEX_APPLICATION.G_F01(1)))
,SYSDATE
,to_char(APEX_APPLICATION.G_F02(2)) )
;
END IF;
END LOOP;
END;
which is not working.. However if i leave only filenumber
DECLARE
L_FILENUMBER WWV_FLOW_GLOBAL.VC_ARR2;
BEGIN
L_FILENUMBER := APEX_APPLICATION.G_F01;
FOR IDX IN 1 .. L_FILENUMBER.COUNT
LOOP
IF L_FILENUMBER(IDX) IS NOT NULL THEN
INSERT INTO OUTGOING
(FILENUMBER)
VALUES
((to_number(APEX_APPLICATION.G_F01(1)))
;
END IF;
END LOOP;
END;
its inserting only the file number fine . This is all being done via a submit button.
NB: i also tried putting outgoing date and department in the declare statement but it still doesnt work
I'd suggest you to learn how to use table aliases. SELECT you wrote is difficult to read due to VERY long table & column names; alias would certainly help.
As of your question: saying that "it is not working" doesn't help at all. What exactly doesn't work? Is there any error? If so, which one? Did you run the page in debug mode and check what's going on? If not, do that.
Apart from that, code you wrote doesn't make much sense - you're trying to insert the same values all over again. E.g. shouldn't APEX_APPLICATION.G_F01(1) be APEX_APPLICATION.G_F01(IDX)? Something like this:
begin
for idx in 1 .. apex_application.g_f01.count
loop
if apex_application.g_f01(idx) is not null then
insert into outgoing
(filenumber,
outgoingdate,
department
)
values
(apex_application.g_f01(idx),
sysdate,
apex_application.g_f02(idx)
);
end if;
end loop;
end;
Check (by inspecting the page) whether (tabular form?) items really are those that you've used (G_F01 and G_F02). If not, you'll have to fix that.
I didn't use any TO_NUMBER nor TO_CHAR functions; I don't know whether your really need them. Even if you don't have them, Oracle will perform implicit datatype conversion when possible, but it'll fail if you try to put e.g. 'abc123' into a NUMBER datatype column. You didn't share that information so - I left those out. Apply them if necessary.

Change inserted value with trigger

I've just started to learn SQL a few weeks ago and I'm trying to make a trigger which changes the inserted value into 10 if it's smaller than 10. I searched for 4h now and I've found a lot of answers but none was good(for me). I really don't understand where the problem is.
Here is the code:
CREATE OR REPLACE TRIGGER NumberOfBooks
BEFORE INSERT
ON Book
FOR EACH ROW
BEGIN
IF new.nobook < 10
THEN
SET new.nobook = 10;
END IF;
END;
In Oracle's trigger syntax the newly inserted record is referred to by :new, not new (notice the colon). Additionally, SET is a part of an update statement, not a way to set field values - those are done by simple assignments, but note that these are done with := rather than =.
So, your trigger should read:
CREATE OR REPLACE TRIGGER NumberOfBooks
BEFORE INSERT
ON book
FOR EACH ROW
BEGIN
IF :new.nobook < 10
THEN
:new.nobook := 10;
END IF;
END;

Resources