SQL Predicate

Download as pdf or txt
Download as pdf or txt
You are on page 1of 41

1

Oracle
SQL Predicate In Sales Cloud

Created by: Radu Marinache


2

INTRODUCTION

SQL Predicates are the units that stand behind all Application Roles from Sales Cloud.
Through SQL Predicates users gain access to the information that is contained in each object
you find in the application.
Regardless if that object is a seeded object or a custom made object,
information access is controlled via SQL Predicates
Learning to manipulate SQL Predicates will provide you the tools to set up the security of the
application according to your specific business requirements
In this document I will try to present how SQL Predicates are created and how they work, via
theory and practical examples.
I hope you will find it useful and will help you create your very own SQL predicates.
3

1 - What is an SQL Predicate?

2 - The First SQL Predicate.

3 - SQL Predicate to show only Owned records of a Custom Object.

4 - SQL Predicate to show only those custom object records in which login user is in the sales
team of the account attached to the record.

5 - SQL Predicate For Opportunity


4

1 - What is an SQL Predicate?

Simply put the SQL Predicate is the WHERE clause of a SQL select operation.
In Sales Cloud every object, either custom made or out of the box is stored in a table or more tables from
the oracle database, the database on which the Sales Cloud environment(and I would say the entire
Fusion Suite) is constructed to.
So every piece of information you introduce in sales cloud will eventually end up as row in a
table from the oracle database.
Well in order for users of the application to retrieve and modify this information they are granted
access via what is called Application Job Roles.
This Application Job Roles are in turn constructed from multiple Duty Roles(or as they are also
called, Application Roles).
If we dig deeper the Application Roles are built by Functional Policies and Data securities
Functional Policies are the ones that provide access to things on the FUSE UI . So if you see Create
button or if you see Opportunity Icon on the dashboard, that is possible via Functional Policies.
The Data securities are the things via which uses can access the information contained in a
particular object. So when you see the records in Accounts(for example) that is due to Data Securities.
Now if we dig even Deeper at the core of a Data security are SQL Predicates

A very simplified graphic representation can be as below:

Note: This is a simplified view of the security model(in reality the security model is much more complex,
but this shows its essence)
5

The SQL Predicate is written at the level of the Database Resource.


Database Resource Represents the Object you have in Sales CLoud.
For example the Opportunity Object is a Database resource called MOO_OPTY

Source: Release 12 Environment - Security Console

Source: Release 12 Environment - Security Console

As you can see the SQL Predicates are written at the level of the Database Resource.
To be mention here that from Release 12 onwards, seeded SQL Predicates can not be edited, to edit them
you have to create a new ones, copies of the seeded one.
But we will learn how to do that in the next chapters.
6

Also as you notice SQL Predicate is in essence simple SQL code, so to write SQL Predicate you have to
understand SQL Language.
I will not teach SQL in this document, if you do not know it here are some resources to help you out.
Tutorials Point: https://www.tutorialspoint.com/sql/
W3Schools.com : https://www.w3schools.com/SQL/deFault.asp

2 - The First SQL Predicate.

We will start simple, in the sense that we will be using a custom object to write our first SQL Predicate.
And this SQL Predicate will have to allow users to see only those records, from the custom object, that
they created.

Before we start making the SQL Predicate I have to mention that the application has out of the box few
SQL function we can use to retrieve information about to user logged in.

This functions are:


a) HZ_SESSION_UTIL.GET_USER_PARTYID
- This will return the Party Id of the user logged into the environment

b) FND_GLOBAL.USER_NAME
- This will return user name of the user logged in

This 2 functions are quite useful when creating SQL Predicates, as you will see next.

So as I was saying, we want to create an SQL Predicate that will allow access on
those records created by the user logged in, on a custom object.
For this I have created in Application Composer a Custom object called
OSCSalesObj.
7

NOTE: When Writing SQL PRedicates on Custom Objects, those objects have to be in mainline!
SQL Predicates work only on mainline objects and attributes

When writing the SQL Predicate you have to use something like this:
&TABLE_ALIAS.COLUMN_NAME

This tells the system that the column you are referring to belongs to the object you are writing the SQL
Predicate for.

So back to our SQL Predicate, we want access to all records that login user created, for this we need an
field(attribute) from the object that stores creator name and the login user name.

