Tuesday, December 7, 2010

Macro Security Settings for Excel 2007 & 2010 with Oracle E-Business Suite

Perform the below steps for the E-Business Suite WebADI component to function properly in Excel 2007 & 2010.

Excel 2010:
  • Click File -> Options
  • Click 'Trust Center' link in the 'Excel Options' window.
  • Click 'Trust Center Settings...' button.
  • In the 'Trust Center' window click 'Macro Settings' link from the menu on the left.
  • Under 'Macro Settings' check 'Disable all macros with notification'.
  • Under 'Developer Macro Settings' check 'Trust Access to the VBA project object model'.
  • Click 'OK' button to close the 'Trust Center' window.
  • Click 'OK' button to return to the spreadsheet.

Excel 2007:
  • Click the Office Button (top-left button in the window)
  • Click the 'Excel Options' button.
  • Click 'Trust Center' link from the menu on the left.
  • Click 'Trust Center Settings...' button.
  • In the 'Trust Center' window click 'Macro Settings' link from the menu on the left.
  • Under 'Macro Settings' check 'Disable all macros with notification'.
  • Under 'Developer Macro Settings' check 'Trust Access to the VBA project object model'.
  • Click 'OK' button to close the 'Trust Center' window.
  • Click 'OK' button to return to the spreadsheet.

Reference: Metalink note 1077728.1

Thursday, October 28, 2010

How to limit the User concurrent login sessions in E-Business Suite

In Oracle E-Business suite, a user can login to any number of sessions concurrently. EBS doesnot really restrict the user login sessions.

For ex., a user PLMMGR can login to EBS from two different browsers at the same time and perform actions in both the sessions.

We can however prevent such a concurrency by using the Business Event "oracle.apps.icx.security.session.created "


The event "oracle.apps.icx.security.session.created" if enabled will fire when ever a new session is created.

The event is raised via WF_EVENT.RAISE and it executes a rule function that takes the session_id and the fnd_user.user_id as parameters. This function will execute the following SQL script:

UPDATE ICX_SESSIONS
SET DISABLED_FLAG='Y'
WHERE USER_ID = <fnd_user>
AND SESSION_ID != <session_id>

What it basically does is to invalidate all other sessions of the same user. This way only one session persists for a user at any point of time.

reference: oracle metalink note 375403.1

Useful SQL Queries in E-Business Suite

1. Database
1.1 General Objects / Tables / Columns

PROMPT Find Object by Type, Name, Status
select object_name, object_type, owner, status
  from dba_objects
 where upper(object_name) like upper('%&object_name%')
   and object_type like upper('%'|| NVL('&object_type', 'TABLE')|| '%')
   and status like upper('%'|| NVL('&Status', '%')|| '%')
order by object_name, object_type;

PROMPT Find table indexes, keys, columns
select index_name,column_position,column_name
from all_ind_columns
where table_name = '&EnterTableName'
order by index_name, column_position;

PROMPT Find tables and columns that include a table and/or column name specified.
select table_name, column_name
from  dba_tab_columns
where column_name like NVL(UPPER('&COLUMN_NAME'), column_name)
  and table_name like NVL(UPPER('&TABLE_NAME'), table_name);

1.2 Invalids / Compiling
PROMPT Find Invalids
select object_name, object_type, owner, status
  from dba_objects
 where status = 'INVALID';
PROMPT Compile Packages
select 'alter package '|| object_name || ' compile '|| decode(object_type, 'PACKAGE', '', 'PACKAGE BODY', 'body')|| ';'
  from dba_objects
 where status = 'INVALID'
and object_type like 'PACK%';

1 .3 Bugs and Patching
PROMPT Find specific package version
select text from dba_source
where
   name = upper( '&PackageName')
    and line < 3;

PROMPT Find bugs already installed fixed in your system
select bug_number
  from ad_bugs
  where bug_number  ='&Bug_Number';

