I am working on Oracle APEX 5 and wanted to transfer values added into List manager (in page 2) to display them on Page 3 as read-only. How can we do that?
What type of item to choose to display values in page 3? and how to get these values from list manager?
please help.Thanks in advance.
The List Manager item type can hold multiple values, which are delimited by a colon e.g. '7782:7902:7788:7698'. If you pass this item value to a hidden item in the target page then you can call apex_string.split to convert it to an array of values, which you can then process as you wish. For example, if the values are EMPNOs and you want to display all the names in a display only item you can write code like:
declare
empno_array wwv_flow_t_varchar2;
begin
empno_array := apex_string.split (:P3_HIDDEN_ITEM, ':');
select listagg (ename, ', ') within group (order by ename)
into :P3_DISPLAY_ITEM
from emp
where empno in (select column_value
from table(empno_array));
end;
Related
My requirement is that users must be able to select from a shuttle page item the employee numbers that they need to delete from a table. In the back end I have a plsql code that is supposed to delete the selected employee numbers as follows:
BEGIN
delete from employees where empno in (:P7_EMPLOYEE_NUMBER);
END;
Additionally I will have more logic in the code to do other stuff, however I am not able to delete multiple rows, if I select 1 employee number in the shuttle item, I am able to delete the record successfully, when I try to delete more than one record I keep getting the following error:
Ajax call returned server error ORA-01722: invalid number for Execute Server-Side Code
I changed the code to:
BEGIN
delete from employees where empno in (to_number(:P7_EMPLOYEE_NUMBER));
END;
and I keep getting the same error message.
How can I make this work?
The API APEX_STRING has a number of utility functions to deal with multi-value page items (select lists, checkbox, shuttles). To convert a colon separated list to an array, use APEX_STRING.SPLIT.
DELETE
FROM
employees
WHERE empno IN
(SELECT column_value
FROM table(apex_string.split(: P7_EMPLOYEE_NUMBER,':'))
);
A shuttle item contains colon-separated values, which means that you have to split it to rows, e.g.
delete from employees
where empno in (select regexp_substr(:P7_EMPLOYEE_NUMBER, '[^:]+', 1, level)
from dual
connect by level <= regexp_count(:P7_EMPLOYEE_NUMBER, ':') + 1
);
The APEX engine will always submit multi-values items as a single colon-delimited string, for example: 1:2:3:4
You need to split the string into multiple values so that you can process them.
There are multiple ways to do this:
Using an the APEX_STRING.SPLIT or the APEX_STRING.SPLIT_NUMBERS API in a subquery
delete from employees
where empno in (select column_value
from apex_string.split_numbers(:P7_EMPLOYEE_NUMBER, ':'));
Using the APEX_STRING API with the MEMBER OF function
delete from employees
where empno member of apex_string.split_numbers(:P7_EMPLOYEE_NUMBER, ':');
Note that the member of needs to have the same type. In this case empno is a number so you must use the split_numbers API.
Using a regular expression to split the values
delete from employees
where empno in (select regexp_substr(:P7_EMPLOYEE_NUMBER, '[^:]+', 1, level)
from dual
connect by level <= regexp_count(:P7_EMPLOYEE_NUMBER, ':') + 1
);
I prefer using option 2 as it's less code and easier to read.
The parameter p_type is the LOV based on the select:
Select p_type
from parameter_types
where table_name = 'X'
and column_name = 'Y'
UNION
Select '-All-'
from dual;
Also the
1)Restrict List to Predermined Values is checked and
2) Hide First Column is unchecked.
3) initial value not given
I tried by setting up the into initial value to 'ALL'
Please help/suggest to debug this
It seems that you set parameter's initial value to something that LoV query doesn't return.
For example, suppose that you used Scott's DEPT table and set LoV to return this:
SQL> select dname from dept order by dname;
DNAME
--------------
ACCOUNTING
OPERATIONS
RESEARCH
SALES
Setting initial value to e.g. FINANCIALS would cause that error because FINANCIALS doesn't exist among selectable values (ACCOUNTING, OPERATIONS, RESEARCH, SALES).
What to do? Remove initial value, or set it to one of valid values.
From my APEX page I am opening a pop up page and trying to load it with data from the database. To do so, I used
Pre-Rendering After Header Process. Process type is set to PL/SQL code:
BEGIN
IF :P3_RECORD_ID IS NOT NULL THEN
select TYPE_ID, RECORD_TEXT
INTO :P3_TYPE_ID, :P3_RECORD_TEXT
from TABLE1
where RECORD_ID = :P3_RECORD_ID;
END IF;
END;
On the pop up page I have a dropdown (P3_TYPE_ID) which is filled from the LOV and a text field (P3_RECORD_TEXT).
The values show up in the session state but not in the dropdown or a text field. I can't figure out what am I doing wrong...
I also tried Automated Row Fetch but that did not load any values into fields either, just into session state
Did you consider using default value for those items? It would be a "PL/SQL Function Body" and look like this (for P3_TYPE_ID):
declare
l_type_id table1.type_id%type;
begin
select max(type_id)
into l_type_id
from table1
where record_id = :P3_RECORD_ID;
return l_type_id;
end;
I used MAX function to avoid possible NO_DATA_FOUND and TOO_MANY_ROWS errors. Handle them in EXCEPTION section, if necessary.
Similarly, populate P3_RECORD_TEXT.
I have a table called Employees with Employee_id and Employee_Name columns. Now i want to create a page with Checkbox in-front of every Employee Name, select the ones that are needed, store them into a temporary table and use them for further operations. The problem i am facing is to how to create that multi select list and store the select values in thee table. Is there an Item for multi select? If not, how should i do it?
There's the Shuttle item. On the left side, you'd display list of all employees. Item buttons allow you to move all (or only some of them) to the right side of the item. Once you submit the page, list of employee IDs is stored into a table column in a form of colon-separated values, for example
6547:8879:5587:9987
This is a simple way of doing that. However, once you have to actually do something with those values, you have to split them to rows. Not a problem, though. Here's a query:
SQL> with emps (shuttle_item) as
2 (select '6547:8879:5587:9987' from dual)
3 select regexp_substr(shuttle_item, '[^:]+', 1, level) one_item
4 from emps
5 connect by level <= regexp_count(shuttle_item, ':') + 1;
ONE_ITEM
---------------------------------------------------------------------
6547
8879
5587
9987
SQL>
Or, you could create a tabular form which also displays all employees and has checkboxes at the beginning of every line. You'd then create a process which - in a loop - stores selected values into a temporary table you mentioned. For example:
-- F01 = row selector. If you check 1st and 3rd row, f01.count = 2 (2 rows checked)
-- f01(1) = 1 (row #1), f01(2) = 3 (row #3)
-- F02 = EMP_ID. f02(1) = EMP_ID that belongs to employee in 1st row,
-- f02(3) = EMP_ID that belongs to emplyee in 3rd row
declare
l_id number;
begin
for j in 1 .. apex_application.g_f01.count
loop
l_id := apex_application.g_f02(apex_application.g_f01(j));
insert into temp_table (emp_id) values (l_id);
end loop;
end;
There is an option for creating multi select list in oracle apex 5.1.
Create a pageItem of type: 'select list'.
Make the 'Allow multi
selection' to 'Yes'.
Write the SQL query for your select list under
the 'List of Values' attribute.
Then the select list will be
displayed based on our query.
Query format is:
select [displayValue],
[returnValue]
from ...
where ...
order by ...
Now once you select multiple value from select list(using ctrl+click), these are stored as ':' separated values in the select list page item.
I've created a video some times ago that covers your problem. It's a step by step tutorial how to create checkboxes and process them.
Video is available here:
https://www.youtube.com/watch?v=T-LXRMWQbPk
Regards
If the list is too big, I recommend to use the Popup LOV item with the Multiple Values switch activated instead the Select list or the Shuttle, because it has an internal search field for the objects list, doing way easier for the user to find the target values. Also, just as the Select List or Shuttle item, you can set a Separator character for the selected fields.
I am creating an overloaded PLSQL stored procedure which allows to display the names of schools, their corresponding category (elementary, etc), and neighbourhood they belong to.
The names of schools is taken from table OTTAWASCHOOLS from the field NAME. The category is taken from the table OTTAWASCHOOLS from the field CATEGORY.
In addition, the user has the choice to input a particular neighbourhood to find the above information of the schools in that neighbourhood. The name of the neighbourhood is taken from the OTTAWANEIGHBOUR table from the field NAME.
However, if the user does NOT input a specific neighbourhood, the output will display the names ALL the schools in the OTTAWASCHOOLS table with their respective neighbourhoods and categories
(I have created only one procedure at the moment).
My code is as follows
SET SERVEROUTPUT ON;
SET VERIFY OFF
CREATE OR REPLACE PACKAGE schools_package
AS
PROCEDURE find_school
(neighbourhood_name IN OTTAWANEIGHBOUR.NAME%TYPE);
END schools_package;
/
CREATE OR REPLACE PACKAGE BODY schools_package
AS
PROCEDURE find_school
(neighbourhood_name IN OTTAWANEIGHBOUR.NAME%TYPE)
IS
school_category OTTAWASCHOOLS.CATEGORY%TYPE;
school_name OTTAWASCHOOLS.NAME%TYPE;
v_neighbourhood_name OTTAWANEIGHBOUR.NAME%TYPE;
CURSOR c_schools IS
SELECT NAME, CATEGORY
FROM eluliGDM.OTTAWASCHOOLS;
r_schools c_schools%ROWTYPE;
BEGIN
FOR r_schools IN c_schools
LOOP
SELECT c1.NAME, c2.NAME, c2.CATEGORY
INTO v_neighbourhood_name, school_name, school_category
FROM eluliGDM.OTTAWANEIGHBOUR c1, eluliGDM.OTTAWASCHOOLS c2
WHERE SDO_RELATE (c2.GEOMETRY, c1.GEOMETRY, 'MASK=INSIDE+COVEREDBY QUERYTYPE=JOIN') = 'TRUE'
AND c2.NAME=r_schools.NAME;
DBMS_OUTPUT.PUT_LINE ('NEIGHBOURHOOD ' || 'CATEGORY '|| 'SCHOOL NAME ');
DBMS_OUTPUT.PUT_LINE ('------------- ' || '-------- '|| '----------- ');
DBMS_OUTPUT.PUT_LINE (v_neighbourhood_name || school_category|| school_name);
END LOOP;
CLOSE c_schools;
END find_school;
END schools_package;
-----------TESTING STORED PROCEDURE---------------
Execute schools_package.find_school();
Execute schools_package.find_school('Mer Bleue');
But when I test the procedure, I get an error :01001. 00000 - "invalid cursor" then proceeds to show me ALL neighborhoods and their corresponding schools. What is wrong with my cursor?
Remove the CLOSE c_schools; statement. The Cursor For Loop already takes care of that. See Oracle Docs:
"The cursor FOR LOOP statement implicitly declares its loop index as a record variable of the row type that a specified cursor returns, and then opens a cursor. With each iteration, the cursor FOR LOOP statement fetches a row from the result set into the record. When there are no more rows to fetch, the cursor FOR LOOP statement closes the cursor."
According to your typing, OTTAWASCHOOLS contains both columns NAME and CATEGORY, so the cursor itself appears to be validly defined.
OTOH, does schema eluliGDM own both the tables and the package? If that is not the package owner, perhaps there are privilege issues? If the schema is the same, why specify the schema in the code? If not the same, consider the use of synonyms and removing the hard-coded schema from the code.
I'm not sure why you have an input parameter; you're not using it. So, I'm not surprised you're getting all the schools; the cursor has no predicate so it's the full table, and the SELECT inside the LOOP joins wherever the NAME column is the same in both tables. Without anything to limit based on input parameter, you have no filters at all beyond the join.
HTH