Build an APEX URL that pulls in the APP_USER ID - oracle-apex

I am using a PL/SQL Region in APEX where I am build an Interactive Report Link that will filter the report for the USERs :APP_USER id and provide them a view of their rows only.
The Region first counts the rows to show the user how many rows he/she has and then the URL directs them to the IR page and filters the IR for their ID. For example...
SELECT count(*) INTO l_open_proj FROM crd_mpl_upload WHERE LOWER(GLB_CPM_QID) = LOWER(:APP_USER);
later...I have the part where the URL is built.
sys.htp.p('<li class="uNumber uGrid col_2">');
sys.htp.p('<ahref="'||sys.htf.escape_sc('fp='||:APP_ID||':12:'||:APP_SESSION||':::12,RIR:**IR_GLB_CPM_QID:upper(:APP_USER)**:') ||'">');
sys.htp.p('<big class="uValue">' || l_open_proj || '</big>');
sys.htp.p('<small class="uLabel">My Projects</small>');
sys.htp.p('</a>');
sys.htp.p('</li>');
The part specifically I am having issues with is the IR_GLB_CPM_QID:upper(:APP_USER) as :APP_USER here does not pull through the users NTLM authenticated ID. I ahve tried upper and lower, etc. and I don;t that is the issues. The ID will come through as P123456 for example.
Any ideas or help would be greatly appreciated.
Thanks,

The reference to the :APP_USER bind variable is within a string, unlike the others.
In this case it's safe to user &APP_USER. instead (don't forget trailing dot), but do not use this substitution syntax in SQL.
You'll also have issues with the upper() in this context, though I don't think it's necessary? And should be done within the SQL if so.

Related

How to change a database name in a query via a URL in power bi

i am trying to change my database name in my advanced editor query in power bi. I know i can create parameters with in the power bi desktop app and pass the different database with in it. I have done this and it works fine.
But what i am trying to do is when i give a user a link for example
https://app.powerbi.com/groups/me/reports/DataSource="PowerBi_1"
how do i get the datasource name which is "PowerBi_1" and pass it into my advanced editor query which looks as follows
let
Source = Sql.Database(".", "PowerBi_2", [Query="select *#(lf)from Customer"])
in
Source
so i want to replace the Powerbi_2 with PowerBi_1
is this possible?
I tried searching and the only things i could find was to add parameters from "manage parameters" which i can already do. But i need it to be passed from the URL and automatically change the data source instead of manually changing it via "edit parameters"
i know you can use filter in your URL as https://app.powerbi.com/groups/me/reports/12345678-6418-4b47-ac7c-f8ac7791a0a7?filter=Customer/PostalCode eq '15012'
but this would only work on datasets. im not sure how to do this for a database change in a query
The only thing you could try is if you have a direct query and use the new feature of binding query parameters.
https://learn.microsoft.com/en-us/power-bi/connect-data/desktop-dynamic-m-query-parameters
Then you can set a filter with url to point to the database you need. Not sure how it would work - haven't tried it myself.
To expand on the idea a bit - you would need a table with database names in it. Then you would bind database column of that table to your query parameter and finally, use your url to set appropriate filter on this new table.
EDIT:
Scratch that, in the article I linked to, it says that direct query T-SQL is not supported. But if they were ;)...

Power BI Row-level security (RLS) if PART of a field is matched (not the entire field)

I have setup my RLS quite successful. I collect the user who is logged on, have setup roles and also manage to limit rows to use in the reporting.
There is a field, that contains the row's responsible person (john#doe.com).
The DAX filter [RowResponsible] = [UsersEmail] works just fine.
The thing is, that the [RowResponsible] may contain multiple values. For example john#doe.com;jane#doe.com.
The DAX filter [RowResponsible] = [UsersEmail] will no longer work, obviously.
I'd like to be able to use some form of 'contains' in this filter, but SEARCH / CONTAINSSTRING will not do the trick (they seem to be not supported).
Any thoughts?
This following code should work for you as I am using a same code for one of mine RLS and its working fine-
CONTAINSSTRING(
[RowResponsible],
[UserEmail]
)

Oracle APEX - Reusable Pages?