PROMPT Find patches applied
select substr(patch_name,1,12) patch_num
  from ad_applied_patches
 where patch_name like '%&Patch_Number%';

1.4 Other Objects

PROMPT Query view details of a specific view.
SELECT VIEW_NAME, TEXT
  FROM DBA_VIEWS
WHERE VIEW_NAME = UPPER('&VIEW_NAME')
  and owner = 'APPS';
PROMPT Trigger details on a table.
select TABLE_NAME, COLUMN_NAME, trigger_name, trigger_type, TRIGGER_BODY
from dba_TRIGGERS
WHERE TABLE_NAME like '%&EnterTableName%';

1.5 Helpful SQL Syntax
1.5.1 Rowid:
Working with Rowids: rowidtochar(rowid) and chartorowid('AAABUeAAQAAACsjAAg')

1.5.2 Date Columns


a. Converting dates to show date with time: to_char(<date> 'DD-MON-YYYY HH24:MI:SS') For example: select to_char(sysdate, 'DD-MON-YYYY HH24:MI:SS') from dual;
b. Comparing date columns -- Sometimes handy to skip the time portion when searching for dates. You can use the trunc command to strip the time off. This resets the time to midnight.
For example: select to_char(trunc(sysdate), 'DD-MON-YYYY HH24:MI:SS') from dual;


2. Foundation (FND/ATG/AOL)

2.1 SQL related to Oracle Application Messages

PROMPT ATG
PROMPT Find Messages by Message Text
select m.message_name, m.message_text, m.message_number, a.application_short_name
from fnd_new_messages m, fnd_application a
where upper(m.message_text) like upper('%&EnterMessageText%')
and m.language_code = 'US'
and m.application_id = a.application_id;

PROMPT Find Messages by Message Short Name
select m.message_name, m.message_text, m.message_number, a.application_short_name
from fnd_new_messages m, fnd_application a
where m.message_name like '%&EnterMessageName%'
and m.language_code = 'US'
and m.application_id = a.application_id;

2.2. Review Oracle Application Programs



a. Looking for trace files (Also see Note 296559.1 for more examples on various versions / releases.)
PROMPT IDENTIFY CONCURRENT REQUEST FILE
PROMPT From Bug.3211206
PROMPT Use the following query to identify the correct trace file:
PROMPT where "request" is the concurrent request id for the inventory transaction
PROMPT worker.
SELECT 'Request id: '||request_id ,
'Trace id: '||oracle_Process_id,
'Trace Flag: '||req.enable_trace,
'Trace Name:
'||dest.value||'/'||lower(dbnm.value)||'_ora_'||oracle_process_id||'.trc',
'Prog. Name: '||prog.user_concurrent_program_name,
'File Name: '||execname.execution_file_name|| execname.subroutine_name ,
'Status : '||decode(phase_code,'R','Running')
||'-'||decode(status_code,'R','Normal'),
'SID Serial: '||ses.sid||','|| ses.serial#,
'Module : '||ses.module
from fnd_concurrent_requests req, v$session ses, v$process proc,
v$parameter dest, v$parameter dbnm, fnd_concurrent_programs_vl prog,
fnd_executables execname
where req.request_id = &request
and req.oracle_process_id=proc.spid(+)
and proc.addr = ses.paddr(+)
and dest.name='user_dump_dest'
and dbnm.name='db_name'
and req.concurrent_program_id = prog.concurrent_program_id
and req.program_application_id = prog.application_id
and prog.application_id = execname.application_id
and prog.executable_id=execname.executable_id;

