Creating a page to show data with foreign keys - oracle

I'm creating an APEX application that allows students to apply to job placements, and allows an admin to see all interactions. I want to create a page to show all of the students applications.
First off, here's the database schema for the tables involved:
Full sized link: http://i.stack.imgur.com/QU1Pr.png
I have a report with a list of students and I've added a "View Applications" column. I've made the "View Applications" column linkable, and it goes to the new page. The problem is, I have no idea how to show all of the applications for the student that the admin is currently looking up.
The only way I can think of doing it is passing RECORD_NUMBER (PK in students table) to the new page and then executing some SQL using that, and populating the page fields with what's returned. But I have no idea how to do that. I don't know how to grab the RECORD_NUMBER value to use in SQL and I don't know how to populate form fields with what's returned by the SQL.
Any help is appreciated.

So you've got one page that lists applications and the students that have applied. We'll call that page 1. If I understand what you're trying to do, you can create a page 2, with a report and a hidden page item. Call the page item P2_RECORD_NUMBER.
Create the report with the query:
SELECT *
FROM tbl_jobs j
INNER JOIN tbl_applications a on a.job_id = j.id
INNER JOIN tbl_students s ON s.record_number = j.record_number
WHERE s.record_number = :P2_RECORD_NUMBER
Now edit the link on page 1 so it points to page 2 and populates P2_RECORD_NUMBER with the record_number of the row that the user clicked on. I don't have Apex in front of me, but I think you can do that by editing the report attributes for that column. Also, you can use the url of the form http://site.com/f?p=<APP_ID>:<PAGE_ID>:0::::P2_RECORD_NUMBER:<record_number>. (I'm doing that from memory and may have the number of colons wrong.)
You'll also want to have some default text in place in case the query above returns no rows.

Just create a new page for the admin and enter a query like
SELECT *
FROM tbl_students s
JOIN tbl_applications a USING (record_number)
JOIN tbl_jobs j ON a.job_id = j.id
Do you know where to add the query?

Related

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.

APEX_ITEM displays only one row

I have created a form region "Form on a SQL query" with this query
SELECT
APEX_ITEM.TEXT(1,TEAM_MEMBER) TEAM_MEMBER,
APEX_ITEM.TEXT(2,HOURS) HOURS
FROM APEX_TEAM_MASTER
WHERE TEAM_DATE = :P2_TEAM_DATE
AND UPPER(TEAM_LEAD) = UPPER(:P2_TEAM_LEAD)
ORDER BY 1
TEAM_MEMBER and HOURS are the exact columns in the APEX_TEAM_MASTER table
The :P2_TEAM_DATE and :P2_TEAM_LEAD are select lists. When i run the page and select values in the lists, the form displays just one row of text boxes.
The purpose of this page is, a manager can login to this application, select a date and a team lead under him, which lists the members under the lead. He can then record the hours each team member worked for the day. There are multiple team leads under each manager and different number of team members under each team lead. So the form has to be dynamic.
What you described looks more like an Interactive Grid (IG) (or former Tabular Form). There's no need for you to reinvent that functionality, so - switch to the IG and let Apex take care about everything else.

APEX 5 Authorization Scheme specific user

I am building an APEX 5 Application for a school. There is a page called "Course Information" and it includes several Classic Reports with information such as the class roster and testing schedule. I want to include a report with grades but I only want this region to be viewable by the teacher of the course. If I can get a hidden item on the page to be filled with the username of the teacher, can I build an authorization scheme that checks APP_USER against this item and only show the region if they match?
How would I accomplish this?
I would go about this slightly differently, and wouldn't use an Authorization Scheme for this particular requirement.
Base the report on a view which has the teacher's username as one of the columns. Put a where clause in the report SQL, e.g. select col1, col2, col3 from the_view where teacher_username = :APP_USER.
Put a Condition on the region using Rows returned based on something like select 1 from the_view where teacher_username = :APP_USER.
This way, the report region will only be rendered if the user is allowed to view the records in it.
The simplest option is to use server side condition, a function that returns Boolean, for that region. Just put
return :APP_USER = 'YOUR_TEACHER';
in there. Region will render only for your teacher. Of course, 'YOUR_TEACHER' should be substituted with his real username.

How to implement many to many relationship using Oracle Apex 3.2 form?