We have some tables in our database that all have the same attributes but the table is named differently for each. I'm not sure of the Architect's original intent in creating them in this way, but this is what I have to work with.
My question for all the expert Oracle APEX developers: is there away to create a reusable page that I can pass the table name to and that table name would be used in the reporting region and DML processing of that page?
I've read up on templates and plugins and don't see a path forward with those options. Of course, I'm new to webdevelopment, so forgive my ignorance.
We are using version 18.2.
Thanks,
Brian
For reporting purposes, you could use a source which is a function that returns a query (i.e. a SELECT statement). Doing so, you'd dynamically decide which table to select from.
However, DML isn't that simple. Instead of default row processing, you should write your own process(es) so that you'd insert/update/delete rows in the right table. I've never done that, but I'd say that it is possible. Basically, you'd keep all logic in the database (for example, a package) and call those procedures from your Apex application.
You could have multiple regions on one page; one region per table. Then use dynamic actions to show/hide the regions and run the select query based on a table name selected by the user.
Select table name from a dropdown or list
Show the region that matches the table name (dynamic action)
Hide the any other regions that are visible (dynamic action)
Refresh the selected region so the data loads (dynamic action)
If that idea works let me know and I can provide a bit more guidance.
I never tried it with reports, but would it work to put all three reports in a single page, and set them via an Item to have Server-Side Conditions that decide what gets shown in the page? You'd likely need separate items with a determined value for the page to recognize and display.
I know I did that to set buttons such as Delete, Save and Create dynamically, rather than creating two or more separate pages for handling editing of certain information. In this case it regarded which buttons to shown based on a reports' primary key being sent to said "Edit" page. If the value was empty, it meant you wanted to create a new record (also because the create button/link sent no PK). If said PK was sent (via a edit button/link), then you'd have the page recognize it and hide the create button and rather show the edit button.

"general" variable in oracle apex

I'm developing an application in Oracle Application Express (APEX).
First page contains list of projects as a tabular report.
Clicking any of the rows forwards to the next page, where records can be edited. I've implemented it with following settings:
Link column: link to custom target
Target: Page in this application
Until this is fine.
My problem is how to pass actual report to the next page?
My table, which is the basis of the report has primary key (ID), and also owner & title combination is unique. Currently ID column is not included in the report.
Also the second page doesn't currently contain field showing ID, as this information isn't important to the users.
I know I could set ID column in report, and create a read only (even hidden) text box in the next page, however I'm looking for a more elegant solution. What is the standard way to solve this?
I wonder if you are asking: "How do I pass a value from page 1 to page 2 so page 2 can use the value to do a query and present the results. If so, here is how it's done.
On page P1, the report, for example, select the attributes for the report region under the region in the Rendering pane on the left of the page designed.
Under Attribute Properties on the right side, look for Link Column and set it to "Link to custom target". Then click Target.
Select the page and then in the Set Items section, on the left, under name, select the PK ID field to receive the passed value ex: P2_ID. On the right under Value select the field to pass the value, ex: #P1_ID# and click ok.
Now, when the link on page 1 report is clicked, the P1_ID is saved into Session state by Apex and passed to P2 which then performs a FETCH using the passed value.
You can read more about Session State here. Also, be aware there are security settings which affect what params can and can't be passed in the URL.
Clicking "Session" in the developer toolbar will enable you to see the session variables being passed.
If you mean "How do I store values in the app that can be accessed anywhere in the app - like a global variable" Then look at Application Items.
As always, please include version numbers in these posts.
When you create a target page let's say Page 3
And you create some items, let's say P3_ITEM_1,P3_ITEM_2, etc
You can assign values to each of them through the url in the original page
The complete APEX URL Syntax looks like this:
http://apex.oracle.com/pls/apex/f?p=AppId:PageId:Session:Request:Debug:ClearCache:Params:ParamValues:PrinterFriendly
Let’s take a closer look:
http:// – the protocol, can be http or https
apex.oracle.com – your domain/host/server, whatever you want to call it. Can also be localhost.
/pls – indicates that you are using Oracle HTTP Server with mod_plsql. If you are using APEX Listener or Embedded PL/SQL Gateway this part is obsolete/missing.
/apex – the entry from your dads.conf file (this a file on your application-server or EPG where the target database is configured) – in case of EPG its just one entry pointing to localhost, in case of an OAS you can have multiple entries, each pointing to an other database
/f?p= – procedure “f” is called and parameter “p” is set to the complete rest of the string. Remember: APEX uses mod_plsql. “f” is a public procedure, this is the main entrypoint for APEX. Or you could say: “f” is APEX.
AppId – the number or the Alias of the Application
:PageId – the number or the Alias of the Page
:Session – unique Session ID, can be 0 for Public Pages or empty (then APEX creates a new Session)
:Request – a Request Keyword. This is basically free text, just a string you can specify to react in a process or region condition on. e.g. you could pass the keyword “CREATE” and have a condition on the delete button of your page saying “dont’t display this button if request is CREATE”.
In other words: use the REQUEST to control the behaviour of your page.
When pressing a button, the button sets the REQUEST to the button-value (e.g. SAVE), so that you can control the processes in the page processing (Submit) phase.
:Debug – set to YES (uppercase!) switches on the Debug-Mode which renders debug-messages and timestamps in your Browser window. This helps to detect wrong behaviour of your page or performance issues and everything else. Every other value then YES turns the Debug-Mode off
:ClearCache – you can put a page id or a list of page ids here (comma-separated) to clear the cache for these pages (set session state to null, …). But there is more: RP resets the pagination of reports on the page(s), a collection name deletes the collection, APP clears all pages and application-items, SESSION does the same as APP but for all applications the session-id has been used in.
:Parameters – comma seperated list of page-item names. Good practice is to set only those page-items which are on the page you are going to. Accepts page-items as well as application-items.
:ParamValues – comma separated list of values. Each value is assigned to the corresponding Parameter provided in ParamNameList (first value assigned to first parameter, second value assigned to second parameter, and so on…).
The trick here is not having values which contain either a comma “,” or a colon “:”. Both would lead to side-effects and errors, as APEX gets confused when parsing the URL. Using a comma works, if enclosed by slashes: e.g. \123,89.
:PrinterFriendly – set to YES (uppercase!) switches the page into PrinterFriendly-Mode, uses the Printerfriendly template to render the Page. You can also hide regions or other elements in PrinterFriendly-Mode using the PRINTER_FRIENDLY variable in a condition.
In your case you'd use Params:ParamValues like this:
P3_ITEM_1,P3_ITEM_2:someValue_1,someValue_2
Documentation