Any custom object has an attribute, out of the box, that holds creator name and it is called Created By
and the column name of this attribute is created_by
Now we only need the username of the user logged in, and this we get using the second function I have
already mentioned, FND_GLOBAL.USER_NAME.

So now is time to put all together, as I said we need to make reference to the
object(table) via &TABLE_ALIAS.COLUMN_NAME and then use the function.
So the SQL Ppedicate that we need can be written as:

&TABLE_ALIAS.created_by = FND_GLOBAL.USER_NAME

Now that we have the code for the SQL Predicate we have to use it in the
application.
8

And as I was saying in the first chapter, we use the SQL Predicate on the database
resource which in this case is our custom object called OSCSalesObj.
For this you have to go to the security Console and select the last tab called
Administration
9

Then you click on Manage Database Resources

Next you search for the Object Name (Or Display Name) and you edit it

Once in Edit screen of the Object go to the Condition tab and create a new
condition
10

Now you give a meaningful name and description and you make the condition as
SQL Predicate and you put in the SQL Predicate box the predicate we made early
and save

Now you need to Save the Object and Submit

Now the custom object has a new condition based on the SQL PRedicate we made.
But to give users access via this condition, we need to add it as a data security to
some role.
Since in Release 12 we can not edit out of the box roles, I will create a new CRM
Job Role specifically for this Custom object and assign it to a user I made for
testing.
11

My test user is called viorel.security and it has the standard roles you would find in a Sales
Representative.

Now I will Create a Job Role (In R12 you have to make CRM Job Role to see them under Object Security
in Application Composer).

Roles can be made from Roles Tab of Security Console.


I will create an Empty Role for now and later will see how we add to it Functional Policies and more
importantly Data Security base on the SQL Predicate.
12

So now we have empty Job Role OSCSalesObj_JOB.


Next we need to give functional policies to this role so that user can see the Custom Object in navigator
and Dashboard
To do this Go to Application Composer, to the Custom Object Security and search in the security list the
Job Role created.
Note: When working with security you are not isolated by Sandbox, Sandbox is used only to access the
Object In application composer, however security changes affect mainline.
13

Now you will notice that there are 7 checkboxes.


Enable only Create; View ; Update ; Delete
This options represent Functional Policies.
View All; Update All ; Delete All Represents Data Security. If those will be enable then the user having
this Job Role will have FULL access to the object records, which is not what we want.

Once you save and if you go back to the Security console and edit the Job Role, you will see functional
policies were added to the role and few grants(also related to functional policies)
14

Now if I assign this role to my test user, the user will be able to see the custom object but no records of
this object.
15

As you see I have logged in with my test user (viorel.security) and I can access the custom object landing
page, but I don’t see any records.
Remember when I said UI elements are given by Functional Policies and Data is given by Data Security.
This proves the point very well; user has the job role I previously created which only has functional
policies at this moment.

Next is time to create a data security and use the SQL Predicate created.
So Go to Security Console and Search the Job Role Created and Edit it
16

Move to the Data Security Policy section

Now here you see some items, do not confuse it with data securities.
This are Functional stuff, I won’t go in details why are here, but the idea is if you see under Data Security
section conditions that are named functional, then those policies do not provide data access.
There is 1 data security and that is for Notes object, so that users can access and view notes on the custom
object. This was generated automatically by the system.
Now is time to make our data security, so click on Create Data security Policy button.

Name your policy, make it something suggestive so you know for what it is, I mill name mine
“ViewOwnRecords”.
Select Database resource, in my case is “OSCSalesObj” the API name of my object.
Set data set to “Select by instance set”.
On the Condition Name you should see the condition we previously created under the custom object.
I named mine “CreatedBy”.
And in actions you provide what kind of interaction the user should have with the object records, create
them, view them, update them, delete them.
I will provide all actions.
Start date, you should set it to the current date or a past date, so that Data Security is enabled.
And then click OK
17

Now you should see the new Data security in the list and you can go to Summary and Impact Report
section and save the role.

After you save the role, a good idea is to run the process “Import User and Role Application Security
Data” from Scheduled Processes to help the system refresh security changes.
Now if I log in with my test user viorel.security I should see only records created by this user only.
18

As you can see in the Custom object there are many more records, but due to the predicate viorel.security
can see only records created by himself.

