Tuesday, October 11, 2011

DUAL TABLE ISSUES.

The SYS-owned dual table was introduced by Oracle long back and since then the Application
Development team across the globe has been using this table for some internal processing.

Getting multiple rows in DUAL can cause a variety of known issues.

If multiple rows are encountered,

for 9i and prior releases the DUAL Insertion and Deletion behavior was different from that in 10g and up.

In 9i and earlier versions the DUAL behavior was as follows:

SQL> connect sys/ as sysdba
SQL> select * from dual;
D
-
x
SQL> insert into dual values('Y');
SQL> insert into dual values('Z');
SQL> commit;
SQL> select count(*) from dual;
-> 3 rows
SQL> select * from dual;
-> retrieves only 1 row even if more rows exist
SQL> delete from dual;
SQL> commit;
SQL> select count(*) from dual;
-> 2 rows, only 1 row was deleted

In other words:

A "Delete from dual", statement without a where clause deletes only one row regardless of how many
rows it contains.

An "Insert into dual", works, and you can insert any number of rows, but when executing
"select * from dual", it returns only one row, but "select count(*) from dual", returns the number of rows that really was inserted.

For 10g and up the dual behaviour has changed as follows:
select * from dual;

D
-
X

select count(*) from dual;

COUNT(*)
----------
1

insert into dual select * from dual;

1 rows created.

select count(*) from dual;

COUNT(*)
----------
1

select * from dual;

D
-
X

delete from dual;

1 row deleted.

select * from dual;

D
-
X

select count(*) from dual;

COUNT(*)
----------
1

In Other words,

For 10g the dual behavior has changed to handle the multiple rows issue. But still it accepts multiple insertion to it and there is no way to know how many rows has been inserted as the Select count (*) returns
only 1 regardless of how many rows has been inserted, therefore TRUNCATE the DUAL then inserting the row again is the only way to bypass the issue.

To know exactly how many rows exits in 10g?

Create table test as select * from Dual;

Select count(*) from dual (it will show only 1 row irrespective it has more then 1 row also)

COUNT(*)

----------

1

select count(*) from test; (it will show the exact values)

COUNT(*)
----------------
3

###################################

How to Recreate the Dual Table:

. Shutdown the database

2. Startup the database in upgrade mode:

sqlplus / as sysdba
SQL> startup upgrade


3. Recreate the DUAL table:

create table dual
(dummy varchar2(1))
storage (initial 1)
/
insert into dual values('X')
/
create public synonym dual for dual
/
grant select on dual to public with grant option
/


4. Verify whether the DUAL table layout is correct:

column OWNER format a15;
OBJECT_NAME format a20;
select OWNER,OBJECT_NAME,OBJECT_TYPE,CREATED from dba_objects where object_name='DUAL';

Example output:

OWNER OBJECT_NAME OBJECT_TYPE CREATED
--------------- -------------------- ------------------- ---------
SYS DUAL TABLE 16-JUN-09
PUBLIC DUAL SYNONYM 16-JUN-09

5. Restart the database in normal mode

#############################





Monday, October 10, 2011

Using a Standard API to assign and Revoke Role/Responsibilities to a User.

col user_name for a15
col responsibility_name for a50
col user_guid for a35
select a.user_name,to_char(a.end_date,'DD-MON-YYYY')"User End",to_char(b.start_date,'DD-MON-YYYY')"Resp St",to_char(b.end_date,'DD-MON-YYYY')"Resp End",c.RESPONSIBILITY_NAME
from apps.fnd_user a,apps.fnd_USER_RESP_GROUPS b,apps.FND_RESPONSIBILITY_TL c
where a.USER_ID=b.USER_ID and b.RESPONSIBILITY_ID=c.RESPONSIBILITY_ID
and b.RESPONSIBILITY_APPLICATION_ID=c.APPLICATION_ID and a.user_name=upper('&fnd_user') order by 5;

set lines 200 pages 999;
col ROLE_NAME for a60;
select USER_NAME,ROLE_NAME,USER_START_DATE,USER_END_DATE,ROLE_START_DATE,ROLE_END_DATE,EFFECTIVE_END_DATE from apps.WF_LOCAL_USER_ROLES
where user_name = upper('&fnd_user');

select USER_NAME,ROLE_NAME,USER_START_DATE,USER_END_DATE,ROLE_START_DATE,ROLE_END_DATE,EFFECTIVE_END_DATE,END_DATE from apps.WF_USER_ROLE_ASSIGNMENTS
where user_name = upper('&fnd_user');

package to delete the responsibility:

SQL> Begin
fnd_user_pkg.delresp(
'&User_Name',
'&Res_Short_Name',
'&Responsibility_Key',
'&Security_Group');
commit;
End;


select * from fnd_security_groups
where security_group_key = 'STANDARD';

go to security user - > define -> enter the username
go to tools -> diagonise and enable the trace
and u can monitor waht is happining to that user when u are running anything backend to disable the user or delete the user.


############

1. Assign role to a user using an API

To assign role to a user using APIs, use the following API wf_local_synch.PropagateUserRole.

Example:

Begin
wf_local_synch.PropagateUserRole(
p_user_name => '&USER_NAME',
p_role_name => '&ROLE_KEY');
commit;
end;

2. Add a responsibility to a user using API fnd_user_resp_groups_api.Insert_Assignment

To add a responsibility to a user using and API, use the following API fnd_user_resp_groups_api.Insert_Assignment:

Example.

begin
fnd_user_resp_groups_api.Insert_Assignment (
user_id =>&USER_ID ,
responsibility_id => &RESP_ID,
responsibility_application_id =>$APPL_ID ,
start_date => &START_DATE,
end_date => &END_DATE,
description =>'Sample
example' );
commit;
end;

This shall raise an error if the responsibility is assigned to a user,
but if needed to update the responsibility assignment in case of responsibility existence,
use the following API:

begin
fnd_user_pkg.addresp(
'&User_Name',
'&Responsablity_Application_Short_Name',
'&Responsibility_Key',
'&Security_Group',
'&Description',
'&Start_Date',
'&End_Date' );
commit;
end;

3. Revoke a responsibility assignment to a user using fnd_user_pkg.delresp

To revoke a responsibility assignment to a user using an API, use fnd_user_pkg.delresp.

Example:

Begin
fnd_user_pkg.delresp(
'&User_Name',
'&Responsibility_application_short_name',
'&Responsibility_Key',
'&Security_Group');
commit;
End;

This simply end date the responsibility assignment to a user by the current system date.

4. Revoke an Indirect Responsibility

To revoke an indirect responsiblity (roles assigned using UMX) assignment to a user using APIs, use the following API Wf_local_synch.PropagateUserRole.

Example:

Begin
Wf_local_synch.PropagateUserRole(
p_user_name => '&USER_NAME',
p_role_name => '&ROLE_KEY',
p_start_date=>'&Start_Date',
p_expiration_date=>'&End_Date');
commit;
End;

End date the parent Role and it shall end date the remaining Roles.