Changing a 0 or 1 value to "Yes" and "No" in APEX report - oracle

I have a report region on my page and it's getting data from a students table. Within that table, there's a column called cv_lodged which is either 1 or 0 representing Yes or No. In the report it shows this columns data as 0 or 1, I want to change it to show Yes or No.
How can I do this?

You can put a CASE statement in your query
SELECT (CASE WHEN cv_lodged = 1
THEN 'Yes'
ELSE 'No'
END) cv_lodged,
other_columns
FROM students
If this is something that is likely to be common, you're probably better served creating a function that converts your pseudo-boolean data to a string. Something like
CREATE FUNCTION my_bool_to_str( p_num IN NUMBER )
RETURN VARCHAR2
IS
BEGIN
IF( p_num = 1 )
THEN
RETURN 'Yes';
ELSE
RETURN 'No';
END IF;
END;
that you would call in your query
SELECT my_bool_to_str( cv_lodged ) cv_lodged,
other_columns
FROM students

I've usually just created a static LOV in Shared Components called YES1_NO0, with 2 entries: 'Yes' -> 1, 'No' -> 0.
In Interactive Reports you can then change these columns. To do this, edit the column of the IR. Change 'Display Type' to 'Display as Text (based on LOV, escape special characters)'. Then under 'List of Values' set 'Column Filter Type' to 'Use Named List of Values to Filter Exact Match' and select the named LOV.
But sure, you can totally do this in SQL.

Currently, there is a simpler way to do this.
First open the APEX page with the "Yes/No" item as developer and click on the item to open the page item settings.
Change the Settings value from Use component settings to Custom.
Afterwards change the Yes Value to 1 and the No Value to 0.
This solution has some advantages:
No need to decode the value 1 or 0 to Y or N (select decode(mycolumn, 1, 'Y', 'N') from mytable where id = 123;) or select case when ...
No need to decode the submitted value back to 1 or 0 from Y or N

Related

Make a text field accept only numeric values in APEX

I have an APEX app that I am working on and need to make a field to only accept numeric values.
I want to have a validation that displays "Only numeric values allowed" whenever the user inputs letters or other characters that are not numeric.
How can I achieve this?
Thanks in advance
If you use the translate function, you can "detect" whether string contains something but digits (this example allows decimal dot as well):
SQL> with test (col) as
2 (select '1234' from dual union all -- valid
3 select '12a4' from dual union all -- invalid
4 select '12.4' from dual union all -- valid
5 select 'abcd' from dual union all -- invalid
6 select '1#34' from dual -- invalid
7 )
8 select col, translate(col, 'x0123456789.', 'x') result
9 from test;
COL RESU
---- ----
1234
12a4 a
12.4
abcd abcd
1#34 #
SQL>
So, if the result is NULL, then it is a valid value.
In Apex, you'd create validation (function that returns error text) which looks like this:
if translate(:P1_ITEM, 'x0123456789.', 'x') is not null then
return 'Only numeric values allowed';
else
return null;
end;
These field definitions are more about the inherent server-side validations that will run on your behalf to ensure the data submitted is numeric.
I think the best you're going to get is having some client side validation as well that gives the user immediate feedback - either has message, or auto-strip. I'm not sure if you can force a HTML element to only allow numerics.
If you really need to validate after each new character, you can try to add Dynamic Action based on Key Release event and Execute JavaScript code when true. Something like this
if ( $v("P2_NEW") !== ""
&& isNaN($v("P2_NEW"))) {
alert("Not a number");
}
Ok after some hours of trying this and that, the following is what has worked for me.
Click in the page. In the "Function and Global Variable Declaration" section add this code:
function isInputNumber(evt){
var ch = String.fromCharCode(evt.which);
if(!(/[0-9]/.test(ch))){
evt.preventDefault();
}
}
In the "Page HTML Body Attribute" section add this code:
onkeypress="isInputNumber(event)"
and thats it. This will prevent the user from entering letters into the input field.