Note: If you don't see any change after saving the role, have more patience give the system more time to refresh,
sometimes even by running the Import User and Role Application Security Data system needs more time to refresh.
Well congratulations are in order, you have just successfully created and implemented a custom
SQL Predicate.
In next lessons I will be showing how to make more complex predicates, but I will not show the entire
implementation flow.
You can always come back to this lesson to see how to make the roles and data securities, the
process is the same every time you want to make a new SQL Predicate.
19

3 - SQL Predicate to show only Owned records of a


Custom Object.
Often when this requirement is encountered, it means that in the custom object a custom Dynamic
Choice List (DCL) was created and it points to the Resource Object.
As in below image:

And the user will set a resource in this DCL which will represent the Owner of the Custom Object
record.
Now the SQL predicate has to sort and show those records that match the Resource set in the
DCL with the User that is logged in.

So if Login user is X , this user should see only those records from the custom object that have
value X in the DCL.

The first step is to find out in which column, inside the database, the value of the DCL is stored.
In this KM you will find all the queries needed to get this information:
How To Extract The Information Needed From the Database on a Custom
Object (Doc ID 2242344.1)

The queries in the above document can be done in a BI Publisher data model as
below:
Go to Navigator > Reports and Analytics > Catalog(BI Publisher) > Create new
Data Model > Create new SQL Query
20
21
22

Ok, so coming back to our case here, once you make this Data Model you can
use the queries in the Km mentioned to get the needed information.
Specifically, you can this one of this 2 queries to find out the Column in which a
field is storing the value.
23

SQL Query 1
SELECT OBJECT_NAME AS OBJECT,OBJECT_ATTR_NAME AS ATRRIBUTE,OBJECT_ATTR_LEN AS
LENGTH,SUBSTR(OBJECT_ATTR_TYPE, - INSTR(REVERSE(OBJECT_ATTR_TYPE), '.') + 1) AS
DATA_TYPE,TXN_VO_ATTR_TABLE,TXN_VO_ATTR_COL
FROM FUSION.MKT_IMP_OBJECT_DETAILS D,FUSION.MKT_IMP_OBJECT_ATTRS A WHERE
D.OBJECT_DETAIL_ID=A.OBJECT_DETAIL_ID
AND A.OBJECT_ATTR_COL LIKE '%EXTN_ATTRIBUTE%' AND A.CREATED_BY != 'SEED_DATA_FROM_APPLICATION'
AND D.OBJECT_DETAIL_TABLE != 'MKT_IMP_JOBS' AND OBJECT_NAME LIKE '%<ObjectName>%'

Note: Replace <ObjectName> with the name of the custom object

Now typically this query works after you have generated artifacts.

However, if it happens you get no results, then you can use this SQL

SQL Query 2
select * from <DATABASE_OBJECT_NAME> where attribute_category ='<OBJ_NAME>'

Note: DATABASE_OBJECT_NAME is actually TABLE_NAME

and OBJ_NAME is CONTEXT_COLUMN_VALUE

This be obtained from this additional queries:

Get Custom object details:


select *
from fusion.adf_extensible_table_usage
where ENTITYDEF_FULLNAME like '%customobject_api_name%'

The results of the above query will be that you get :


USAGE_ID ; ENTITYDEF_FULLNAME;CONTEXT_COLUMN_VALUE;TABLE_ID

Get the table of the custom object


select TABLE_NAME from fusion.adf_extensible_table where TABLE_ID = <Table Id >
24

The results of the above query will be that you get:


TABLE_NAME

Ok so now you know how to obtain all the information you need to create the SQL predicate.

Let’s take up an example.

In my own environment as mentioned above I have a custom object with API name : OSCSalesObj
Inside the custom object I have a DCL pointing to Resources, which represents Owner of the custom
record with API name: Owner_c

