How to Redirect to different pages using branch in Oracle Apex? - plsql

I have defined a function returning a URL(redirect).
branch
Page 1: Home-
Pre-Rendering-
Before Header-
Branches
With the following script:
declare
x number:=1;
myurl varchar2(255);
begin
if v('AGENCY') = 'R-AG' then
x := 3;
myurl := 'f?p=&APP_ID.:3:&SESSION.'; ---page 3
else
x := 50;
myurl := 'f?p=&APP_ID.:50:&SESSION.'; --- page 50
end if;
return myurl;
end;
I have defined item applications
Name : AGENCY
Scope : Application
Session State Protection: Unrestricted
I have defined an application computation
Sequence :10
Computation Item: AGENCY
Computacion Point: After
Authentication Computacion Type: SQL Query(return single value)
Computacion:
SELECT ROL
FROM USERS;
But for some reason the branch only took page 3 as priority and "else" is not fulfilled to redirect to page 50 when it is the case.

Your computation looks like something that should have a filter - how many rows return from a select from 'users' with no filter?
Though if there were any issues from that, I would have thought p50 would be the result.
You could also do this more declaratively. As in, have a branch to page 3 when item AGENCY = R-AG, and a second branch to p50 with no condition.
You first branch to p3 could also have just a query returning rows, such as
select null
from users
where username = :app_user -- or whatever your filter should probably be here
and rol = 'R-AG'

Related

Getting multiple values from a function

I have my CLIENTS table with the fields: (PK:ID NUMBER), PRICE NUMBER, PAYMENT_TYPE_ID NUMBER, SESSION_AREA NUMBER
I created a dynamic action from my page, in order to take the above values from CLIENTS table according to my :P2007_CLIENTS_ID.
First i created this type:
CREATE OR REPLACE EDITIONABLE TYPE "PATIENT_DETAILS" as object
( payment_type number,
session_area number,
price number
)
/
then i created this function:
create or replace FUNCTION "F_PATIENT_DETAILS"
(patient_id in NUMBER, session_date date)
RETURN patient_details
IS
v_payment_type number;
v_session_area number;
v_price number;
BEGIN
SELECT CLIENTS.PAYMENT_TYPE_ID into v_payment_type
FROM CLIENTS
WHERE CLIENTS.ID = patient_id;
SELECT CLIENTS.SESSION_AREA into v_session_area
FROM CLIENTS
WHERE CLIENTS.ID = patient_id;
SELECT CLIENTS.PRICE into v_price
FROM CLIENTS
WHERE CLIENTS.ID = patient_id;
if v_price is null then
SELECT POLICIES.PRICE into v_price
FROM POLICIES
WHERE POLICIES.ACTIVE = 1
AND to_char(session_date, 'MM-DD-YYYY') BETWEEN POLICIES.START_DATE AND POLICIES.END_DATE;
end if;
return patient_details(v_payment_type, v_session_area, v_price);
END;
How do i get the values from this function in my page, with Dynamic Action?
I tried this: Identification-> Set Value, Set Type -> PL/SQL Function Body:
declare
My_Result PATIENT_DETAILS;
begin
My_Result := F_PATIENT_DETAILS(:P2007_CLIENTS_ID, :P2007_SESSION_DATE);
end;
Items to Submit-> P2007_CLIENTS_ID, :P2007_SESSION_DATE
Affected Elements -> P2007_PAYMENT_TYPE_ID, :P2007_SESSION_AREA, :P2007_PRICE
but nothing happens..!
Those three fields are never assigned the new values after your function is returned, eg:
:P2007_PAYMENT_TYPE_ID := my_result.payment_type;
Also, there is no reason for 3 separate queries on CLIENTS. You could do this in one motion.
SELECT c.PAYMENT_TYPE_ID, c.SESSION_AREA, c.PRICE
into v_payment_type, v_session_area, v_price
FROM CLIENTS c
WHERE c.ID = patient_id;
Taking that a step further, you could coalesce c.price with a subquery on policies.
Which has a questionable filter on a date being represented as a character. I doubt this would return accurate results.

Passing variable to a Select query in Oracle