Oracle: How to check whether the given array exists in the table?

I want to check whether the array of values (4690, 4693) both is exists in the contextid column without using functions as the table contains more that a million records
Table structure:
ID
CONTEXTID
4
4690
5
4690
6
4693
7
4693
8
4690
What about this query?
select
case when count(distinct CONTEXTID) = 2 then 'Y' else 'N' end as contains_4690_4693
from tab
where CONTEXTID in (4690, 4693)
it retuns Y if both keys are in the table at least once, N otherwise.
If you just want to find out if they exist then
SELECT DISTINCT(CONTEXTID)
FROM SOME_TABLE
wHERE CONTEXTID IN (4690, 4693)
will do it. If CONTEXTID isn't indexed, though, the database will have to do a full table scan which will probably be slow.
Takeaway: add an index on CONTEXTID or live with the fact that it's going to be slow.
If the "test" values are known when you write the query (as they very rarely are - even though all the solutions presented so far make the implicit assumption that they are), you could do something like this - which is probably the most efficient way, regardless of whether there is an index on the relevant column or not:
select case when exists
( select *
from sys.odcinumberlist(4690, 4693)
where column_value not in ( select contextid
from the_table
where context_id is not null
)
) then 'Not all found' else 'All found' end as result
from dual
;
Note how I gave an array of input values to the query - I used the sys.odcinumberlist constructor. You will have to clarify how you plan to "input" an array of "test" values.

Oracle Apex Master Detail Report and Detail report with Radio Button Option to select

