How to update records form a from whose data source is set to view in Oracle Apex? - sql

My oracle apex application has an events page that has a v_event view as its data source. This view contains all the column that an event table contains plus it also has club_name column that holds the name of the organizing club. The report displays correctly as I want it for now.
When I try to update a record I get an error saying 'data manipulation operation not legal on this view'
This must be because the data source for the page is a view. How can I solve this problem ?
Also when I try to create new events I get an error:
First I thought that the '... non key-preserved table' occurred because the relationship between event and club_event(junction table between club and event) table was one to many and same event row was repeating multiple times if there were multiple clubs organizing it. So to solve this issue I "LISTAGG" clause to combine multiple club names for a single event in a single row using comma separation as you can see in the second row of the first image above. But it didn't solve the issue. What am I doing wrong?
By the way the entire page is a "report with form" that oracle apex provides. So I am able solve this problem by create a new page and setting its data source to event table. But I just wanted to learn if there is a way that I can create a new event through the view table.
Also one final question. How can I map the values in 'From College' and 'From Community' column in the first image to be "yes" if the value in the table is 1 and "no" is the value is 0 ?
Thank you.

As far as I remember, there are several tables involved here. Even if it weren't for Apex, the answer is to create an instead of trigger which fires when view is updated, and then trigger body decides which tables are updated and how.
In Apex, you could - additionally - try to write your own processes that handle inserts, updates and deletes. In other words, don't use automatic row processing as it won't work, but create your processes.
As of mapping 1/0 to "yes/no":
in (interactive) report, use CASE (or DECODE)
in form, either create radio button or select list item

The view needs to have a 1:1 mapping to the table and the column that has the "LISTAGG" should have the attribute "Source > Query Only" set to "On".

Related

vb.net dataview grid won't add record and doesn't update after data is modified independently

I have a dataview grid bound to a datasource at run time. The datasource is filled from an access database via a DataAdapter. The data fills and displays correctly, and updates to existing rows seem to work OK but I have two problems:
When I type something in a new row and then press return or switch to a different row, I want the DataAdapter to add that row then and there to the database so I can retrieve the Autonumber index of the new record from Access and use that to add an associated record in a different table (Entries, a many to many linking table). This isn't happening. In the RowLeave event I have adapter.Update(dsSentences) and then I check for the new row, but the RowCount doesn't reflect its presence even though the newly added data is visible in the grid, and the adapter.Update doesn't seem to have triggered the Insert query that I specified in the DataAdapter. So nothing is added.
(edit: OK, so the new row has not yet been added when this event is fired. Which event should I then use to commit the data and retrieve the Autonumber primary key for my new record? I've tried UserAddedRow but that one fires before you've entered any data into the new row.)
THe second problem is that I need to update the data independently and then have the grid reflect those changes. How do I do that? Is there some call that will force the grid to get the updated data from the DataAdapter via the Dataset? Any help would be much appreciated. I'm almost ready to dtop the whole idea of binding data and do it all through code, Data binfing is supposed to save time but I'm finding it labyrinthine and unpredictable.
FWIW here's the query I'm using to fill the grid:
PARAMETERS nIdCollection Long;
SELECT tblSentences.IdSentence, tblSentences.SentenceText, tblSentences.SentenceParsed, Not IsNull([tblSentences]![SentenceParsed]) AS HasParsed, Entries.IdEntry
FROM tblSentences INNER JOIN Entries ON tblSentences.IdSentence = Entries.IdSentence
WHERE (((Entries.IdCollection)=[nIdCollection]))
ORDER BY Entries.SortValue;
As you can see, it requires a record in Entries. After I've entered a new record in tblSentences, before there are any entries the IdEntry will be null assuming it shows up at all. That's why I need to intercept directly after the Insert, add the record to Entries and requery to keep everything in order. You could do it all in an SQL stored procedure but I have to use Access.
Edit: After a lot of googling I've come to the conclusion that what I'm trying to do = add a record to a table through an additional INSERT query apart from the one handled by the DataAdapter, every time a new row is added - simply can't be done if you are using data binding. I am going to have to delete all my code and start from scratch populating the grid through code (unbound). I think it's the only way to do what I want. I will leave this here as a warning to anyone else not to make my mistake of trying to use Data binding when your data is coming from more than one table. Bad mistake.

How to get the values of a checkbox in after trigger in PL/SQL?

