5

I am currently working in Oracle Application Express 18.1.0.00.45 and I am getting an error that I do not understand.

I created an interactive grid using the following query:

select periodic_topics_id, filter, topic,
CASE 
WHEN LINK1 like '%116%' then LINK1||:APP_SESSION 
ELSE LINK1
END AS LINK1
From periodic_topics
where meeting like :P31_MEETING_DESC
and
(nvl(:P31_FILTER,'0') = '0' or instr(:P31_FILTER||':',filter||':') > 0) 

In the table in the database, the periodic_topics_id column is the primary key and it is automatically populated when a new row is added to the table using the following trigger:

create or replace TRIGGER periodic_topics_trigger
BEFORE INSERT ON periodic_topics
FOR EACH ROW
BEGIN
:new.periodic_topics_id := periodic_topics_seq.nextval;
END;

In the APEX application, link1 is a textfield and in the "Link" section of this column's properties, the "Target" is of type URL and the URL is &LINK1. I also indicated in the APEX application that periodic_topics_id is the primary key. These are the properties of the link column that I am referring to:

enter image description here

The problem: when I manually insert a value into a cell in the "LINK1" column of the interactive grid, an error is raised that says:

"•Ajax call returned server error ORA-20987: APEX - Process 'Periodic Topics - Save Interactive Grid Data' raised 'ORA-01733: virtual column not allowed here' while executing a DML command. This error can occur if a column is based on an aggregation or SQL expression. Set column attribute 'Query Only' to Yes to exclude the column from the INSERT and UPDATE statement. - Contact your application administrator. for ."

However, if I create the interactive grid using the same query but without the case statement, then I have no problem adding a link in the interactive grid. No error occurs. In other words, no error occurs when I try to add a value to the "Link1" column in the interactive grid if I create the interactive grid using the following query:

select periodic_topics_id, filter, topic, link1
From periodic_topics
where meeting like :P31_MEETING_DESC
and
(nvl(:P31_FILTER,'0') = '0' or instr(:P31_FILTER||':',filter||':') > 0)

Just FYI, I need the query to have the case statement because some of the links will direct the user to external websites and others will direct the user to another page in the application. Without the case statement concatenating :APP_SESSION to the link, the user is forced to log back in to the application whenever they click on a link that directs them to another page in the application.

Does anyone know why the error would occur when the case statement is in the query but not when the case statement isn't in the query?

Thank you in advance.

Katherine Reed
  • 301
  • 1
  • 7
  • 20
  • I try to test something like that in apex.oracle.com but I have a problem to create a IG with a case statement. but if you can create... did you try to set the attribute "query only" to "yes" in this column of your IG? – romeuBraga Aug 24 '18 at 17:39
  • Thank you for your response. I tried setting the attribute "query only" to "yes" for the Link column, but when I did that I was not able to edit the Link column in the interactive grid. Meaning, I couldn't manually enter a new URL value into the Link column in the interactive grid because it was set to "query only", so it was excluded from insert and update statements. I will work on creating a test application so that you and others can see the error. – Katherine Reed Aug 24 '18 at 18:26
  • I would just like to add, this was such as well written question. Thank you. – Scott Aug 26 '18 at 23:46

1 Answers1

4

The way I see it, this is a known issue which dates back from tabular forms (TF) (while interactive grid (IG) is its advanced version). As far as I can tell, you couldn't / can't create a TF/IG using a query with joins or fabricated columns - the one you created using CASE. Why? Because Apex has difficulties in knowing how to manipulate such a data.

Joins are commonly used in situations like Scott's EMP table, when you want to display DEPTNO along with department name (DNAME), but it is stored in DEPT table. Join is a natural choice, but it won't work. Solution is to create a function which returns such a value. And, of course, it can't be enterable.

Similarly, in your case, you actually can use CASE, but you'll have to set it to "query only" (as suggested) and use it for display purposes. Then you have to have the "original" LINK (database) column which will be enterable.

Basically, layout would look like this:

PERIODIC_TOPICS_ID  FILTER  TOPIC  LINK  LINK_DESCRIPTION
------------------  ------  -----  ----  -------------------------
<-------  enterable columns  --------->  <- your CASE construct ->

Users would click the LINK_DESCRIPTION column which will take them to URL, while you'd use LINK to enter/update that column's value.

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
  • Thank you for your detailed response and advice about how to handle this problem! – Katherine Reed Aug 27 '18 at 01:54
  • Someone suggested this solution and I thought you may find it interesting. Write the query without the case statement (the 2nd query in my question). Manually add a column to the grid in the Page Designer on the APEX page. Name the column LINK_SESSION, type is hidden, source type SQL Expression, and the query is "case when link1 like '%116%' then :app_session else null end". Change the Target on the LINK1 column to &LINK1.&LINK_SESSION. The query will raise an error but you can still save and run the page and add URLs to the LINK1 column the way I was trying to do. @romeubraga – Katherine Reed Aug 28 '18 at 13:41
  • Thank you, Katherine. It is nice you managed to find another way to solve the problem and share it with the community. – Littlefoot Aug 28 '18 at 14:16