I am working on Oracle 11g Db, Having trouble on writing Oracle syntax.
I am trying to pass a number variable to my select query and populate the select query to a cursor.
Declare yr_nr NUMBER;
Begin
yr_nr := 2014;
SELECT DCD.CCY ID, DCD.CCYCDDSC DSC
FROM CCYDCD DCD, CCYEXC EXC
WHERE DCD.CCY = EXC.CCY
AND EXC.YEARNR = yr_nr
End
This select query returns 80 records. How to rewrite this syntax.
Ok, so what you have here is an anonymous block and everything that happens in the block stays in that block. Kinda like Vegas.
In other words there is nothing to handle the result set from your query. When you do this:
declare
[varName] [type]
begin
select foo from bar where column = var ; <--- this has no place to go!
end
When you are at an sqlPlus prompt, sqlPlus has a default record set handler which then processes the returned record set and prints it to the screen.
When you use any third party tool like JDBC or Oracle's own OCI library those provide a record set handler then parse them to you with the appropriate calls to get the data, e.g.:
rs.getInteger([query],[column] ) //which returns the specific value.
That anonymous block is essentially a stored procedure. So you have to have something to do with the result set. This is the cause of the missing "into" error you are getting.
If on the other hand you did something like:
declare
[varName] [type]
result number ;
begin
select count(foo) into result from bar where column = var ;
end
The variable result would have the value of 80 since that is the number of records fetched.
declare
[varName] [type]
cursor thisCursor(p1 in number ) is select foo from bar where column = p1 ;
begin
for rec in thisCursor(varName) loop
If rec.column = [some value] then
doSomething
end if ;
end loop ;
end
Do this would allow you to do something with the result set.

PLS-00487 Error-Invalid reference to Variable 'CHAR'

I'm designing a function that is part of a larger package. The function is intended to take a District Code and return a collection of unique IDs for 10-15 stores that are assigned to that district. The function is intended to return a collection that can be queried like a table, i.e., using the TABLE function in a SQL statement.
I've created the following Types:
Schema Level type:
create or replace TYPE HDT_CORE_ORGIDS AS TABLE OF CHAR(20);
and a Type inside the Package
TYPE CORE_ORGIDS IS TABLE OF CHAR(20) INDEX BY BINARY_INTEGER;
Here's the function code:
FUNCTION FindDistrictOrgs(
ParamOrgCode VARCHAR2
)
RETURN HDT_CORE_ORGIDS
AS
ReturnOrgs HDT_CORE_ORGIDS := HDT_CORE_ORGIDS();
FDOTemp HDT_CORE_MAIN.CORE_ORGIDS;
i BINARY_INTEGER := 0;
CURSOR FDOCurr IS
SELECT org.id AS OrgID
FROM tp2.tpt_company org
WHERE LEVEL = 2
START WITH org.name = ParamOrgCode
CONNECT BY PRIOR org.id = org.parent_id;
BEGIN
OPEN FDOCurr;
LOOP
i := i +1;
FETCH FDOCurr INTO FDOTemp(i);
EXIT WHEN FDOCurr%NOTFOUND;
END LOOP;
IF FDOTemp.EXISTS(FDOTemp.FIRST) THEN
ReturnOrgs.EXTEND(FDOTemp.LAST);
FOR x IN FDOTemp.FIRST .. FDOTemp.LAST LOOP
ReturnOrgs(x) := FDOTemp(x).OrgID;
END LOOP;
END IF;
CLOSE FDOCurr;
RETURN ReturnOrgs;
END FindDistrictOrgs ;
I'm getting the PLS-00487:Invalid Reference to variable 'CHAR' at the line:
ReturnOrgs(x) := FDOTemp(x).OrgID;
I've double-checked at the value returned by the SQL (the org.id AS OrgID) is of the CHAR(20 BYTE) datatype.
So...what's causing the error?
Any help is appreciated! :)
OrgID is the alias you gave the column in your cursor, it has no meaning to the collection. Since both collections are of simple types you should just be doing:
ReturnOrgs(x) := FDOTemp(x);
The syntax you're using is implying FDOTemp is a collection of objects and you're trying to reference the OrgID attribute of an object; but since CHAR isn't an object type, this errors. The error message even makes some sense when viewed like that, though it's not terribly helpful if you don't already know what's wrong... and not entirely helpful when you do.
Incidentally, you could use a bulk collect to populate the collection without the cursor or loops, or the extra collection:
SELECT org.id
BULK COLLECT INTO ReturnOrgs
FROM tp2.tpt_company org
WHERE LEVEL = 2
START WITH org.name = ParamOrgCode
CONNECT BY PRIOR org.id = org.parent_id;
RETURN ReturnOrgs;

Unable to return query output in Apex PL SQL expression

