How to pass a parameter to an Oracle Apex application process? - oracle

I'm using Oracle Apex 5. I have an ajax routine that gets a list of room numbers:
apex.server.process("getRooms"
,{pageItems:"#P1_ROOM"}
,{dataType:"text"})
.done(function(pReturn){
-- my processing code --
})
Instead of hard coding #P1_ROOM, can I pass a parameter? (I have many room number drop downs on the page.) Can I also somehow pass additional parameters, like the div id in which the form field #P1_ROOM exists?
Also, the 'getRooms' application process references the same hard coded value for the form field: :P1_ROOM. Can I parameterize this also?
declare
roomList varchar2(32000) := '';
begin
IF(:P1_ROOM)!= ' ' THEN
for c in
(select distinct room_id from RTP_PERSON_VIEW
where upper(room_id) LIKE upper(:P1_ROOM) || '%'
order by room_id)
loop
roomList := roomList || '~' || c.room_id;
end loop;
htp.prn( roomList );
END IF;
end;

Use the Apex JavaScript API syntax $v("P1_ROOM") to pass the parameter.
You can pass a maximum of 10 values like this:
apex.server.process (
"MY_PROCESS"
, { x01: $v("P1_ROOM")
, x02: $v("P1_CATS")
, x03: $v("P1_DOGS")
, x04: 'my last variable'
}
, { dataType: 'text'
,success: function(pData){alert(pData)}
}
);
Here you have more examples on how to use the Apex JavaScript API.
Here you can find a tutorial on how to pass more than 10 values with apex.server.process

There is another way:
apex.server.process (
"MY_PROCESS"
, { pageItems: "#P152_ID,#P152_ID_OBJ,#P152_ORDER_DT,#P152_SUMM" }
, { dataType: 'text'
, success: function(pData){alert(pData)}
} );

Related

How to get a value in a variable PL/SQL

I am in the realization of a form in PL/SQL also with the help of hypertext procedures (HTP), what I want is to obtain in a variable the value that I am selecting in a dropdown, the code with which I am building part of my form is as follows:
ELSIF cant_rol > 1 then
HTP.p( 'V_ROL: '|| V_ROL);
HTP.p( 'V_TERM: '|| V_TERM);
bwckfrmt.p_open_doc ('HWSKCETI.P_Principal', v_term); --
HTP.formOpen (twbkwbis.f_cgibin || 'HWSKCETI.P_Principal', cattributes=>'onsubmit="checkSubmit();"');
twbkfrmt.P_TableOpen (
'DATAENTRY',
cattributes => 'SUMMARY="' ||
G$_NLS.Get ('HWSKCET1-0000',
'SQL',
'This table allows the user to select the role') ||
'."'
);
twbkfrmt.P_TableRowOpen;
twbkfrmt.P_TableDataLabel (
G$_NLS.Get ('HWSKCET2-0001', 'SQL', 'Select a rol: ')
);
twbkfrmt.P_TableDataOpen; --
twbkfrmt.p_formlabel (
G$_NLS.GET ('HWSKCET3-0002', 'SQL', 'Rol'),
visible => 'INVISIBLE',
idname => 'role_id'
); --twbkfrmt
HTP.formSelectOpen (
'campus',
NULL,
1
);
FOR currole IN (select sorarol_radm_code
from SORAROL WHERE SORAROL_PIDM = global_pidm
AND sorarol_radm_code LIKE 'EXPT%')
LOOP
twbkwbis.P_formSelectOption (currole.sorarol_radm_code);
END LOOP;
HTP.FormSelectClose;
twbkfrmt.P_TableDataClose;
twbkfrmt.P_TableRowClose;
twbkfrmt.P_TableClose;
HTP.formsubmit (NULL, G$_NLS.Get ('BWSKFLI1-0007', 'SQL', 'Enviar'), 'id="btn_submit_role"'); --G$_NLS.Get ('BWSKFLI1-0007', 'SQL', 'Submit')
HTP.p( 'V_ROL: '|| v_rol);
HTP.formClose;
RETURN;
END IF;
The following is the view in which I am showing my dropdown and I load the different roles that I have
See example image here
But when wanting to select the value within the dropdown, the variable V_ROL is shown empty.
It's a little unclear what you're asking and your code sort of starts in the middle. But if you're using htp, then you're generating a form for a user to interact with. So if you want v_rol to have a value, you have to assign it one and you don't seem to do that anywhere.
If you want the value in the page to change in response to user action, like when the user chooses an option in the select list, that's not going to be PL/SQL, that's going to be JavaScript running in the browser.

Oracle APEX -How to combine server side condition of "requet = expression1" and "exisits ( sql query return atleast one row)