I am looking for advice to build a simple Quiz type application in Oracle Apex.
I don't need to build any Create/Update/Delete screens for base tables since I will populate my tables with data using SQL statements.
I have two tables
Create Table Question_Bank
(
Question_Id Number (5) Primary Key ,
Question_Description Varchar2(1000)
)
;
Question_Choice_Id is like 1,2,3,4 ( it is like no of quiz option choices)
Create Table Question_Choices
(
Question_Choice_Pk Number (5) Primary Key,
Question_Id Number(5) References Question_Bank(Question_Id),
Question_Choice_Id Number(1),
Question_Choice_Description Varchar2(200),
Is_Correct Varchar(1) Default 'N',
Explanation Varchar2(500)
);
So application should be displaying questions and options like this.
I would prefer one scrollable page of some numbers on question on one page.
This is Question No 1
Option 1
Option 2
Option 3
Option 4
This is Question No 2
Another Option 1
Another Option 2
Another Option 3
Another Option 4
This is Question No 3
Q No 3 Option 1
Q No 3 Option 2
Q No 3 Option 3
Q No 3 Option 4
So far I have created Master/Detail form which is kind of report (not editable) and I can see questions and possible choices (I have select question and choices are shown in 2nd column) but this is not what I want.
I am using Free Oracle Apex online account version 20.2.
You can try dynamicly build page with questions and choices. You have to add a new PL/SQL Dynamic Region region to page. In Source > PL/SQL Code region attribute put sample code below.
FOR l_question IN (
SELECT QUESTION_ID, QUESTION_DESCRIPTION
FROM QUESTION_BANK
order by QUESTION_ID
) LOOP
HTP.P('<h3>' || APEX_ESCAPE.HTML(l_question.QUESTION_DESCRIPTION) || '</h3>');
HTP.P(
APEX_ITEM.HIDDEN(
p_idx => 1, -- Values stored in APEX_APPLICATION.g_f01 table.
p_value => l_question.QUESTION_ID
)
);
HTP.P('<fieldset id="qfs' || l_question.QUESTION_ID || '">');
HTP.P(
APEX_ITEM.TEXT(
p_idx => 2, -- Values stored in APEX_APPLICATION.g_f02 table.
p_item_id => 'qh' || l_question.QUESTION_ID,
p_attributes => 'style="display:none"'
)
);
FOR l_choice IN (
SELECT QUESTION_CHOICE_ID, QUESTION_CHOICE_DESCRIPTION
FROM QUESTION_CHOICES
WHERE QUESTION_ID = l_question.QUESTION_ID
) LOOP
HTP.P('<input type="radio" value="' || l_choice.QUESTION_CHOICE_ID || '" name="' || l_question.QUESTION_ID || '" onchange="document.getElementById(''qh' || l_question.QUESTION_ID || ''').value = this.value">');
HTP.P('<label for="' || l_question.QUESTION_ID || '">' || APEX_ESCAPE.HTML(l_choice.QUESTION_CHOICE_DESCRIPTION) || '</label>');
END LOOP;
HTP.P('</fieldset>');
END LOOP;
This PL/SQL block iterates through all questions, then prints HTML markup with question description and fieldset with radio buttons. As you can see I use APEX_ITEM package to generate two columns - QUESTION_ID and QUESTION_CHOICE_ID. Each iteration creates new record with these two columns. If you checked the APEX documentation you may wonder why I didn't use APEX_ITEM.RADIOGROUP for building radio buttons. The trick is this procedure doesn't fit for this case, because its behaves different then developers expects. So insted of using this procedure i build radio group buttons manually. I also put simple onchange event for every input to save selected choice in every question. This event sets item in second column.
Each column is stored in collection APEX_APPLICATION.G_Fxx, where xx is between 01 and 50. There is p_idx parameter which determines index of collection for store column values. After page submit, APEX submit values in those collections. You can handle this, creating new process (Processing > Processes or Processing > After Submit) and pasting code below.
DECLARE
v_question_count NUMBER := APEX_APPLICATION.g_f01.COUNT;
v_question_answer_id QUESTION_ANSWERS.QUESTION_ANSWER_ID%TYPE := QUESTION_ANSWERS_SEQ.NEXTVAL;
BEGIN
FOR i IN 1..v_question_count LOOP
INSERT INTO QUESTION_ANSWERS (QUESTION_ANSWER_ID, QUESTION_ID, QUESTION_CHOICE_ID)
VALUES (v_question_answer_id, APEX_APPLICATION.g_f01(i), APEX_APPLICATION.g_f02(i));
END LOOP;
END;
There is another iteration through collections (both has the same number of members) and insert values into some table.
My code generates form without fancy styling, so you have to handle this yourself :)
Please take a look at the Survey Builder app, which allows users to review/preview/submit questions and answers.
This application can solve the requirement you have or give you an idea on how to build it.
You can find this application at App Gallery.

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")

Make condition only if "something" - Query Oracle

i'm with a problem in a query.
I have a table called "store" that I need to query.
Select s.store_name
from store s
where s.store = case
when p_store != 0 then
p_store
else
s.store
end;
This should work but as I have "stores" with characters (-) in column and this is defined as number, that query raise an exception: ORA-01722: invalid number.
So I want to do something like this in query:
IF p_store != 0 then
select store_name from store where store = p_store
else
select store_name from store;
Is it possible?
Thanks!
EDIT:
The query that I wrote above was an example of the query I was running.
The exception was raised because another column (too much hours in front of PC :-( ).
This table have a column that's varchar2(15) and I was doing this condition:
(...)AND S.CODE > 4 (...)
The correct condition that I want to do is:
(...)AND LENGTH(S.CODE) > 4
Thank you all!
As far as I understand you have varchar2 s.store which in fact contains numbers so Oracle tries to compare it casting to numbers but at some point it gets - and throws an exception. What you should do is update on table replacing - by null. But if you don't want to do that you can try to make case return varchar2
Select s.store_name
from store s
where s.store = case
when to_char(p_store) != '0' then
to_char(p_store)
else
s.store
end;
I am guessing you are running the query in a plsql block (as cursor?). In that case dynamic sql is the way to go. check out REF CURSOR too (google!).

Resources