Thursday 26 February 2015

All About MO_GLOBAL and FND_GLOBAL


11i -> dbms_application_info.set_client_info(&org_id);
R12 -> mo_global.set_policy_context('S',&org_id);
Ref: from http://www.orafaq.com/node/2243

How To Retrieve Rows From Table Or Synonym For An ORG_ID In E-Business Suite 12 [ID 787677.1]
Ref:from http://oracle.anilpassi.com/mo-global-dive-into-r12-multi-org-design.html

How is CLIENT_INFO being replaced in R12?
Lets take an example.
In pre Release 12, you would have had following methodology for PO_HEADERS_ALL
a. A table is created in PO Schema, named PO_HEADERS_ALL
b. A synonym named PO_HEADERS_ALL is created in APPS schema, referring to PO.PO_HEADERS_ALL
c. Create a view PO_HEADERS in APPS schema, as "select * from po_headers_all where org_id=client_info"

But now in R12, following will happen
a. A table is created in PO Schema, named PO_HEADERS_ALL
b. A synonym named PO_HEADERS_ALL is created in APPS schema, referring to PO.PO_HEADERS_ALL
c. Another synonym named PO_HEADERS is created in APPS, referring to PO_HEADERS_ALL

d. A Row Level security is applied to PO_HEADERS, using package function MO_GLOBAL.ORG_SECURITY.
This can be double-checked by running SQL

select * from all_policies where object_name='PO_HEADERS'
 
e. The effect of this policy is that,whenever you access PO_HEADERS, Oracle RLS will dynamically append WHERE CLAUSE similar to below

SELECT * FROM PO_HEADERS
WHERE EXISTS (SELECT 1 FROM mo_glob_org_access_tmp oa WHERE oa.organization_id = org_id)

Explanation:



What is MO_GLOBAL.INIT
Purpose of mo_global.init :-
It will check if new Multi Org Security Profile is set, to decide if new Security Profile method will be used.
If the new MO security profile is set, then mo_global.init inserts one record, for each Organization in Org Hierarchy, in table mo_glob_org_access_tmp

What is the purpose of MO_GLOBAL.ORG_SECURITY?
The purpose of Row-Level-Security is to hide certain data[based on some conditions]. RLS does so by appending a where clause to the secured object.
1. MO_GLOBAL.ORG_SECURITY is a function that returns a predicate for the WHERE CLAUSE
2. The where clause will be appended to Table/Synonym/View for which Multi Org Row Level security is enabled

What is the purpose of MO_GLOBAL.SET_POLICY_CONTEXT ?
This procedure has two parameters
p_access_mode
Pass a value "S" in case you want your current session to work against Single ORG_ID
Pass a value of "M" in case you want your current session to work against multiple ORG_ID's
p_org_id
Only applicable if p_access_mode is passed value of "S"



FND_PROFILE and FND_GLOBAL values
[For more information, please visit http://docs.oracle.com/cd/E18727_01/doc.121/e12897/T302934T462356.htm]

Following are the FND_PROFILE values that can be used in the PL/SQL code:
   fnd_profile.value('PROFILEOPTION');
   fnd_profile.value('MFG_ORGANIZATION_ID');
   fnd_profile.value('ORG_ID');
   fnd_profile.value('LOGIN_ID');
   fnd_profile.value('USER_ID');
   fnd_profile.value('USERNAME');
   fnd_profile.value('CONCURRENT_REQUEST_ID');
   fnd_profile.value('GL_SET_OF_BKS_ID');
   fnd_profile.value('SO_ORGANIZATION_ID');
   fnd_profile.value('APPL_SHRT_NAME');
   fnd_profile.value('RESP_NAME');
   fnd_profile.value('RESP_ID');

Following are the FND_GLOBAL values that can be used in the PL/SQL code:
   FND_GLOBAL.USER_ID;
   FND_GLOBAL.APPS_INTIALIZE;
   FND_GLOBAL.LOGIN_ID;
   FND_GLOBAL.CONC_LOGIN_ID;
   FND_GLOBAL.PROG_APPL_ID;
   FND_GLOBAL.CONC_PROGRAM_ID;
   FND_GLOBAL.CONC_REQUEST_ID;

For example, I almost always use the following global variable assignments in my package specification to use throughout the entire package body:
   g_user_id      PLS_INTEGER  :=  fnd_global.user_id;
   g_login_id     PLS_INTEGER  :=  fnd_global.login_id;
   g_conc_req_id  PLS_INTEGER  :=  fnd_global.conc_request_id;
   g_org_id       PLS_INTEGER  :=  fnd_profile.value('ORG_ID');
   g_sob_id       PLS_INTEGER  :=  fnd_profile.value('GL_SET_OF_BKS_ID');

And initialize the application environment as follows:
   v_resp_appl_id  := fnd_global.resp_appl_id;
   v_resp_id       := fnd_global.resp_id;
   v_user_id       := fnd_global.user_id;
    
FND_GLOBAL.APPS_INITIALIZE(v_user_id,v_resp_id, v_resp_appl_id);

1 comment:

  1. SELECT fnd.user_id ,
    fresp.responsibility_id,
    fresp.application_id,
    fresp.responsibility_name
    FROM fnd_user fnd ,
    fnd_responsibility_tl fresp
    WHERE fnd.user_name = 'HCM'
    AND fresp.responsibility_name LIKE 'US%';

    l_user_id is the fnd user ID
    l_resp_id is the responsibility ID
    l_resp_appl_id is the responsibility application ID.

    EXEC fnd_global.APPS_INITIALIZE(l_user_id,l_resp_id,l_resp_appl_id);
    (OR)
    BEGIN
    fnd_global.APPS_INITIALIZE(l_user_id,l_resp_id,l_resp_appl_id);
    mo_global.init('appl_shrt_name');
    --Ex :: exec mo_global.init('AR');
    END;
    /
    Another option is Help > Diagnostics > Examine and get the values from $profile session values.
    To Initialize session
    SELECT fnd_global.session_id,USERENV('sessionid') FROM dual;

    INSERT INTO FND_SESSIONS VALUES
    (USERENV('sessionid'),TRUNC(sysdate)
    );

    ReplyDelete