Oracle Forms: have a specific column on some rows not store a value in the database? - oracle

Requirements
Here are the simplified requirements. The end goal is to be able to display data about an item, or print labels using the saved data. The solution is being created in Oracle Forms Builder
Attribute Definition form
Designed to define attributes.
Attribute configuration details are stored in an attribute
definition table
Attributes can be either a manually entered
values, or SQL driven
SQL Example: Case Weight (uses the Item's
Case UOM conversion rate multiplied by the item's unit weight)
Manual Example: Color of item
When SQL driven, a select statement is saved in the attribute configuration
Tokens like :INVENTORY_ITEM_ID are used in the SQL, and will be replaced with
values by the form when the SQL is evaluate.
Item Attribute Assignment form
Designed to link attributes to an item
Form includes a list of attributes assigned to an item
Records that link the attribute to the item are saved in the
database
Records store the attribute ID, Item ID and the attribute
value (if applicable)
List should be in a single block.
The form
allows additional assignments of attributes (which defined in first
form)
Items can have SQL and Manual type attributes assigned to
them.
Form allows "manual" values to be updated at any time by the
user
Form derives SQL values, displays them in the "value" field,
but the value field should be disabled so the user can't edit it.
Upon querying an item or assigning a new attribute
SQL values should be derived/evaluated
Manual entered values should be pulled
from the tables "value" column
Problem
We don’t want the form to save the SQL derived values to the table.
Is there a way to have a specific column on some rows not store a value in the database? These would be the rows that contain the SQL derived values, which are displayed in the disabled value cell, and derived when an item is queried, or an attributes is assigned.

It is possible, but you really should implement table handlers for your Forms, rather than relying on Oracle Forms to do your DML for you.
By "implement table handlers", I mean, set the block's "DML Data Target Type" property to "Use Transactional Triggers".
Then, code the ON-INSERT, ON-UPDATE, etc triggers for your block to call PL/SQL (passing in the appropriate values to insert, update, etc from your block).
In your PL/SQL, you can insert each column exactly where and how you want it, or don't insert a column at all, which is what you're after here.
If you are using the Oracle e-Business Suite, this is documented in the Oracle Applications Developer's Guide, chapter 10 ("Using PL/SQL in Oracle E-Business Suite: Coding Item, Event, and Table Handlers").

Related

How to use Oracle APEX dynamic action to populate a 'form on a table' field on the basis of other fields and underlying sequence?

I am implementing a 'form on a table' that will allow the end-user to create records in the database. I would like to generate the primary key for the underlying table based on the selections the user makes as well as the underlying sequence.
The basic formula for the primary key should be a concatenation of the 'disposal site code' + 'year of study' + str(sequence). The sequence is should start at and increment by 1 so that the first project created in the database end with -1 and the nth with -n.
For example if the user selects the 'Disposal Site' as 'Seldom', the field 'Disposal Site Code' should be dynamically populated by 'CA-AT-D130' (a 1:1 code alphanumerical code for each site) and after selecting the year, for example 2022, the project number would dynamically be populated as CA-AT-D130-2022-01 (assuming first entry in the table). After creating the new record CA-AT-D130-2022-01 would become the 'project number'.
Can anyone recommend the idiomatic way to do this in APEX? I have a feeling what I am needlessly complicated something that should be relatively straightforward.
There are 2 ways of doing this that are a lot simpler than what you are trying. There is no reason at all to use a dynamic action, this can just be done using apex page processing.
option 1: in the database: Create an trigger on the table that sets the primary key column based on the other column values & sequence
option 2: in apex: Create an after submit computation on the page item to compute the value based on the other page item values & the sequence.
option 3: what I would do instead:
In my personal opinion this isn't a good option for a primary key. The primary key should just be a unique row identifier with no business value. Just use an identity column for that and no additional work is needed in db or apex.
Sounds like you want to capture business information in the key. Well... make that a "pseudo-primary key" and store that information in a column with a unique index in your database. Or, use a virtual column in your table that calculates this value from the primary key column and the other columns you need.

Form WHERE clause

I have an APEX form I'm developing for "user settings". I have a table with a sequence as a primary key and the users ID in another column...in addition to a few columns where each users saved settings are stored (things like "N" for do not receive notices).
I haven't used Oracle APEX in a while so excuse this likely newbie question...The insert works fine, but I'm having trouble with making the form only show the current users values. In my Form Region the source is set to my Table, and I have a WHERE clause like this:
USER_ID = 813309
But that's not working (813309 is my id and I'm just hard-coding it for now). The form always comes up with a "New" record.
For a form to load a specific record you can set the primary key page item to the value you need. You can do so in the url using the link builder from another page or you can set a computation on the item. That is what I would try in your case: add a computation to your item P_USER_ID of type "Static Value" with value 813309. Make sure the computation happens before the "Fetch Row" - the value obviously needs to be set before the process runs.
In such cases, I prefer creating a Report + Form combination (using the Wizard, of course): it creates an interactive report (so that you can review data in a table), and a form which is used to add new records or update/delete existing ones.
Doing so, when you pick a user in interactive report and click the icon at the beginning of a row, Apex redirects you to the form page, passing primary key column value to the form which then fetches appropriate data from the table.
Not that it won't work the way you're trying to do it, it's just simpler if you let Apex do everything for you.
So: did you create an automatic row fetch pre-rendering process? If not, do so because - without it - Apex doesn't know what to fetch. Also, if you hardcoded user_id, it won't do much good. Consider storing username into the table so that you could reference it via :APP_USER Apex variable.

