Oracle : Execute Query with LOV selected value - oracle

I need to run a query with a value that is selected from a LOV.
I've got the next setup :
a block named "MENIU"
a table named "MENIU" with a column "ID_MENIU".
a LOV named "LOV_MENIURI"
a parameter named P_IDMENIU
a button on the form named "Alegeti Meniul"
In order to run a query with the value selected from the LOV I've tried this :
LOV return item "ID_MENIU" is set to PARAMETER.P_IDMENIU
in the pre-query of block MENIU I've assigned the PARAMETER.P_IDMENIU value to MENIU.ID_MENIU
Button "Alegeti Meniul" has the next "when-button-pressed" trigger code :
declare
success boolean;
begin
Enter_Query;
success := show_lov('LOV_MENIURI');
Execute_Query;
end;
My problem is that when pressing the button for the first time nothing happens, if I press the button a second time LOV window appears and the query is executed twice.
A GIF with the outcome:

You don't need that enter_query call.
begin
if show_lov('LOV_MENIURI') then
execute_query;
end if;
end;
When calling the execute_query built-in you'll fire the pre-query trigger, setting the where clause using the value returned by the LOV.

Related

List of Values PL/SQL function body returning sql query in APEX not reading item values

i have this PL/SQL function
declare
v_sql varchar2(222);
s1 real;
s2 real;
p67_price real;
p67_type_project real;
begin
p67_price:=:p67_price;
p67_type_project:=:p67_type_projet;
select :limit_1_type_project into s1 from type_project where id_type_project=p67_type_project;
select :limit_2_type_project into s2 from type_project where id_type_project=p67_type_project;
if p67_price>=s1 then
v_sql:='select label_mode_pass, id_mode_pass from mode where id_mode_pass<4';
return v_sql;
end if;
if p67_price<s1 and p67_price>=s2 then
v_sql:='select label_mode_pass, id_mode_pass from mode where id_mode_pass=3 or id_mode_pass=2';
return v_sql;
end if;
if p67_price<s2 then
v_sql:='select label_mode_pass, id_mode_pass from mode where id_mode_pass<5';
return v_sql;
end if;
end;
that i tested and it works fine when both :p67_price and :p67_type_projet are given numeric values for example :
p67_price:=15000000;
p67_type_project:=2;
the problem is it won't work otherwise and the APEX compiler show this error message ORA-01403: no data found.
is it not possible to include region item's data in the list of values or is there another problem i am not seeing?
NO DATA FOUND means that one of SELECT statements didn't return anything because there's no row which satisfies WHERE condition.
If code you wrote works for values you mentioned (15000000 / 2) but not for other values, then you'll have to handle it somehow:
one option is to make sure to provide only valid values for price and type_project
another is to review where clauses; maybe you coded it wrong
the most obvious is to include the exception handling section; it begins with the exception keyword and ... well, handles the error. For example:
declare
s1 ...
s2 ...
begin
select ... into ... from ... where ...; --> this is SELECT which might raise the error
<do stuff if SELECT succeeds>
-- this is what you need
exception
when no_data_found then
-- handle it; this is just an example, you should know what to do
s1 := 0;
s2 := 0;
end;
Also, make sure that P67_ items you use in that code are stored into session state. One way to do that is to submit the page (by pressing a button). Or, if it is a list of values, you can use those P67_ items as parent items in cascading list of values, or submit their values (you'll find both properties in LoV items' property palette).
If you wonder "how come 15000000 / 2 combination works?", it might be because you did put those values into session state previously, and it stays so during your session. If you log off and log in again, their values will be lost and - I presume - your code won't work any more, at least not until those values enter session state again.
i found a solution to my problem, instead of
p67_price:=:p67_price;
i used
p67_price:=V('p67_price');
and of course i had to add this piece of code at the end
exception
when no_data_found then
v_sql:='select label_mode_pass, id_mode_pass from mode';
return v_sql;

Oracle Forms If List of Values Contain No Entries Show Message