I want to call validation when
query return at least one row like ( select 1 from table where id = 1 )
and
when request "add_data" is called
Don't know what to select here:
The value of request can be accessed via the bind variable REQUEST . To tackle your specific problem you could add that to your condition of type 'Rows returned' like this:
SELECT 1
FROM table
WHERE (
id = 1 AND
:REQUEST = 'add_data'
)
If you're more a fan of pl/sql you could take the condition type 'PL/SQL Function Body' with code like this:
DECLARE
l_dummy NUMBER;
BEGIN
-- quit here if request value doesn't match
IF :REQUEST != 'add_data' THEN
RETURN false;
END IF;
-- check if we have rows in table.
BEGIN
SELECT 1
INTO l_dummy
WHERE EXISTS (select 1 from table where id = 1)
EXCEPTION WHEN NO_DATA_FOUND THEN
RETURN false;
END;
RETURN true;
END;
This is more code but you could find it easier to read which can be an advantage for maintenance later on.
The way I understood it, add_data request is related to a button you push. If that's so, then - if you don't do anything, request name equals button name - so let's pretend that button name is ADD_DATA. Therefore:
in "When Button Pressed" property select button's name (ADD_DATA, right?)
in "Condition Type" pick the condition you mentioned ("SQL query returns at least one row")

Checking Count of Records from a Cursor

I have a custom-defined cursor that is pulling from a function that returns a nested table. I'm using the TABLE function (DDS_COMPILE) in the SQL of the cursor definition to pull the data. I have built a simple check after the pull to FETCH records into a Record DataType Object (also custom-defined to match) and, if no data if found using the %NOTFOUND, it should raise an Exception.
When I run the routine for a given set of input parameters (i.e., STORE X, for CLASS Y), the code returns 1 record. I can see the record if I run the function that queries the database by itself and the record displays only if my FETCH statement is commented out. If the FETCH is uncommented, it throws a NoData Exception. So what is wrong with my FETCH?
Here's a snippet of the code:
OPEN DataReturn FOR
SELECT
DDSRecs.OrgID
, DDSRecs.DistrictCode
, DDSRecs.DistrictName
, DDSRecs.StoreNumber
, DDSRecs.StoreName
, DDSRecs.AssociateLastName
, DDSRecs.AssociateFirstName
, DDSRecs.AssociateMiddleName
, DDSRecs.AssociateLDAP
, DDSRecs.AssociateUID
, DDSRecs.AssociateDeptName
, DDSRecs.DeptHeadCount
, DDSRecs.JobCode
, DDSRecs.ActSourceableStatus
, DDSRecs.CertTargetDate
, DDSRecs.CertName
, DDSRecs.CertExpiredOn
, DDSRecs.CertRevokedOn
, DDSRecs.CertRecertStartsOn
, DDSRecs.CourseNumber
, DDSRecs.CourseNumberName
, DDSRecs.CourseHours
, DDSRecs.RegID
, DDSRecs.CourseStatus
, DDSRecs.CourseActionStatus
, DDSRecs.CourseTargetDate
, DDSRecs.CourseCompletionDate
, DDSRecs.CourseDenseRank
, DDSRecs.DueDateStatus
, DDSRecs.DueDate
, DDSRecs.RegAction
, DDSRecs.DeliveryMode
, DDSRecs.MMUFlag
, DDSRecs.ErrorMessage
FROM TABLE(HDT_CORE_MAIN.DDS_COMPILE(
FinalOrgID
, ParamReportType
, ParamCourseNumberCheck
, ParamNameKeywordCheck
)) DDSRecs
;
LOOP
FETCH DataReturn INTO DDS_ERR_CHECK;
IF DataReturn%NOTFOUND THEN
RAISE DDS_ERR_NO_DATA;
END IF;
END LOOP;
CLOSE DataReturn;
There's much more to the procedure, of course, that's not related to this issue. Utlimately, it's the loop at the end that isn't working as intended. Anyone got any ideas?
Thanks in advance for your help! :)
UPDATE:
I've tried a couple of suggestions and changed the FETCH LOOP to the following:
LOOP
x := x + 1;
FETCH DataReturn INTO DDS_ERR_CHECK;
IF DataReturn%FOUND THEN
DBMS_OUTPUT.PUT_LINE('x = ' || x);
EXIT;
ELSE
RAISE DDS_ERR_NO_DATA;
END IF;
END LOOP;
This sees the 1 record (as it does not throw the Exception), but the 1 record is not displayed in the Output Variables. Note that the X did increment to 1 as intended.
You have no exit statement to terminate your loop - it will keep on fetching until %notfound no matter how many rows in your table function.

identify selected checkboxes in apex interactive report