In Oracle Apex 5 I want to link to an Interactive Report and set a filter RequestID = #RequestID#

I am trying to link a column from an Interactive Report to another Interactive Report in Apex 5. I want to set the filter in the later one with a value from the first one. I used a column of type Link then clicked on Target button to set the page number like this:
It doesn't work. I read there are other ways, I could use an URL link and build the URL to pass the parameters using a package but if I used this, how can I bind it to the link?
Normally you'll need to specify the operator to be used in the link - documentation:
Developing Reports > Editing Interactive Reports in Page Designer > Linking to Interactive Reports
Snippet concerning setting up a link:
To create a filter, use the following itemNames and itemValues syntax:
IR[region static ID]<operator>_<target column alias>
Consider the following example:
IR[EMP]C_ENAME:KING
Meaning that if you want to place a filter on your report where the column REQUEST_ID matches a given value, you'd need the equals operator syntax:
IREQ_REQUESTID:#REQUEST_ID#
However, using
IR_REQUESTID:#REQUEST_ID#
should also work, as the EQ operator is the default operator.
Also consider other issues: do you have more than one IR on the page? You'll need to reference the correct one. Is your generated link correct? Inspect it!
I found what was causing the filter not to work. I was trying to filter a column of type "link". It doesn't work when it's a "link", but it does when it's "plain text". So now you know. Here's how it's looking...
For me it works like this:
I created an Item (display only)(source type: null) on the second page with the second IR.
In the first IR in the Column Attributes set a Link Text and the Target and Page number (like you did already). In the Name part put your Item that you just created and for the Value put the column name in which are the values for your filter (like #Request_ID'#).
Then again on the second page with the second IR you will put something like this in the Region Source:
select REQUEST_ID,
REQUEST_NUMBER,
NAME,
FIRST_NAME,
COMPANY,
COUNTRY,
TYPE,
RQ_IS_ARCHIVE,
RQ_ID_TO
from REQUEST
where REQUEST_ID = :P20_REQUEST_ID
The :P20_REQUEST_ID is the Item that you created on that second page.
You passed the value from the Request_ID column from the first page in to the Item on the second page, there you used it then as a condition.
Hope this helps you...