I have a button and this code in WHEN-BUTTON-PRESSED trigger of button. When I press button, show a LOV. And LOV's query gets result depends on user who press button. I want to show specific message like 'You have no authorization' if list of value gets no entries. But I get error message "FRM-41830: List of Values contains no entries". What can I do?
DECLARE
A BOOLEAN;
BEGIN
A := SHOW_LOV ('LIST_OF_VALUE');
SET_BLOCK_PROPERTY (...);
GO_BLOCK ('...');
EXECUTE_QUERY ();
:SYSTEM.message_level := 25;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
MESSAGE ('You have no authorization');
:SYSTEM.message_level := 0;
END;
there is no relation with lov and exception . Please check the lov query and try to get the count if count is greater than 0 then show lov if not display message.
There is nothing in your code that would raise a NO_DATA_FOUND exception. However, if the record group underlying the LOV called by SHOW_LOV contains 0 records, the BOOLEAN return value for SHOW_LOV will be FALSE. You can try to trap that, or possibly put an ON-ERROR trigger on the button to trap the "FRM-41830: List of Values contains no entries" error and return your customized message there.

How can I apply condition to Insert data in Oracle Forms 6i

I have table DOC_CUST_PRODUCT (DOC_CODE, CUST_CODE, P_CODE)
I want to restrict insertion and show message when DOC_CODE has more than 5 different CUST_CODE
SELECT COUNT(DISTINCT CUST_CODE)
INTO Y
FROM BP_DOC_CUST_PRODUCT
WHERE DOC_CODE = :DOC_CODE;
IF NVL(Y,0) > 4 THEN
MESSAGE('Sorry, Can Not Entry More Than 5 Chemist...');
MESSAGE('Sorry, Can Not Entry More Than 5 Chemist...');
but it doesn't work.
Where did you put that code? Should be WHEN-VALIDATE-ITEM trigger on DOC_CODE item.
If there are two (or more) items named DOC_CODE, Forms doesn't know which one you're referencing - I suggest you to always specify block name with the item name.
Code you posted isn't complete - variable declaration is missing, IF doesn't have an END IF. I don't know whether you really didn't do that, or you just didn't post everything you wrote (by the way, how are we supposed to know that?).
COUNT function can't return NULL as a result, so applying NVL to the variable Y is superfluous.
The following code should be OK (if you fix what's missing - a block name).
-- WHEN-VALIDATE-ITEM trigger on :BLOCK_NAME.DOC_CODE item
declare
l_count number;
begin
select count(distinct b.cust_code)
into l_count
from bp_doc_cust_product b
where b.doc_code = :block_name.doc_code;
if l_count = 5 then
message('Sorry, ...');
message('Sorry, ...');
end if;
end;
You could achieve this by adding a post-query trigger to your block. If the count returns more than 5 elements, just change the ENABLE property of your item to disable it otherwise enable it.
To display your message before inserting a new record, you can also use an 'pre-insert' trigger on your block and check the result of the count, then display your message :
IF EL_COUNT > 5 THEN
Message('Sorry, Can Not Entry More Than 5 Chemist...');
RAISE Form_trigger_Failure;
END IF;

PL/SQL Dynamic action [Set Value] not recognizing apex item value

I have a problem setting the value of an apex item (P13_3) using a pl/sql defined dynamic action. At the moment the dynamic action is triggered using a button. For example if "530000000019" is entered into the item (P13_3), after the clicking the button it should return a value (Product Code) and set the item with that value.
This is the pl/sql code that runs when the button is clicked:
DECLARE
p_code products.prod_code%TYPE;
p_id products.prod_id%TYPE;
BEGIN
p_id := :P13_2;
SELECT prod_code INTO p_code FROM products WHERE prod_id = p_id;
RETURN p_code;
END;
This is the error that appears:
Ajax call returned server error ORA-01403: no data found for Set Value.
This means that no data was returned when the SELECT INTO clause ran. I then altered the code and ran this code to see if there were any faults in the code:
DECLARE
p_code products.prod_code%TYPE;
p_id products.prod_id%TYPE;
BEGIN
p_id := 530000000019;
SELECT prod_code INTO p_code FROM products WHERE prod_id = p_id;
RETURN p_code;
END;
This code returned a value and the set value dynamic action was successful. This therefore means, that in apex was not picking up the value in the P13_3 item.
I have a apex process that has similar syntax that calls the P13_3 apex item and it runs successfully. Here is the code of the apex process:
DECLARE
b_code products.prod_id%TYPE := :P13_3;
p_quant products.prod_qnty%TYPE := :P13_2;
BEGIN
UPDATE products
SET prod_qnty = prod_qnty - p_quant
WHERE prod_id = b_code;
END;
If I am not mistaken, I would say that this proves that the problem lies with dynamic action and not the pl/sql code. I am currently using apex 5.1 (The 16 Dec release). Please Help. Thank you in advance :)
I have tried similar work ,I have created two text boxes one for input & another for output & I am getting expected result .Please check following screen shots of result & dynamic action settings
And dynamic action settings is as follows :
Edit view of True action is as follows :
Hope this will help you.

