Select row value from column in interactive report - oracle

Version: Oracle 18.2
I have an interactive report in my application. When I click the 'delete' icon, I want to delete information about the user I selected. Is there a way to get the value from the 'Facility Manager' column so I can use that value in a select statement to perform the delete statement.
I've tried to do it by using the ROW_ID variable (:selected_rowid) but this didn't work.
+ Interactive Report Image
+ Set Value statement

The column value is referenced by hashes, e.g. #STUDENT_ID#.
Have a look at what Jackie McIlroy wrote, "Delete a Row of a Report with a Dynamic Action" (https://jackiemcilroy.blogspot.com/2018/03/delete-row-of-report-with-dynamic-action.html) . She describes the process in details, with a lot of screenshots.
If I were you, I'd do one of the following:
use an interactive report with a form (and navigate to the form in order to delete a row)
if it has to be a tabular layout, I'd try
the old tabular form
the new interactive grid
I don't think I'd remove rows from the interactive report (but OK, that's just me, and my ideas usually aren't too smart).

Related

Oracle APEX - Initializing an Interactive Grid Column Using PL/SQL

I have an interactive grid in Apex that I'm trying to add a column that would have its values filled out using PL/SQL. I've added a column to the IG manually by right clicking on it in the page designer and clicking "Create Column". The issue I'm getting is I'm not seeing a way to have column initialized with the output of PL/SQL when I load the page. It seems like under the "Source" section after creating the column, there's only an option for using just SQL.
I've tried looking into dynamic actions for this, but I'm not seeing a way to set all the values in the column to a PL/SQL output when using the "Page Load" event. It seems like doing calculations on each row of a column is pretty straightforward using JavaScript, but I'm trying to port over numerous PL/SQL calculations into Apex so it would be preferable to do this without having to rewrite those scripts.
Is there a straightforward method to do this in Apex?

Make Specific rows not editable using Interactive Report

I am using Apex 18.2. I created an interactive report which has 10 records. I try to add a logic that user can only be able to edit those records which recently created. User cannot do an edit to an old records. Means when user try to edit old records, it show as 'Display only' or not editable. Is there any way I can do that? Your help is really appreciated. Thanks
One option is to create your own link (icon, if you wish), just like another column in report's query.
As you're in SQL now, use any condition you want. Obviously, you have to be able to distinguish "old" from "new" rows. If we suppose that it is some DATE datatype column, so whatever is "yesterday" or older is considered to be "old", you'd
select case when datum < trunc(sysdate) then null
else 'Click here'
end as link,
empno,
ename
from emp
LINK column's type would be "link" (of course) and you'd make it navigate to another page in this application, pass values from here to there, etc.

Making a search bar manually WITHOUT interactive report. (Oracle APEX)

I am trying to make an application completely manually without using any interactive reports or generated PL/SQL. Everything is working at the moment but I am stumped when it comes to the search bar and I can't find anything online to help me.
I have a classic report called 'Browse Job Vacancies' and a 'Search' button; I also have the 'C1_JOB_TITLE_ITEM' search bar and a page process called 'Search'.
In the process I have this code:
SELECT
JOB_CODE,
JOB_TITLE,
JOB_DESCRIPTION,
SITE_NAME,
EMAIL_ADDRESS,
TELEPHONE_NUMBER,
SALARY,
START_OF_PLACEMENT,
APPLICATION_METHOD,
APPLICATION_CLOSING_DATE
FROM JOB
WHERE upper(job_title) = upper(:C1_JOB_TITLE_ITEM);
I am getting this error:
ORA-06550: line 1, column 64: PLS-00428: an INTO clause is expected in this SELECT statement
So I created this code:
DECLARE temp_row char;
BEGIN
SELECT
JOB_CODE,
JOB_TITLE,
JOB_DESCRIPTION,
SITE_NAME,
EMAIL_ADDRESS,
TELEPHONE_NUMBER,
SALARY,
START_OF_PLACEMENT,
APPLICATION_METHOD,
APPLICATION_CLOSING_DATE
INTO temp_row
FROM JOB
WHERE job_title = :C1_JOB_TITLE_ITEM;
END;
Here I am getting this error:
ORA-06550: line 13, column 16: PL/SQL: ORA-00947: not enough values
I am completely stumped on what to do at this point so any help at all is greatly appreciated. Sorry if I'm not being detailed enough this is my first time writing in Stack Overflow.
(Editing because someone didn't think this was an answer.)
You say you have a page process. You don't need any sort of process for this. You should have a Region with the following properties (assuming 18.x):
Type = Classic Report
Source > Location = Local Database
Source > Type = SQL Query
Source > SQL Query > your query from your first block above
Apex will run the query and create a report based on it. Processes are for PL/SQL blocks that do something like populating data or manipulating the database in some way.
When you enter a keyword in your item and click your button (the button action should be Submit Page), Apex will populate C1_JOB_TITLE_ITEM in session state with the user's value, then use that in the bind variable when it re-generates the page.
1) Create a classic report with that SQL as the source code.
2) Set C1_JOB_TITLE_ITEM in Page Items To Submit attribute, just under region source.
3) Create the page item C1_JOB_TITLE_ITEM, as your search field.
4) Create a Dynamic Action on Change of that item, and refresh your classic report region. The timing of this refresh is up to you. Step 2 ensures the value you've typed in the browser is sent to the database for the purpose of re-running that query.
Do you have a function based index on upper(job_title)? Otherwise you may experience performance issues.

Oracle Forms 6i Resolve LOV code