b. Another for programs and managers:
PROMPT Programs and Managers
PROMPT Provide various output of concurrent managers related to a specific program.
PROMPT In this case using default of Item Supply/Demand program.
SELECT
fcq.processor_application_id, fcp.concurrent_program_name,
fr.responsibility_id, fr.responsibility_key, fr.data_group_id, fr.request_group_id,
fr.application_id, fa.application_short_name,
fcq.concurrent_queue_id, fcq.CONCURRENT_QUEUE_NAME,
fcq.MIN_PROCESSES, fcq.TARGET_PROCESSES, fcq.TARGET_NODE, fcq.SLEEP_SECONDS, fcq.CONTROL_CODE, fcq.DIAGNOSTIC_LEVEL,
fcpr.*
FROM fnd_application fa,
fnd_concurrent_programs fcp,
fnd_conc_processor_programs fcpp,
fnd_responsibility fr,
fnd_concurrent_queues fcq,
fnd_concurrent_processes fcpr
WHERE fcq.processor_application_id = fcpp.processor_application_id
AND fcq.concurrent_processor_id = fcpp.concurrent_processor_id
AND fcpp.concurrent_program_id = fcp.concurrent_program_id
AND fcpp.program_application_id = fcp.application_id
AND fcp.application_id = fa.application_id
AND fcp.concurrent_program_name = NVL('&EnterProgramShortName', 'INXDSD')
AND fr.application_id = 401
AND fr.data_group_id = fcq.data_group_id
AND fcq.manager_type = '3'
AND fcpr.concurrent_queue_id = fcq.concurrent_queue_id
AND fcpr.queue_application_id = fcq.application_id
-- AND fcpr.process_status_code = 'A'
AND fcpr.instance_number = userenv('instance')
ORDER BY dbms_random.random;



c. Concurrent program statuses


PROMPT Concurrent program values
Select distinct lookup_code, meaning From Fnd_Lookup_Values
Where Lookup_Type = 'CP_STATUS_CODE'
order by lookup_code;
A Waiting
B Resuming
C Normal
D Cancelled
E Error
G Warning
H On Hold
I Normal
M No Manager
P Scheduled
Q Standby
R Normal
S Suspended
T Terminating
U Disabled
W Paused
X Terminated
Z Waiting

d. Submitted Concurrent Programs
Select * From Fnd_Concurrent_Requests
Where Request_Id = &YourRequestID;
Example Output:
Phase_Code: C
Status_Code: G
Argument_Text: 207, 2, , Jbp1-M1-10, ,
Argument1: 207
Argument2: 2
Argument3: Null
Argument4: JTP1-M1-10
CONCURRENT_PROGRAM_ID: 31534

e. Ensure trace is disabled
The best way is to check via the forms System Administrator > Concurrent > Programs > Define. This is just a quick update to change trace enabled to no.
Update Fnd_Concurrent_Programs
Set Enable_Trace = 'N'
where ENABLE_TRACE = 'Y';


2.3. Users and Responsibilities
a. Basic user check


PROMPT Basic check for user details
select user_id, user_name, employee_id
from fnd_user
where user_name like '&EnterUserName%';
b. Active users


PROMPT Active Users
select fnd.user_name, icx.responsibility_application_id, icx.responsibility_id, frt.responsibility_name,
icx.session_id, icx.first_connect,
icx.last_connect,
DECODE ((icx.disabled_flag),'N', 'ACTIVE', 'Y', 'INACTIVE') status
from
fnd_user fnd, icx_sessions icx, fnd_responsibility_tl frt
where
fnd.user_id = icx.user_id
and icx.responsibility_id = frt.responsibility_id
and icx.disabled_flag <> 'Y'
and trunc(icx.last_connect) = trunc(sysdate)
order by icx.last_connect;

c. Users with a responsibility
There is also a similar concurrent program "Users of a Responsibility".
PROMPT Find users who have a responsibility
select usr.user_id, usr.user_name, res.RESPONSIBILITY_ID, res.RESPONSIBILITY_NAME
from apps.FND_USER usr, apps.FND_RESPONSIBILITY_TL res, apps.FND_USER_RESP_GROUPS grp
where upper(res.RESPONSIBILITY_NAME) like upper('%' || NVL('&EnterRespName', 'INV')|| '%')
and upper(res.RESPONSIBILITY_NAME) NOT like '%AX%'
and upper(res.RESPONSIBILITY_NAME) NOT like '%OPM%'
and grp.responsibility_id = res.responsibility_id
and grp.user_id = usr.user_id;