How can I revert changes to a record in Oracle Forms 6i?

I have a form running in Oracle Forms 6i which has tabular formatted rows that are being populated from a certain table in the database. One column has a [List_Of_Values] property enabled to allow the user to select among possible values.
Some values among the list can only be selected if the user has permission to do that, and I have created a [ WHEN-VALIDATE-ITEM ] trigger to check the permission after the value has been changed. The trigger raises a form_trigger_failure to prevent the user from saving the changes done.
The problem is that if the user gets notified about lack of permission to select the value, then there is no way for the user to know the previous (old) value to select it again, unless the form is cancelled which will cause his other (valid) changes to be lost too.
Here is the code I have written in the trigger
DECLARE
NEW_LOCATION VARCHAR2(100);
BEGIN
NEW_LOCATION := :BLK_MAT_STG_PLACES_PILE.STG_LOC_ID;
IF NEW_LOCATION LIKE 'OH01%' THEN
IF NOT :GLOBAL.USER_ID LIKE 'Admin%' THEN
MESSAGEBOX('You are not authorized to select this value');
/* What can I write to load the old value to this item? */
RAISE FORM_TRIGGER_FAILURE;
END IF;
END IF;
END;
I have tried ROLLBACK but that did not revert the old value to the form. I tried SYNCHRONIZE as well, but that had no effect. Is there any option other than going through the database table again to pull out the value?
BEGIN
IF NEW_LOCATION LIKE 'OH01%' THEN
IF NOT :GLOBAL.USER_ID LIKE 'Admin%' THEN
MESSAGEBOX('You are not authorized to select this value');
/* Return it to the original value that was fetched from database */
:BLK_MAT_STG_PLACES_PILE.STG_LOC_ID :=
get_item_property('BLK_MAT_STG_PLACES_PILE.STG_LOC_ID'
,DATABASE_VALUE);
RAISE FORM_TRIGGER_FAILURE;
END IF;
END IF;
END;
One of my colleagues found the solution to this problem as follows:
Define a Global Parameter in the parameter list (I named it TEMP_LOCATION)
In the PRE-TEXT-ITEM trigger (which is executed before navigating to the item) I wrote
BEGIN
:GLOBAL.TEMP_LOCATION := :BLK_MAT_STG_PLACES_PILE.STG_LOC_ID;
END;
3 Then in the WHEN-VALIDATE-ITEM trigger code that I wrote in this question, I cancelled raising FORM_TRIGGER_FAILURE and simply filled the item with the TEMP_LOCATION
DECLARE
NEW_LOC VARCHAR2(100);
BEGIN
NEW_LOC := :BLK_MAT_STG_PLACES_PILE.STG_LOC_ID;
IF NEW_LOC LIKE 'OH01%' THEN
IF NOT :GLOBAL.USER_ID LIKE 'Admin_%' THEN
MESSAGE('YOU ARE NOT AUTHORIZED TO SELECT THIS VALUE');
:BLK_MAT_STG_PLACES_PILE.STG_LOC_ID := :GLOBAL.TEMP_LOCATION;
/* this solved my problem */
END IF;
END IF;
END;
I thank all of those who tried to help. If someone comes up with a better answer than my own, then I will happily accept it.

Resources