METHOD 1
As mentioned before, get the column from the database in which Owner_c is stored.
I make a Data Model and run the first query(SQL Query 1):
SELECT OBJECT_NAME AS OBJECT,OBJECT_ATTR_NAME AS ATRRIBUTE,OBJECT_ATTR_LEN AS
LENGTH,SUBSTR(OBJECT_ATTR_TYPE, - INSTR(REVERSE(OBJECT_ATTR_TYPE), '.') + 1) AS
DATA_TYPE,TXN_VO_ATTR_TABLE,TXN_VO_ATTR_COL
FROM FUSION.MKT_IMP_OBJECT_DETAILS D,FUSION.MKT_IMP_OBJECT_ATTRS A WHERE
D.OBJECT_DETAIL_ID=A.OBJECT_DETAIL_ID
AND A.OBJECT_ATTR_COL LIKE '%EXTN_ATTRIBUTE%' AND A.CREATED_BY != 'SEED_DATA_FROM_APPLICATION'
AND D.OBJECT_DETAIL_TABLE != 'MKT_IMP_JOBS' AND OBJECT_NAME LIKE '%OSCSalesObj%'
25

So as you can see Owner_c holds its value in the column called:
EXTN_ATTRIBUTE_NUMBER003

And the table of the Custom object OSCSalesObj is : ZCA_REF_ENTITIES


26

METHOD 2
But let’s presume that the query I ran above will return no results.
Then we make use of the second query I have mentioned at SQL Query 2.
For this query we need additional info so we ran in this order:
select *
from fusion.adf_extensible_table_usage
where ENTITYDEF_FULLNAME like '%OSCSalesObj%'

So we get the result:


USAGE_ID (300100089813234)
ENTITYDEF_FULLNAME (sessiondef.oracle.apps.sales.custExtn.entities.OSCSalesObj_c)
27

CONTEXT_COLUMN_VALUE (OSCSalesObj_c)
TABLE_ID (100000020154628)

Next we ran:
select TABLE_NAME from fusion.adf_extensible_table where TABLE_ID = 100000020154628

Result is: TABLE_NAME (ZCA_REF_ENTITIES)

So now we have the custom object table as ZCA_REF_ENTITIES and attribute_category as OSCSalesObj_c
28

And we can finally run:


select * from ZCA_REF_ENTITIES where attribute_category ='OSCSalesObj_c'

But, here is a bit tricky, if you don’t have any value in your DCl then you may not realize which of the
columns hold the value.
So what you can do is, go to UI put a value into that DCL, run the query to return just the record you
modified, then go back and remove the value from the DCL and run gain the query and observe which
column will get modified.

select * from ZCA_REF_ENTITIES where attribute_category ='OSCSalesObj_c' and RECORD_NAME=


'Test_3'

Notice I added additional condition to the query to search a specific custom record (RECORD_NAME=
'Test_3')
29

Go to UI and add a value


30

Ran again the query after setting the value and notice a column was populated, that’s the column holding
Owner_c values.

So that's 2 ways go get the needed information, other way we will get that the table of the custom object
is: ZCA_REF_ENTITIES and column for the Owner_c is EXTN_ATTRIBUTE_NUMBER003

Now we have the information from the Custom object side, but we now need to get the information from
the login user.
There is one thing that you need to know, when you have a DCL that points to Resource Object,
the Id of the resource is not Party Id, it is in fact Resource Profile Id.
Because the DCL will store the Primary Key of the Object to which it points to and the Resource
Object table is JTF_RS_RESOURCE_PROFILES which has as Primary key RESOURCE_PROFILE_ID.
http://docs.oracle.com/cloud/farel11/salescs_gs/OEDMS/JTF_RS_RESOURCE_PROFILES_tbl.htm

Problem now is how do we get the Resource Profile Id of the login user?
31

Well we make use of the application functions I already mentioned at chapter 2, specifically this function:
HZ_SESSION_UTIL.GET_USER_PARTYID

And we query the JTF_RS_RESOURCE_PROFILES table by the Party Id and we return the Resource
Profile Id,a s below:
SELECT RESOURCE_PROFILE_ID FROM JTF_RS_RESOURCE_PROFILES WHERE PARTY_ID =
HZ_SESSION_UTIL.GET_USER_PARTYID

Now we have the query that will return the resource profile id of the login user and is time to put
all the information together in making the SQL for the SQL predicate
And the SQL for the predicate look like this:

select ID from ZCA_REF_ENTITIES where attribute_category ='OSCSalesObj_c' and


EXTN_ATTRIBUTE_NUMBER003 = (
SELECT RESOURCE_PROFILE_ID FROM JTF_RS_RESOURCE_PROFILES WHERE PARTY_ID =
HZ_SESSION_UTIL.GET_USER_PARTYID
)

