Oracle concurrent programs initializes application context before running the actual code. Therefore, if we take out the SQLs from the concurrent program code (PLSQL or Reports) and execute in the development tools like Toad or SQL Developer, the results could be different. It could be due to 3 different kind of context variables
i. NLS Context variables:- Many language specific views (Eg:- FND_FLEX_VALUES_VL) will be deepndendent on the the NLS language context variable.
ii. Multi Org context variables :- Org specific synonyms(Eg:-PO_HEADERS) in R12 will not return any data unless we initialize the Multi Org context variables.
iii.Security Context variables:- Access to many Application Object library features (Eg:- Profile option values) is possible only after setting the fnd_global security variables (user_id, responsibility_id etc)
The below script accepts concurrent request id as input and initializes the context variables accordingly.
The intialized values can be found in DBMS OUTPUT.
Thursday, July 21, 2016
Wednesday, July 13, 2016
Oracle XML Publisher: Generate Skeleton XML data file from SQL
The below steps generates an XML data definition
data template from an SQL statement.
1.Define new concurrent program in EBS with required parameters.
2.Develop the SQL to fetch the data for the report.
3.Download and compile the helper PLSQL package xxxdo_generate_xml.sql
4.Execute the below script with SQL and concurrent program short name as parameters.
5.Save the DBMS output as XML data template file.
6. Upload the data template to Oracle using XML Publisher reponsibility
7. Submit the concurrent request to make sure that XML output is being generated.
The next step is to develop the layout. This is quiet userful to rapidly develop XML publisher reports from relatively simpler SQL.
1.Define new concurrent program in EBS with required parameters.
2.Develop the SQL to fetch the data for the report.
3.Download and compile the helper PLSQL package xxxdo_generate_xml.sql
4.Execute the below script with SQL and concurrent program short name as parameters.
5.Save the DBMS output as XML data template file.
6. Upload the data template to Oracle using XML Publisher reponsibility
7. Submit the concurrent request to make sure that XML output is being generated.
The next step is to develop the layout. This is quiet userful to rapidly develop XML publisher reports from relatively simpler SQL.
Wednesday, July 6, 2016
Identify the record causing an SQL statement to raise an Exception using LOG ERRORS feature
Oracle provides a powerful mechanism to uncover DML errors from version 10g Release 2 onwards. The LOG ERRORS clause is similar to SAVE EXCEPTIONS in PLSQL bulk operations. This feature can be used to identify the records the problematic records which cause an SQL statements to raise an exception.
SQL statements work in all or nothing principle. Even if a
single record causes an ‘Invalid Number’ exception, the entire SQL fails. It
could be a bit tricky to identify the record(s) which triggered the exception
when the SQL is complex and the dataset is large.
As an example, if we run the below SQL against Oracle
provided EMP table,
SELECT emp.*
,sal / comm sal_to_comm_ratio
FROM scott.emp emp;
The result will be ORA-01476 since there is atleast one
record where COMM is 0.
But the error message will not give a clue which record has
caused this issue. Identifying the record is key to fixing this issue either in
the SQL or in the database. Below steps can be performed to make use of
the LOG ERRORS feature.
Step 1 : Create a table using the SQL in error. We
just need the structure of the table. So please add a condition in the where
clause (1=2).
create table emp_test as
SELECT emp.*
,sal / comm sal_to_comm_ratio
FROM scott.emp emp
where 1=2;
Step 2: Create the error logging table for the new
table created.
begin
dbms_errlog.create_error_log(dml_table_name
=> 'EMP_TEST');
end;
This creates a table with name ERR$_EMP_TEST in the
database.
Step 3: Execute the SQL in an INSERT statement with
LOG ERRORS clause appended at the end.
INSERT INTO emp_test
SELECT emp.*
,sal / comm sal_to_comm_ratio
FROM
scott.emp emp LOG errors
INTO
err$_emp_test reject LIMIT unlimited;
This inserts all records without error to EMP_TEST while the
records in error will be kept in ERR$_EMP_TEST.
Step 4: Query up ERR$_EMP_TEST to see the error message
and records in error.
select * from ERR$_EMP_TEST;
PLSQL Script
Steps 1 to 3 can be automated using the below PLSQL script.
This script accepts the problem SQL as input and performs the steps.
DECLARE
l_sql_statement VARCHAR2(30000) := '&select';
l_create_table_sql VARCHAR2(32767);
l_insert_table_sql VARCHAR2(32767);
l_table_name VARCHAR2(30) := 'XXERR' || TO_CHAR(SYSDATE
,'DDMMYYYYHH24MISS');
l_error_table_name VARCHAR2(30) := 'ERR$_' || l_table_name;
BEGIN
l_create_table_sql := 'CREATE TABLE ' || l_table_name
||
' AS SELECT * FROM (' || l_sql_statement ||
') WHERE 1=2';
' AS SELECT * FROM (' || l_sql_statement ||
') WHERE 1=2';
dbms_output.put_line('Table name is ' || l_table_name);
dbms_output.put_line(l_create_table_sql);
EXECUTE IMMEDIATE l_create_table_sql;
dbms_errlog.create_error_log(dml_table_name => l_table_name);
l_insert_table_sql := 'INSERT INTO ' || l_table_name || ' SELECT * FROM (' ||
l_sql_statement || ') LOG ERRORS INTO err$_'
||l_table_name || ' (''INSERT'') REJECT LIMIT UNLIMITED';
EXECUTE IMMEDIATE l_insert_table_sql;
dbms_output.put_line('Error Messages are stored in table ' || l_error_table_name);
END;
On executing the script with SQL as input, the DBMS output
displays the name of the error table which can be queried to find the record(s)
in error.
Limitations
Limitations
- The single quotes in the SQL needs to be escaped when running from SQL*Plus or another IDE. This can be done by replacing all single quotes with 2 quotes.
- All derived values in the select clause list need to be given explicit aliases. Otherwise, the table creation will fail.
- This method can uncover only those issues arising from SELECT clause. The exceptions raised from FROM and WHERE clause will still fail the entire SELECT statement.
Tuesday, July 5, 2016
Oracle Time and Labor: Identify Layouts used by a timecard
OTL layouts are selected for an employee based on OTL Preferences
configuration. There could be many custom layouts defined in the
system. The SQL below accepts the employee number as prameter and
displays the layouts being used by the timecards entered for the
employee.
SELECT
person.full_name,
tc.start_time,
tc.stop_time,
tc.recorded_hours,
tc.approval_status,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute1) timecard_entry_layout,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute2) review_layout,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute3) confirmation_layout,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute4) detail_layout,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute5) export_layout,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute6) audit_layout,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute7) approval_fragment_layout,
(SELECT layout_name FROM hxc_layouts WHERE layout_id =
attr.attribute8) notification_layout
FROM
hxc_timecard_summary tc,
per_all_people_f person,
hxc_time_attribute_usages usag,
hxc_time_attributes attr
WHERE tc.resource_id =
person.person_id
AND SYSDATE BETWEEN person.effective_start_date
AND
person.effective_end_date
AND
person.employee_number = '&Employee_number'
AND tc.timecard_id =
usag.time_building_block_id
AND tc.timecard_ovn
= usag.time_building_block_ovn
AND
attr.time_attribute_id = usag.time_attribute_id
AND
attr.attribute_category = 'LAYOUT'
ORDER BY tc.start_time DESC;
Monday, July 4, 2016
Oracle eBusiness Suite: FRM-40501: ORACLE error: unable to reserve record for update or delete
This error message appears when the user while tries to update a record in Oracle eBusiness suite forms screen. Most of us knows the reason behind is that the same record is being updated by another user and the modifications have not been saved yet.
The below SQL can be used to list the details of the session which has locked any database object. You should be able to find the details of your record in this list.
WITH sessions_inline AS
(SELECT client_identifier user_name
,(SELECT responsibility_name
FROM
fnd_responsibility_vl
WHERE
responsibility_key = SUBSTR(action
,INSTR(action
,'/'
,1
,1) + 1)) responsibility
,DECODE(SUBSTR(module
,INSTR(module
,':'
,1
,2) + 1
,INSTR(module
,':'
,1
,3) - INSTR(module
,':'
,1
,2) - 1)
,'frm'
,'Forms Screen'
,'wf'
,'Workflow'
,'cp'
,'Concurrent Process'
,'fwk'
,'Self Service Page'
,'bes'
,'Business Event'
,'gsm'
,'Workflow') usage_type
,SUBSTR(module
,INSTR(module
,':'
,1
,3) + 1) ebs_module
,
ses.*
FROM
v$session ses
WHERE 1 = 1)
SELECT obj.object_name
,user_name
,responsibility
,usage_type
,ebs_module
,DECODE(usage_type
,'Forms Screen'
,DECODE(ebs_module
,'FNDSCSGN'
,'EBS Navigator'
,(SELECT user_form_name FROM fnd_form_vl WHERE form_name =
ebs_module))) forms_screen
,DECODE(usage_type
,'Concurrent Process'
,(SELECT user_concurrent_program_name FROM
fnd_concurrent_programs_vl WHERE concurrent_program_name = ebs_module))
concurrent_program
,DECODE(usage_type
,'Concurrent Process'
,(SELECT user_concurrent_queue_name FROM
fnd_concurrent_queues_vl WHERE concurrent_queue_name = ebs_module))
concurrent_manager
FROM sessions_inline ses
,v$locked_object lck
,all_objects obj
WHERE lck.session_id = ses.sid
AND obj.object_id = lck.object_id
ORDER BY ses.usage_type;
Note
The lock on database does not necessirily mean that all records are locked. So there could be multiple locks on the same table.
Note
The lock on database does not necessirily mean that all records are locked. So there could be multiple locks on the same table.
Subscribe to:
Posts (Atom)