d. Values of a profile option


It is sometimes hard to know where a profile option is set. A user might have a profile option set, an application, responsibility, and these might result in unexpected results. The following prompts for the profile name that a user sees. You could also query for the internal profile code instead by using the column a.profile_option_name instead.
select
b.user_profile_option_name "Long Name"
, a.profile_option_name "Short Name"
, decode(to_char(c.level_id),'10001','Site'
,'10002','Application'
,'10003','Responsibility'
,'10004','User'
,'Unknown') "Level"
, decode(to_char(c.level_id),'10001','Site'
,'10002',nvl(h.application_short_name,to_char(c.level_value))
,'10003',nvl(g.responsibility_name,to_char(c.level_value))
,'10004',nvl(e.user_name,to_char(c.level_value))
,'Unknown') "Level Value"
, c.PROFILE_OPTION_VALUE "Profile Value"
, c.profile_option_id "Profile ID"
, to_char(c.LAST_UPDATE_DATE,'DD-MON-YYYY HH24:MI') "Updated Date"
, nvl(d.user_name,to_char(c.last_updated_by)) "Updated By"
from
apps.fnd_profile_options a
, apps.FND_PROFILE_OPTIONS_VL b
, apps.FND_PROFILE_OPTION_VALUES c
, apps.FND_USER d
, apps.FND_USER e
, apps.FND_RESPONSIBILITY_VL g
, apps.FND_APPLICATION h
where
--a.application_id = nvl(401, a.application_id)
--and a.profile_option_name = nvl('INV', a.profile_option_name)
b.user_profile_option_name like '&ProfileName' -- 'AFLOG_ENABLED'
and a.profile_option_name = b.profile_option_name
and a.profile_option_id = c.profile_option_id
and a.application_id = c.application_id
and c.last_updated_by = d.user_id (+)
and c.level_value = e.user_id (+)
and c.level_value = g.responsibility_id (+)
and c.level_value = h.application_id (+)
order by
b.user_profile_option_name, c.level_id,
decode(to_char(c.level_id),'10001','Site'
,'10002',nvl(h.application_short_name,to_char(c.level_value))
,'10003',nvl(g.responsibility_name,to_char(c.level_value))
,'10004',nvl(e.user_name,to_char(c.level_value))
,'Unknown');


e. SQL statement to count concurrent_users in Oracle apps:


select count(distinct d.user_name) from apps.fnd_logins a,
v$session b, v$process c, apps.fnd_user d
where b.paddr = c.addr
and a.pid=c.pid
and a.spid = b.process
and d.user_id = a.user_id
and (d.user_name = 'USER_NAME' OR 1=1)


f. Number Of Times A User Connected To A Responsibility

select f.RESPONSIBILITY_NAME, count(*) from icx_sessions i, fnd_responsibility_tl f where user_id=0
and i.RESPONSIBILITY_ID=f.RESPONSIBILITY_ID group by f.RESPONSIBILITY_NAME;
.

2.4 Set Context / Initialize
Sometimes you want to run queries that reference profile options. To do this, you should first initialize the context of the current session to the user, responsibility and application being used. You can also set the context of the current inventory organization for queries that reference the organization context.

a. Set context
PROMPT Initialize context of profiles, etc.
PROMPT Note you can query the user id, responsibility id,
PROMPT and application id from the FND tables.
execute fnd_global.APPS_INITIALIZE(&UserID, &ResponsibilityID, &ApplicationID);

b. Set organization
PROMPT Set organization
PROMPT Note you can query the organization idea from mtl_parameters.
execute fnd_client_info.set_org_context('&OrganizationID');
 

Ref: Oracle Metalink Note 731190.1, 295206.1, 944233.1