I have a many to many relationship on 2 tables.
table1 - primary key = link_id + other fields
table2 - primary key = category_id + other fields
table3 - primary key = link_id + category_id (no other fields in the table)
I'm just wondering how can I implement this on Apex 3.2.
The 2nd table is just the possible categories that can apply to a link. (e.g. Training, Prevention, Mental health and etc). 1 link can have many categories attached to it.
I'm hoping all the possible categories will appear on the screen as a checkbox and then when I open a link record (e.g. Mental health and training categories are assigned to the record), the corresponding checkbox will be automatically ticked. And of course, the ability to tick/untick checkboxes as I please and save/update the record.
I've looked at examples but I cannot find them.
Thanks
Create a report on your table1 and a form on your table2 and 3. In your report you need to add an edit_link which will set your form with the correct link_id. For your category form items you can set the attribute "Display as" to "Checkbox".

Ordering records by foreign field while maintaining adding capability

I have an Access form that lists all records in a table. One column in that table refers to a 'device' table, which then has a foreign key reference to a 'brand' column. In the form, the brand name + device name are displayed due to some magic in a combo box for every row.
The question: how can I sort this form by the brand name, while still retaining the ability to create new records? This is my current query:
SELECT ehs.*
FROM ehs, brand, device
WHERE brand.ID=device.brand_id AND ehs.device_id=device.ID
ORDER BY brand.brand_name, device.model;
Apparently (and understandably), you cannot add records when the query has a join in it. What would be a better approach to sorting the list?
You can create a form that has a foreign key in the query that allows adds and updates. I've just done this in Access 2010 to confirm.
It's possible that some of the magic you mentioned with the combo boxes has broken the ability to do so.
Note: I've just noticed I've used DeviceName where you've used model - you'll need to adjust the SQL below.
There are some tricks, though:
Make sure all of your tables have primary keys (hard to avoid in Access)
Make sure all your foreign keys are indexed (so brand_id in device table, and device_id in ehs table) - duplicates ok.
Use the relationships diagram to draw the relationships between these tables
I then created a query - I just used the query designer, so Access' interesting brackety arrangement is all its own doing:
SELECT ehs.*
FROM (Brand INNER JOIN Device ON Brand.brandID = Device.BrandID) INNER JOIN ehs ON Device.DeviceID = ehs.DeviceID
ORDER BY Brand.Brandname, Device.DeviceName;
If you view that in a data sheet view you should be able to add a record. That's important, if you can't there's a problem, if you can then we're on the way.
If this works, then I'd suggest create a new form based on this query and verify that the new form allows you to add records. This new form is basically going to have an id number for device_id. So you'll have to type a number to make it work.
The trick you're going to want to perform is, and I'm guessing the thing that's causing you problems:
To have a "brand" drop-down that you choose a brand, which then limits the options for the device drop-down.
That's REAL tricky (and I'm afraid I'm somewhat rusty in Access, and it's not in the question, really).
What you CAN do, easily, instead, is have a drop-down for device, that includes the brand name, and sort that appropriately.
I added a combo box to the form. The wizard takes you through using a table or query, I just chose the device table (we'll tweak this later), and the fields - you need device_id model and brand_id, and what to display (model and brand_id - we'll tweak it) and it hides the primary key. When it says "do you want to save it for later or store it in this field, choose store it in this field and choose device_id (which is in the ehs table).
When the wizard completes, click on the new combo box, and get the properties for it. Switch to the Data tab, an there's a builder [...] button next to RowSource. Click that, you get a query builder. Add the Brand table and show the brand_name field and hide the brand-id field. (We just chose that so the combo box has two columns). Sort as you like.
When you close it, it will ask you if you want to save it, so say yes. Your SQL will be something like (with appropriate field name changes because of my mistake):
SELECT Device.DeviceID, Brand.Brandname, Device.DeviceName
FROM Brand INNER JOIN Device ON Brand.brandID = Device.BrandID
ORDER BY Device.DeviceName;
Your form should now have a combo box that shows the device name when not selected, and device name and brand name when you select the drop-down.
You can then delete the original device_id text box from the form.
And you can also add the brand name to the source query and add it as a text field on your form, so you can see the brand next to the device, even when it's not in the drop-down.
The primary query for the form can be:
SELECT ehs.*, Brand.Brandname
FROM (Brand INNER JOIN Device ON Brand.brandID = Device.BrandID) INNER JOIN ehs ON Device.DeviceID = ehs.DeviceID
ORDER BY Brand.Brandname, Device.DeviceName;
You can add BrandName as a text box - you don't need devicename (model) because this shows in the combo box.
And you should still be able to add records.
So, not ideal, but a lot simpler than coding up a bunch of VBA, which is where I think you'd need to go if you wanted to separate your combo boxes (not sure), especially as that's not the original question anyway.
I suggest you do each step and verify that it's still working at each stage.
Good luck.

Resources