I am trying to write a following PL/SQL function body for a dynamic action
The purpose of dynamic action is to set value for text area based on input parameters. Way I am trying to do it, is that setting the value into variable for different options
declare
P_NOTE varchar(100); -- derive value
P_WEBSERVER varchar(100); -- derive name
begin
-- for getting the P_NOTE value
select distinct note into P_NOTE from port_mapping where PLATFORM = :P3_PLATFORM and VERSION = :P3_VERSION;
-- for getting web server value
select CONCAT(P_NOTE,CONCAT('https-',:P3_CLIENT)) into P_WEBSERVER from dual order by 1;
if (:P3_PLATFORM = 'Apache') then
return P_WEBSERVER;
end if;
end;
However I am getting error
ORA-06550: line 15, column 5:
PLS-00372: In a procedure, RETURN statement cannot contain an expression
ORA-06550: line 15, column 5:
PL/SQL: Statement ignored
declare
P_NOTE varchar(100);
P_WEBSERVER varchar(100);
I am not sure what I am missing.
(Since you did not post any apex version this explanation deals with version 4.2)
If this -is- a dynamic action and the code you posted is in a true action of type 'Execute PL/SQL Code' then you can not use RETURN. The plsql block is not a function body (close, Mr Kemp!).
If you want to return values from the session state to page items then you need to use the "Page Items to Return" item of the true action.
This will put the session state of the defined page items into the value of the item on the page. This means that you can not use any variable to just put stuff in to be able to return it to the page, but you need to use an actual page item (after all, these are bind variables).
To clarify further, you would not write :
return P_WEBSERVER;
But you'd have to use a page item, say P3_WEBSERVER, and you'll need to create one if it doesn't exist of course:
:P3_WEBSERVER := p_webserver;
Of course you'd need to make sure that the correct value will be in there as you can not shortcircuit as you did in your code sample (p_webserver will usually hold a value even if the platform is not 'Apache') eg:
if (:P3_PLATFORM = 'Apache') then
:P3_WEBSERVER := P_WEBSERVER;
else
:P3_WEBSERVER := NULL;
end if;
Just read error message:
line 15, column 5
So, trouble caused by this line:
return P_WEBSERVER;
return not allowed in PL/SQL blocks, use output parameter to return a value.
Read Tom's answer to find out how to do that.

Ora-00904 - Error with creating a View

I'm stuck with creating a view in Oracle, but before I create the view, I always test it first and I always got this error: Ora-00904.
This is the situation. I have this one Set of Query let say Query A that I need to combined using UNION ALL with the Query A itself with only few modifications applied to create another bigger Set of Query - Query B. The main constraint that keeps me on doing this is the Database Design, and I'm not in the position in the company to change it, so I have to adapt to it. Query A unions Query A for 6 times creating Query B. The additional Major constraint is Query B is from 1 database user only, but there are 54 database users with the same structures that I need to fetch the same query. Query B (db user1) unions Query B (db user2) unions Query B (db user3) and so on until 54 then finally creating Query C --- the final output. My scrip has already reached 6048 lines, then I got this problem that I don't get when I test Query A and Query B. All my table names, owner names, and column names are all correct but I got that error.
This is the code (that needs to be repeated for 54x6 times) - the Query A. Query B applies some similar modification only.:
Select
'2013' "YEAR",
Upper(a.text_month) "MONTH",
Upper('Budget') "VERSION",
case
when length(b.level1_name) > 5 then 'Parent'
else 'SUBSIDIARIES'
end "COMPANY_GROUP",
case
when length(b.level1_name) < 6 and b.level1_name <> '1000' then 'Subsidiaries'
else '1000 Parent'
end "COMPANY",
case
when length(b.level1_name) < 6 and b.level1_name <> '1000' then 'SUBS'
else '1000'
end "COMPANY_CODE",
case
when length(b.level1_name) > 5 then 'Parent'
else 'SUBSIDIARIES'
end "COMPANY_NAME",
b.level1_displayname "DIVISION",
b.level1_name "DIVISION_CODE",
case
when length(b.level1_name) > 5 then ltrim(upper(substr(b.level1_displayname, 8)))
else upper(ltrim(substr(b.level1_displayname, 10)))
end "DIVISION_NAME",
upper(a.text_nature_of_trip) "NATURE_OF_TRAVEL",
upper(a.text_placeeventstraining) "TRAVEL_DETAILS",
upper(a.text_country) "COUNTRY",
a.text_name_of_employee "EMPLOYEE_NAME", a.float_no_of_attendees "NO_OF_ATTENDEES",
a.text_sponsored "SPONSORED",
a.text_remarks "REMARKS",
'OTHER TRAVEL EXPENSES' "COST_ELEMENT",
a.FLOAT_702120005_OTHER_TRAVEL_E "AMOUNT"
From PUBLISH_PNL_AAAA_2013.et_travel_transaction a,
PUBLISH_PNL_AAAA_2013.cy_2elist b
Where a.elist = b.level3_iid
ORA-00904 is "invalid column name" -- either you've spelled the column name wrongly, or prefixed it with the wrong table alias, omitted quotes from a string literal, or any number of other issues.
Check the point in the code that the error message mentions for mistakes like that.

Resources