HOW TO INSERT RECORD IN DATA BLOCK ON ORACLE FORMS

I have oracle form which contains data block B_ITEM which refers database table master_item. The User is entering two items in one bill manually in data block and based on certain conditions I need to add freight item in same block B_ITEM automatically. could you please guide how to insert data in data block. (Note:I don't want to insert directly in table which it refers)
Step-1 Created a canvas on date block on B_ITEM where user can give provide input. Block
contains field item from master_item table.
Step-2 Lets Say, User entered two items on canvas which refers B_ITEM and click on ok button.
Step-3 So along with two items, one more item should get inserted in block B_ITEM and it should display on canvas on 3rd line.
In the above image, I have shown example of single item, so once user clicks on OK button 2nd item should get added based on setup table.
MASTER_FREIGHT_LINK
ITEM FREIGHT_ITEM
101396306 101396307
So, In canvas freight item should added on second row as soon as user click on OK button by entering ITEM-101396306.
I don't quite understand what you have, so - let me think aloud.
there's a table in the database, called MASTER_ITEM
you created a form whose block B_ITEM is based on the MASTER_ITEM table
data block contains some items which are, I presume, database items (that belong to the MASTER_ITEM table)
you enter some data into those items
based on their values (i.e. a certain condition), you'd want to populate FREIGHT_ITEM which resides in the same block, but is not a database item. Is that correct?
If that's so,
create the FREIGHT_ITEM (there are several ways to do that; a simple one is to use the vertical toolbar's + button; or, copy/paste one of existing items and modify its properties)
create WHEN-VALIDATE-ITEM trigger on items that should decide which value should be put into the FREIGHT_ITEM. Put the condition you mentioned into the trigger code and populate FREIGHT_ITEM's value, e.g.
if :b_item.item1 > 100 and
:b_item.item2 = 'A'
then
:b_item.freight_item := 42;
end if;
Now, as you said that you don't want to store that value into the database directly (which means that it is not a database item), you'll have to do it manually, creating additional ON-INSERT and/or PRE-INSERT and/or PRE-UPDATE trigger, which will do that as
update master_item i set
i.freight_item = :b_item.freight_item
where i.some_id = :b_item.some_id;
ON-INSERT trigger can be used to override oracle forms insert mechanism. Write in the on-insert trigger the insert statements necessary, which can insert data on any table.

Oracle forms hybrid validation

This is my first post ever and haven't come across any other questions related to this. I am attempting to try and create a hybrid validation type and add it to an existing oracle form. We have a super/subset type of thing going on. When one chooses something from a dropdown, there are 5 options. If 4 of those options are chosen, the data is pulled from one validation table dataset, table A. If the other option is chosen, it comes from a different table's dataset, table B. These (along with others items) are saved in Table C. Table C has a FK constraint regarding these validations. I have added another column to table C to attempt to bypass the FK constraint, but the field still tries to save in the FK column. I can't seem to figure out if I need to add a database trigger, an item level trigger, or a form level trigger to reroute the data to correct columns in the database. Thanks in advance for any help!
If your items are select lists, you would use an item level trigger (when-validate-item) on the superset list item to populate/repopulate the list for the subset item.
Alternatively, you could use a popup LOV on the subset item which has a query which is filtered by the value of the superset item.

TableAdapter to return ONLY selected columns? (VS2008)

(VS2008) I'm trying to configure a TableAdapter in a Typed DataSet to return only a certain subset of columns from the main schema of the table on which it is based, but it always returns the entire schema (all columns) with blank values in the columns I have omitted.
The TableAdpater has the default Fill and GetData() methods that come from the wizard, which contain every column in the table, which is fine. I then added a new parameterized query method called GetActiveJobsByCustNo(CustNo), and I only included a few columns in the SQL query that I actually want to be in this table view.
But, again, it returns all the columns in the master table schema, with empty values for the columns I omitted.
The reason I am wanting this, is so I can just get a few columns back to use that table view with AutoGenerateColumns in an ASP.NET GridView. With it giving me back EVERY column i nthe schema, my presentation GridView contains way more columns that I want to show th user. And, I want to avoid have to declare the columns in the GridView.
When you add a new query to a given TableAdapter, it is going to assume the schema in which it is attached to, which is why you are getting blank values for the columns you don't want.
Since you mentioned having already created the procedure, what you need to do is use the Server Explorer to connect to the database and simply drag that stored procedure over into your XSD work area. What this will do is create a separate QueryAdapter that will have just the columns you specified (still strongly typed) and you can bind/interact with your GridView using that QueryAdapter instead.
Is the strongly typed dataset used in another query that returns all the rows from the table?
What you could do is create a dataview using the strongly typed dataset and expose a data table for your DataGridView.
I'm not sure what your requirements are totally, but this example should help you:
DataView dv = new DataView(ds.<Your_Table>);
// This will create a new data table with the same name,
// But with only two columns from the original table.
// This could then be bound to your data grid.
DataTable dt = dv.ToTable(false,
ds.<Your_Table>.<Your_Column1Column>.ColumnName,
ds.<Your_Table>.<Your_Column1Column>.ColumnName);
Just delete the columns you don't want at run-time before you bind to your Gridview. The underlying class is still just a DataTable after all.

Resources