I have a LOV with two columns one is code and the other is description. I know that text items have a property which says validate from list however my code field and description field are display items. We do not want to force the user to click on a button to show the LOV. In the pre-form trigger i am setting a default value in the code field.
I would like to get/resolve the code to its description from the list without having to do a select from the database. Does anyone know of a way to get this done?
I have had also this very same problem. There might not be a solution to retrieve the label column from record group in the runtime.
But you could do this:
Store the record group query somewhere (package header or DB column).
Populate your record group with query in the runtime.
Create DB function which takes query and key value as parameters. The function would then return description of the key value (use dynamic SQL, execute immediate / dbms_sql).
Use the function in the POST-QUERY trigger:
:block.item_description := your_new_function(l_query, :block.item_value);

Oracle Apex - Updating a view with instead-of trigger

Apex beginner here. I have a view in my Oracle database of the form:
create or replace view vw_awkward_view as
select unique tab1.some_column1,
tab2.some_column1,
tab2.some_column2,
tab2.some_column3
from table_1 tab1,
table_2 tab2
WHERE ....
I need the 'unique' clause on 'tab1.some_column1' because it has many entries in its underlying table. I also need to include 'tab1.some_column1' in my view because the rest of the data doesn't make much sense without it.
In Apex, I want to create a report on this view with a form for editing it (update only). I do NOT need to edit tab1.some_column1. Only the other columns in the view need to be editable. I can normally achieve this using an 'instead-of' trigger, but this doesn't look possible when the view contains a 'distinct', 'unique' or 'group by' clause.
If I try to update a row on this view I get the following error:
ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
How can I avoid this error? I want my 'instead-of' trigger to kick in and perform the update and I don't need to edit the column which has the 'unique' clause, so I think it should be possible to do this.
I think that you should be able to remove the "unique".
if tab2.some_column1, tab2.some_column2, tab2.some_column3 are not unique, then how do you want to update them ?
if they are unique then the whole result: tab1.some_column1, tab2.some_column1, tab2.some_column2, tab2.some_column3 is unique.
When you state in a sql query "unique" or "distinct" it's for all columns not only 'tab1.some_column1'
Hope i'm in the correct direction of your question here ;)
Your query could be achieved by doing something like:
select a.some_column1, tab2.some_column1, tab2.some_column2, tab2.some_column3
from table_2 tab2
join (select distinct some_column1 from table_1) a
on tab2.column_in_tab1 = a.some_column1
The reason you get the ORA-02014 error is because of the automatically generated ApplyMRU process. This process will attempt to lock a (the) changed row(s):
begin
for r in (select ...
from vw_awkward_view
where <your first defined PK column>= 'value for PK1'
for update nowait)
loop
null;
end loop;
end;
That's a bummer, and means you won't be able to use the generated process. You'll have to write your own process which does the updating.
For this, you'll have to use the F## arrays in apex_application.
If this sounds totally unfamiliar, take a look at:
Custom submit process, and on using the apex_application arrays.
Also, here is a how-to for apex from 2004 from Oracle itself. It still uses lots of htmldb references, but the gist of it is there.
(it might be a good idea to use the apex_item interface to build up your form, and have control over what is generated and what array it takes.)
What it comes down to is: loop over the array containing your items and do an UPDATE on your view with the submitted values.
Of course, you don't have locking this way, nor a way to prevent unnecessary updates.
Locking you can do yourself, with for example using the select for update method. You'd have to lock the correct rows in the table(s) you want to alter, before you update them. If the locking fails, then your process should fail.
As for the 'lost update' story: here you'd need to check the MD5-checksums. A checksum is generated from the editable columns in your form and put in the html-code. On submit, this checksum is then compared to a newly generated checksum from those same columns, but with values from the database at that time of submit. If the checksums differ, it means the record has changed between the page load and the page submit. Your process should fail because the record has been altered, and you don't want to have those overwritten. (if you go the apex_item way, then don't forget to include an MD5_CHECKSUM call (or MD5_HIDDEN).
Important note though: checksums generated by either using apex_item or simply the standard form functionality build up a string to be hashed. As you can see in apex_item.md5_hidden, checksums are generated using DBMS_OBFUSCATION_TOOLKIT.MD5.
You can get the checksum of the values in the DB in 2 ways: wwv_flow_item.md5 or using dbms_obfuscation.
However, what the documentation fails to mention is this: OTN Apex discussion on MD5 checksums. Pipes are added in the generated checksums! Don't forget this, or it'll blow up in your face and you'll be left wondering for days what the hell is wrong with it.
Example:
select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.md5(input_string=>
"COLUMN1" ||'|'||
"COLUMN2" ||'|'||
"COLUMN5" ||'|'||
"COLUMN7" ||'|'||
"COLUMN10" ||'|'||
"COLUMN12" ||'|'||
"COLUMN14" ||
'|||||||||||||||||||||||||||||||||||||||||||'
)) md5
from some_table
To get the checksum of a row of the some_table table, where columns 1,2,5,7,10,12,14 are editable!
In the end, this is how it should be structured:
loop over array
generate a checksum for the current value of the editable columns
from the database
compare this checksum with the submitted checksum
(apex_application.g_fcs if generated) if the checksums match,
proceed with update. If not, fail process here.
lock the correct records for updating. Specify nowait, and it
locking fails, fail the process
update your view with the submitted values. Your instead-of trigger
will fire. Be sure you use correct values for your update statement so that only this one record will be updated
Don't commit inbetween. It's either all or nothing.
I almost feel like i went overboard, and it might feel like it is all a bit much, but when you know the pitfalls it's actually not so hard to pull this custom process off! It was very knowledgable for me to play with it :p
The answer by Tom is a correct way of dealing with ths issue but I think overkill for your requirements if I understand correctly.
The easiest way may be to create a form on the table you want to edit. Then have the report edit link take the user to this form which will only update the needed columns from the one table. If you need the value of the column from the other table displayed it is simple when you create the link to pass this value to the form which can contain a display only item to show this.

Resources