So that is the SQL for the Predicate, but it is not yet a SQL Predicate, to become one we need to add it
under the Database Resource for the Custom object with this format:

&TABLE_ALIAS.ID IN (
32

select ID from ZCA_REF_ENTITIES where attribute_category ='OSCSalesObj_c' and


EXTN_ATTRIBUTE_NUMBER003 = (
SELECT RESOURCE_PROFILE_ID FROM JTF_RS_RESOURCE_PROFILES WHERE PARTY_ID =
HZ_SESSION_UTIL.GET_USER_PARTYID
)
)

Notice I added &TABLE_ALIAS.ID for the reasons already explained at Chapter 2.

So now we can go to Security console and add the SQL Predicate a condition in the Custom object
Database Resource.
Steps how to do it already provided at chapter 2
You should end up with something like this in the end.

How to use this condition in a role is also explained at Chapter 2 so please refer to that section.
33

4 - SQL Predicate to show only those custom object


records in which login user is in the sales team of
the account attached to the record.

There are cases where in a custom object we have a Dynamic Choice List pointing to Account
Object.
The Account object, as you are well aware of has a child called sales team, which represents the
resources assigned to that account.
There could be a requirement to restrict visibility on the custom object, in such away that for a
user that is logged in, to see only those custom object records, in which he or she is member of the
account sales team, account that is associated via that Dynamic Choice List to the custom object record.
This is the case that we will treat in this chapter.
The first thing that needs to be done is to identify in which column from the database, is the
PartyId of the account associated with the custom object, stored.
And next is to identify which are the tables and columns where the account sales team are stored,
and how to retrieve that.

The Setup
Custom Object Name is: OSCSalesObj
Dynamic Choice List : Account_c
34

Requirement:
Show to log in user only those custom object records that are associated with an account and the user is in
that account sales team.

Step 1 - Get the column in which the account party id is stored in the database.
As you seen in previous chapter we will use BI Publisher and a data model to access the oracle
database.
And we will be using the same queries as before, to identify the table in which the custom object
is stored and then to find out the column where the Dynamic Choice List is held
As you already know there is a SQL query that can give us all the details needed in one go.
This is the Query:

SELECT OBJECT_NAME AS OBJECT,OBJECT_ATTR_NAME AS ATRRIBUTE,OBJECT_ATTR_LEN AS


LENGTH,SUBSTR(OBJECT_ATTR_TYPE, - INSTR(REVERSE(OBJECT_ATTR_TYPE), '.') + 1) AS
DATA_TYPE,TXN_VO_ATTR_TABLE,TXN_VO_ATTR_COL
FROM FUSION.MKT_IMP_OBJECT_DETAILS D,FUSION.MKT_IMP_OBJECT_ATTRS A WHERE
D.OBJECT_DETAIL_ID=A.OBJECT_DETAIL_ID
AND A.OBJECT_ATTR_COL LIKE '%EXTN_ATTRIBUTE%' AND A.CREATED_BY != 'SEED_DATA_FROM_APPLICATION'
AND D.OBJECT_DETAIL_TABLE != 'MKT_IMP_JOBS' AND OBJECT_NAME LIKE '%OBJECT NAME%'

In our case the object name is OSCSalesObj, so query to be used is:

SELECT OBJECT_NAME AS OBJECT,OBJECT_ATTR_NAME AS ATRRIBUTE,OBJECT_ATTR_LEN AS


LENGTH,SUBSTR(OBJECT_ATTR_TYPE, - INSTR(REVERSE(OBJECT_ATTR_TYPE), '.') + 1) AS
DATA_TYPE,TXN_VO_ATTR_TABLE,TXN_VO_ATTR_COL
FROM FUSION.MKT_IMP_OBJECT_DETAILS D,FUSION.MKT_IMP_OBJECT_ATTRS A WHERE
D.OBJECT_DETAIL_ID=A.OBJECT_DETAIL_ID
AND A.OBJECT_ATTR_COL LIKE '%EXTN_ATTRIBUTE%' AND A.CREATED_BY != 'SEED_DATA_FROM_APPLICATION'
AND D.OBJECT_DETAIL_TABLE != 'MKT_IMP_JOBS' AND OBJECT_NAME LIKE '%OSCSalesObj%'
35