I have an Interactive Report which I'm generating using a collection.
select apex_item.checkbox(1,'obj_name') ' ',
col 01,
col 02
from apex_collections where collection_name='XYZ';
The table on which this report is being generated has a composite primary key,
so when the user selects multiple checkboxes, I'm not able to figure out how to identify which all rows were selected by user. This is because according to my knowledge, through p_value in apex_item.checkbox(p_idx,p_value) I can just pass one column/field/item. But the requirement is to pass both obj_name and col 01 back to the pl/sql code.
To explain it better, I have an on submit process associated to it.
FOR I in 1..APEX_APPLICATION.G_F01.COUNT LOOP
DELETE FROM abc
WHERE obj_name = (APEX_APPLICATION.G_F01(i))
AND tab_col = col 01;
END LOOP;
So how can I send the value of col 01 of the selected checkboxes to the above process is what my question is. Any help would be great.
A better approach which I've found now is using rownum as unique value, that actually reduces a lot of logic in my code. Just calling it out.
Could you concatenate the obj_name and col_name?
select apex_item.checkbox(1,'obj_name-'||col_01) ' ', from apex_collections where collection_name='XYZ';
Then in the processing section
FOR I in 1..APEX_APPLICATION.G_F01.COUNT LOOP
my_object_name := substr( G_F01(i), 1, instr( G_F01(i), '-' ) - 1 );
my_column_name := substr( G_F01(i), instr( G_F01(i), '-' ) + 1 );
DELETE FROM abc WHERE obj_name = my_object_name AND tab_col = my_column_name;
END LOOP;

Oracle pipelined function cannot access remote table (ORA-12840) when used in a union

I have created a pipelined function which returns a table. I use this function like a dynamic view in another function, in a with clause, to mark certain records. I then use the results from this query in an aggregate query, based on various criteria. What I want to do is union all these aggregations together (as they all use the same source data, but show aggregations at different heirarchical levels).
When I produce the data for individual levels, it works fine. However, when I try to combine them, I get an ORA-12840 error: cannot access a remote table after parallel/insert direct load txn.
(I should note that my function and queries are looking at tables on a remote server, via a DB link).
Any ideas what's going on here?
Here's an idea of the code:
function getMatches(criteria in varchar2) return myTableType pipelined;
...where this function basically executes some dynamic SQL, which references remote tables, as a reference cursor and spits out the results.
Then the factored queries go something like:
with marked as (
select id from table(getMatches('OK'))
),
fullStats as (
select mainTable.id,
avg(nvl2(marked.id, 1, 0)) isMarked,
sum(mainTable.val) total
from mainTable
left join marked
on marked.id = mainTable.id
group by mainTable.id
)
The reason for the first factor is speed -- if I inline it, in the join, the query goes really slowly -- but either way, it doesn't alter the status of whatever's causing the exception.
Then, say for a complete overview, I would do:
select sum(total) grandTotal
from fullStats
...or for an overview by isMarked:
select sum(total) grandTotal
from fullStats
where isMarked = 1
These work fine individually (my pseudocode maybe wrong or overly simplistic, but you get the idea), but as soon as I union all them together, I get the ORA-12840 error :(
EDIT By request, here is an obfuscated version of my function:
function getMatches(
search in varchar2)
return idTable pipelined
as
idRegex varchar2(20) := '(05|10|20|32)\d{3}';
searchSQL varchar2(32767);
type rc is ref cursor;
cCluster rc;
rCluster idTrinity;
BAD_CLUSTER exception;
begin
if regexp_like(search, '^L\d{3}$') then
searchSQL := 'select distinct null id1, id2_link id2, id3_link id3 from anotherSchema.linkTable#my.remote.link where id2 = ''' || search || '''';
elsif regexp_like(search, '^' || idRegex || '(,' || idRegex || || ')*$') then
searchSQL := 'select distinct null id1, id2, id3 from anotherSchema.idTable#my.remote.link where id2 in (' || regexp_replace(search, '(\d{5})', '''\1''') || ')';
else
raise BAD_CLUSTER;
end if;
open cCluster for searchSQL;
loop
fetch cCluster into rCluster;
exit when cCluster%NOTFOUND;
pipe row(rCluster);
end loop;
close cCluster;
return;
exception
when BAD_CLUSTER then
raise_application_error(-20000, 'Invalid Cluster Search');
return;
when others then
raise_application_error(-20999, 'API' || sqlcode || chr(10) || sqlerrm);
return;
end getMatches;
It's very simple, designed for an API with limited access to the database, in terms of sophistication (hence passing a comma delimited string as a possible valid argument): If you supply a grouping code, it returns linked IDs (it's a composite, 3-field key); however, if you supply a custom list of codes, it just returns those instead.
I'm on Oracle 10gR2; not sure which version exactly, but I can look it up when I'm back in the office :P
To be honest no idea where the issue came from but the simplest way to solve it - create a temporary table and populate it by values from your pipelined function and use the table inside WITH clause. Surely the temp table should be created but I'm pretty sure you get serious performance shift because dynamic sampling isn't applied to pipelined functions without tricks.
p.s. the issue could be fixed by with marked as ( select /*+ INLINE / id from table(getMatches('OK'))) but surely it isn't the stuff you're looking for so my suggestion is confirmed WITH does something like 'insert /+ APPEND*/' inside it'.

Resources