I have a form for creating new events in Oracle Apex. With that form I am able to create new events just fine. But at the bottom of that form is a checkbox where the user will specify the clubs that are involved in organizing the event.
The list of values for the checkbox which you can see at the bottom of the image above is set to a sql query which selects 'club_name' and 'club_id' from 'club' table.
Now what i want to do is after the events gets successfully created, the club_id of the checked clubs with the id of the newly created event needs to be inserted into the 'club_event' junction table which related each event with their organizing club. So for that I thought of creating after trigger on events table. But I couldn't find how can I access the id's of the club selected in the plsql code. So my question is how my I do so and is my approach for relating event with organizing club fine? Thank you.
With the suggestiong from "Koen" I tried to I tries to implement it through "Process". But I am having problem in making my script work.
DECLARE
type idarray IS VARRAY(10) OF VARCHAR2(10);
ids idarray;
BEGIN
ids := apex_string.split(:P72_CLUBS, ':');
FOR id IN ids LOOP
INSERT INTO club_event
VALUES(id, P72_EVENT_ID);
END LOOP;
END;
What are the things that I am doing wrong and how may I resolve it?
You don't need a trigger for that. Use a page process instead. The values of the page item (I assume that is P1_CLUB) will be passed on page submit as a colon separated list of return values (in your case club_id). Use apex_string.split to convert the colon separated list to a pl/sql array . Loop through the array and insert/update/delete the records in/from the clubs table .
In addition to Koen's answer, if you want to view the event and also want to populate the checkbox with the checked values, you will have to set the following attributes for the checkbox page item:
Source - Type = SQL Query (return colon separated value)
SQL Query = select club_id from my_club_to_event_table where event_id = :P1_EVENT_ID
Used = Always, replacing any existing value in session state
Assuming P1_EVENT_ID is the primary key page item on that page.

SSRS SQL report builder deleting column

I have a problem with SSRS report builder. Basically what I want to do is to delete a column. I have a report that someone else made and there is 1 column (xxx) that no longer exists in data source tables so I need to delete it.
When I go to query designer and delete this column from the code and run it there, it works. I close query designer window and see that list of columns (fields) is updated now and xxx column is not there. Then, I delete this column manually in designer (default screen) and when I try to run the report, It doesn't work:
"The Value expression for the text box ‘XXXDataField’ refers to the field ‘xxx’. Report item expressions can only refer to fields within the current dataset scope or, if inside an aggregate, the specified dataset scope. Letters in the names of fields must use the correct case."
But that field should be already deleted. So I don't know what else I can do, or what it can be linked to. I just want to delete it. Any Idea?
Thank you
If your dataset does not contain xxx but your DataTable has this error is normal
You either delete that column from your table or at lease delete DataSet Binding from table so that SSRS does not try to retrieve that column from DataSet
It will be a reference to the field in another field. For example, if you deleted a column that showed an OrderShipped status, then you might have another text box highlighted based on this.
The error is telling you which textbox is in error. So, click somewhere on the designer, then in the properties window, right at the top, click the dropdown which allows you to choose specific report items, choose XXXDataField (the one named in the error message) and then check the value expression. In there you will find the reference to the column you deleted.

VBA access and forms

I created a database in Access and there are some type of records in some tables that requires a particular inserting, so I decided to use VBA to handle this.
The problem is that if i create a form with some controls which i want to refer and use their values as criteria for queries, the form is still a way to insert data. So the query works but the data i inserted are added directly from the form too, creating duplicates.
The question is, is there a way to create a form that has controls only for text input but does nothing to record , leaving inserting, deleting , updating all to queries in VBA?
I tried to put "no" on propriety "add records" in the form but it gets totally blank with no controls.
Your form must be unbound, i.e. its RecordSource must be empty.
Your form can be bound or not bound to a table / query.
This means that the controls on your form may be bound to a field of that table / query.
But you can also have controls in the same form which are not bound.
Example:
You can make a form in which the body has a list view of the records of the table. In this section the controls would be bound to a field.
In the header of the table instead you may have controls that are not bound and that could be used either to filter the records shown or to add new records. You may want to add records this way rather than let users insert data directly in order to add checks or do any other kind of processing before actually adding the data in a new record.

Refreshing values in a TClientDataset after update

I got a TClientDataset that contains data from several tables. When I apply updates on this dataset it might get out of sync.
I'll give you one example:
In the table to update i got an id called "Client_id". The clientdataset also contains a value "Client_name" that is fetched from a "Client" table and displayed in the GUI.
Then I change the "Client_id" in my table and do an apply updates on the table the "Client_name" field in my dataset suddenly is out of sync. This is naturally because the clientdataset has not been refreshed.
Now I could do a clientdataet.refresh on the afterpost event, but then the cursor on the dataset jumps to the first record, and I loose my pointer to the updated record.
Anyone got a clue on how to solve this?
You should give RefreshRecord a try.
set poPropogateChanges for your provider and assign any new field values in AfterUpdateRecord event handler