Result is:

So we can see the attribute Account_Id_c (which is actually PatyId of the Account) is stored in column
called EXTN_ATTRIBUTE_NUMBER001 from the tables ZCA_REF_ENTITIES.

Note: If query does not return results, you method 2 from chapter 3 to get same information (page 26)

So now that we have this information we can go to next step.

Step 2 - Get The Login User PartyId


In Chapter 2 at page 6 I presented the function that return the login user party Id, this function is:
HZ_SESSION_UTIL.GET_USER_PARTYID

Step 3 - Find out in which tables and columns the Account Sales Team is stored
36

This tables are: ZCA_S_ACCT_RESOURCES and ZCA_SALES_ACCOUNTS


You can learn more about tables from Tables and Views for Oracle Sales Cloud.

So what we need is to return the Party Id of the Account Team that matches the login user Party Id.
The Query is:

SELECT PARTY_ID
FROM ZCA_S_ACCT_RESOURCES acct_team,
ZCA_SALES_ACCOUNTS acct
WHERE acct_team.sales_account_id = acct.sales_account_id and acct_team.resource_id =
HZ_SESSION_UTIL.GET_USER_PARTYID

Notice we are using the function from Setp 2 , to find the matching account team member.

Step 4 - Put all together and get the final form of the SQL Predicate

So we have the Custom Object and DCL (Dynamy Choice List) Table and column, we also have the
account sales team info, we can build the SQL for the predicate as below:

SELECT ID
FROM ZCA_REF_ENTITIES
WHERE EXTN_ATTRIBUTE_NUMBER001 IN
(SELECT PARTY_ID
FROM ZCA_S_ACCT_RESOURCES acct_team,
ZCA_SALES_ACCOUNTS acct
WHERE acct_team.sales_account_id = acct.sales_account_id and acct_team.resource_id =
HZ_SESSION_UTIL.GET_USER_PARTYID)

But because we are going to use it as a SQL Predicate then we have to write the code, by adding
TABLE_ALIAS, so that system know we are working in the context of the custom object.
37

Code For SQL Predicate is:

&TABLE_ALIAS.ID IN (
SELECT ID
FROM ZCA_REF_ENTITIES
WHERE EXTN_ATTRIBUTE_NUMBER001 IN
(SELECT PARTY_ID
FROM ZCA_S_ACCT_RESOURCES acct_team,
ZCA_SALES_ACCOUNTS acct
WHERE acct_team.sales_account_id = acct.sales_account_id and acct_team.resource_id =
HZ_SESSION_UTIL.GET_USER_PARTYID))

Or you can write it like so:

&TABLE_ALIAS.EXTN_ATTRIBUTE_NUMBER001 IN
(SELECT PARTY_ID
FROM ZCA_S_ACCT_RESOURCES acct_team,
ZCA_SALES_ACCOUNTS acct
WHERE acct_team.sales_account_id = acct.sales_account_id and acct_team.resource_id =
HZ_SESSION_UTIL.GET_USER_PARTYID))

Both variations will work just as good.

Now you we can use it to make the condition on the database resource and create our data security policy.
Already shown how to do all this in chapter 2.
38

5 - SQL Predicate For Opportunity


In this scenario we have created 2 Custom Fix Choice Lists(FCL).
Once FCL will be in Opportunity and the second FCL will be on Resource Object.

Opportunity

Resource

As it can be seen, both fields have the same set of values.


Now the requirement is to create a SQL Predicate that will make it so for the Login user to see all
opportunities that have same value in the FCL field as the FCL field from Resource Directory for the
user.
And also the User has to be in the Opportunity Sales Team.
39

For example the login user in this case is Campbell,Scott and for him the value of the FCL in
resource Directory is “BB”.
So for him the SQL predicate should show all opportunities in which he is in the team and also
the opportunities have to have in their FCL field also “BB”

As before first thing is to identify in which columns from MOO_OPTY and from
JTF_RS_RESOURCE_PROFILES the value of FCL field is stored.

For this we make a Data Model in BI Publisher using the SQL already presented in the early
chapters.
SELECT OBJECT_NAME AS OBJECT,OBJECT_ATTR_NAME AS ATRRIBUTE,OBJECT_ATTR_LEN AS
LENGTH,SUBSTR(OBJECT_ATTR_TYPE, - INSTR(REVERSE(OBJECT_ATTR_TYPE), '.') + 1) AS
DATA_TYPE,TXN_VO_ATTR_TABLE,TXN_VO_ATTR_COL
FROM FUSION.MKT_IMP_OBJECT_DETAILS D,FUSION.MKT_IMP_OBJECT_ATTRS A WHERE
D.OBJECT_DETAIL_ID=A.OBJECT_DETAIL_ID
AND A.OBJECT_ATTR_COL LIKE '%EXTN_ATTRIBUTE%' AND A.CREATED_BY !=
'SEED_DATA_FROM_APPLICATION' AND D.OBJECT_DETAIL_TABLE != 'MKT_IMP_JOBS' AND OBJECT_NAME LIKE
'%Opportunity%'

As it can be seen FCL field in opportunity is stored in the column EXTN_ATTRIBUTE_CHAR041 of


table MOO_OPTY.

For the FCL in Resource Directory we run:

SELECT OBJECT_NAME AS OBJECT,OBJECT_ATTR_NAME AS ATRRIBUTE,OBJECT_ATTR_LEN AS


LENGTH,SUBSTR(OBJECT_ATTR_TYPE, - INSTR(REVERSE(OBJECT_ATTR_TYPE), '.') + 1) AS
DATA_TYPE,TXN_VO_ATTR_TABLE,TXN_VO_ATTR_COL
40

FROM FUSION.MKT_IMP_OBJECT_DETAILS D,FUSION.MKT_IMP_OBJECT_ATTRS A WHERE


D.OBJECT_DETAIL_ID=A.OBJECT_DETAIL_ID
AND A.OBJECT_ATTR_COL LIKE '%EXTN_ATTRIBUTE%' AND A.CREATED_BY != 'SEED_DATA_FROM_APPLICATION'
AND D.OBJECT_DETAIL_TABLE != 'MKT_IMP_JOBS' AND OBJECT_NAME LIKE '%ResourceProfile%'

As it can be seen FCL field in Resource Directory is stored in the column


EXTN_ATTRIBUTE_CHAR009 of table JTF_RS_RESOURCE_PROFILES.

Now what is left is to build the SQL to return all opportunities that have same value in FCL as in resource Directory
FCL and login user is in the sales team.

SQL Look as below:

SELECT OPTY.OPTY_ID
FROM MOO_OPTY OPTY INNER JOIN MOO_OPTY_RESOURCES RES
ON (OPTY.OPTY_ID = RES.OPTY_ID ) INNER JOIN JTF_RS_RESOURCE_PROFILES R ON (RES.RESOURCE_ID =
R.PARTY_ID)
WHERE RES.RESOURCE_ID = HZ_SESSION_UTIL.GET_USER_PARTYID AND OPTY.EXTN_ATTRIBUTE_CHAR041 =
R.EXTN_ATTRIBUTE_CHAR009

Notice the usage of HZ_SESSION_UTIL.GET_USER_PARTYID , function that was presented in the


first chapters.

Next is to make this SQL into a SQL Predicate, by adding &TABLE_ALIAS.OPTY_ID, as below:
&TABLE_ALIAS.OPTY_ID IN (
SELECT OPTY.OPTY_ID
FROM MOO_OPTY OPTY INNER JOIN MOO_OPTY_RESOURCES RES
ON (OPTY.OPTY_ID = RES.OPTY_ID ) INNER JOIN JTF_RS_RESOURCE_PROFILES R ON (RES.RESOURCE_ID =
R.PARTY_ID)
WHERE RES.RESOURCE_ID = HZ_SESSION_UTIL.GET_USER_PARTYID AND OPTY.EXTN_ATTRIBUTE_CHAR041 =
R.EXTN_ATTRIBUTE_CHAR009
)
41

Now all is left is to go to Manage Database Resources , open the Opportunity resource and add a new
Condition having this SQL Predicate

After this is done, the condition newly created can be used to create custom Data Securities.

And with this final example we conclude the tutorial on creation of SQL Predicates.
All other SQL predicates follow the same pattern, all that is needed is knowledge of SQL and of
course knowledge of the tables in Oracle Sales Cloud.

You might also like