DBMS_UTILITY.FORMAT_ERROR_BACKTRACE in 9i
Hello,
I have a procedure that calls a lot of procedures, functions, packages in 9i database.
I'm trying to send an email with the error information whenever an error prevents the procedure to execute with success.
I searched something about this and i'm using this code for trapping the possible error:
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
DBMS_OUTPUT.PUT_LINE ('error code ' || SQLCODE);
DBMS_OUTPUT.PUT_LINE ('error MESSAGE ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE ('ERROR STACK:' ||DBMS_UTILITY.FORMAT_ERROR_STACK);
END;
But in this information is missing the exactly program (function, procedure or package) and line number.
I could do this using
DBMS_OUTPUT.PUT_LINE ('ERROR BACKTRACE:' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
But i think is not available on database 9i.
How can i get this kind of result in database 9i?
Thank you.
Rute
Hello,
the DBMS_UTILITY.FORMAT_CALL_STACK gives me:
ERROR STACK:ORA-01407: cannot update ("DVA2"."P1ALLA"."CFASTC") to NULL
ERROR STACK:----- PL/SQL Call Stack -----
object line object
handle number
name
66D1BDD4 453 procedure DVA2.P1053FCLNV
655EEB28 2 anonymous block
That gives me the error "ORA-01407: cannot update ("DVA2"."P1ALLA"."CFASTC") to NULL", gives the name and line in the principal procedure "453 procedure DVA2.P1053FCLNV" but it does not give the name of the package where the error ocurred!
There is anything else?
Thank you.
Similar Messages
-
FOR loop messes up the DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
Hello!
I've encountered the following problem which could be resolved for now
by eliminating FOR loop, but that's not a good solution.
The problem is that if some exception is raised inside the `for' loop
with cursor, and the outer block contains exception handler with
`format_error_backtrace' call, the last one shows not the exact line
where the exception was raised, but the loop beginning. Let me show
you.
The next block loops over some table and tries to assign one of the
field's value to local variable with intentionally low
precision. Please look at line where exception is raised:
========================================
SQL> ed
Wrote file afiedt.buf
1 declare
2 x number(1);
3 begin
4 for x_r in (select xlong from xtable)
5 loop
6 dbms_output.put_line('Processing... '|| x_r.xlong);
7 x := x_r.xlong;
8 end loop;
9* end;
SQL> /
Processing... 611911
declare
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: number precision too large
ORA-06512: at line 7========================================
Next, I'll put exception handler with `format_error_message' call in
it:
========================================
SQL> ed
Wrote file afiedt.buf
1 declare
2 x number(1);
3 begin
4 for x_r in (select xlong from xtable)
5 loop
6 dbms_output.put_line('Processing... '|| x_r.xlong);
7 x := x_r.xlong;
8 end loop;
9 exception
10 when others then
11 dbms_output.put_line(dbms_utility.format_error_backtrace);
12* end;
SQL> /
Processing... 611911
ORA-06512: at line 4========================================
Now look how line number changed; instead of 7'th line it is 4'th
now -- at the beginning of the loop.
Now, let's expand this loop into explicit open/fetch/close sequence:
========================================
SQL> ed
Wrote file afiedt.buf
1 declare
2 x number(1);
3 cursor x_c is select xlong from xtable;
4 x_r x_c%rowtype;
5 begin
6 open x_c;
7 loop
8 fetch x_c into x_r;
9 exit when x_c%notfound;
10 dbms_output.put_line('Processing... '|| x_r.xlong);
11 x := x_r.xlong;
12 end loop;
13 close x_c;
14 exception
15 when others then
16 dbms_output.put_line(dbms_utility.format_error_backtrace);
17* end;
SQL> /
Processing... 611911
ORA-06512: at line 11========================================
Here we see that line number where exception was raised is now
correct!
I suppose the problem is in some hidden exception handling behind the
`for' loop execution. Any help will be appreciated, thanks in advance!
Message was edited by:
uj2uj2,
I think the reason is probably PL/SQL optimisation. Because you are using backtrace, it means you are on 10g. This means you have an automatic PLSQL_OPTIMIZE_LEVEL of 2. At this level, the compiler will re-write your cursor-for-loop to array fetches "under the covers", so my feeling is that the internal code re-organisation might have something to do with it.
Can you try your cursor-for-loop example with these settings:
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 0;
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 1;
Neither of these levels optimise cursor-for-loops.
The reason your explicit fetch doesn't display the same behaviour is that the compiler doesn't optimise those.
Of course I could be wrong, but this is where I'd start testing.
Regards -
How to get the entire trace with dbms_utility.format_error_backtrace
Hi,
I made 35 procedures where test35 is
calling test34 and test34 is calling test33 etc.
division-by-zero is in test1 and format_error_backtrace shows the trace up to test31.
Just curious, is it possible to get the entire trace?
Thanks
An example
SQL> BEGIN
2 EXECUTE IMMEDIATE 'create or replace procedure test1 as a number; begin a:=1/0; end;';
3 FOR i IN 2..35 LOOP
4 execute immediate 'create or replace procedure test'||i||' as begin test'||(i-1)||'; end;';
5 END LOOP;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> BEGIN
2 test35;
3 EXCEPTION WHEN OTHERS THEN
4 dbms_output.put_line(dbms_utility.format_error_backtrace);
5 END;
6 /
ORA-06512: at "ANTS.TEST1", line 1
ORA-06512: at "ANTS.TEST2", line 1
ORA-06512: at "ANTS.TEST30", line 1
ORA-06512: at
"ANTS.TEST31", line 1
ORA-06512: at line 2Out of interest, do you get any further back if each error message is shorter (e.g. a shorter procedure name)? From a quick test, SQLERRM is limited to 510 characters (doubtless documented somewhere though I can't find it just now) - the documentation says FORMAT_ERROR_BACKTRACE is not subject to the same size limitation, but that doesn't mean there is no size limitation.
-
Challenge: Grab N rows AFTER performing sort
I am not an SOA developer, but am working with a team of people who use the tool to develop software for us. I have stated a business requirement which the developers tell me SOA cannot do. I am certain they are wrong, but not being versed in SOA, I'm unable to debate the point without turning to experts for help.
All I want to do is select N+ rows from my table after it has been sorted on the "importance" column, i.e., "Give me the top 100 rows ordered by importance". I am also filtering on a "status" column, taking only those rows that have statue='A'.
To code this in raw SQL, I would simply say:
SELECT *
FROM (
SELECT <my fields>
FROM <my table>
WHERE
STATUS = 'A'
ORDER BY importance ASC
) where rownum <=100
The way they have solved this issue in SOA is generating the following (again in native SQL):
SELECT <my fields>
FROM <my table>
WHERE
STATUS = 'A'
AND ROWNUM <=100
ORDER BY importance ASC
These two are not equivalent, and the second query does not satisfy the goal. The developers are telling me that it is impossible to satisfy my query using SOA.
The actual SQL that got generated by SOA is:
SELECT <my fields>
FROM <my table>
WHERE
STATUS = :1
AND ROWNUM <= :2
ORDER BY importance ASC
FOR UPDATE NOWAIT
Is there some way to get SOA to generate THIS instead? :
SELECT <my fields>
FROM (
SELECT <my fields>
FROM <my table>
WHERE
STATUS = :1
ORDER BY importance ASC
WHERE ROWNUM <= :2
FOR UPDATE NOWAIT
Edited by: user10593614 on Apr 26, 2012 6:49 AMThe DB Adapter is able to call PLSQL API's.
I have copied and pasted some code we used from one of recent patches:
- Create a type var for the results of your query
CREATE OR REPLACE TYPE ICSOA_ARAUTOINV_DISTRIB_TYP AS OBJECT(
FIELD1 VARCHAR2(30),
FIELD2 VARCHAR2(30)
- Create a table of this type
CREATE OR REPLACE TYPE ICSOA_ARAUTOINV_DISTRIB_TBL AS TABLE OF ICSOA_ARAUTOINV_DISTRIB_TYP;
- Create your PLSQL using the params you need as simple types something like: (In a package)
function CreateAction(
p_param1 in number,
p_parm2 in VARCHAR2,
p_result out ICSOA_ARAUTOINV_DISTRIB_TBL,
p_err_message out varchar2
) return number;
- your fuction devlaration section needs a cursor something like
cursor c_lines_rsp(p_1 in number, p_2 in varchar2) is
select ICSOA_ARAUTOINV_DISTRIB_TYP(123,'rrr') from dual
where p_1=1 and p_2='abc';
- in your plsql have it return 0 on success and in the exception handler get it to put the error message in p_err_message:
begin
--use cursor to get data
OPEN c_lines_rsp(p_param1,p_param2);
FETCH c_lines_rsp BULK COLLECT INTO p_result;
CLOSE c_lines_rsp;
return 0;
EXCEPTION
WHEN OTHERS THEN
x_err_message := 'Unknown Error ' || sqlerrm || ' ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
return 99;
end;
If you point the DB adapater at this it will create all the nessecary xml's and wsdls. It should be easy to call this from a BPEL process.
The DB Adapter will create the object var and table but prefer creating my own as it fits in better with the patching process.
From experence I have learned to always return the error message to BPEL it makes debugging a lot easier.
oh and you shouldn't use and commit or rollback statements in your PLSQL if you are using XA db connections. (SOA will preform a commit for you)
Robert
Edited by: RobertMetcalf on Apr 26, 2012 4:09 PM -
MERGE statement - Source with duplicate values not raising error ora-30926
Hi ,
I'm having a problem with merge that has already been reported in another thread ( Re: MERGE strange behavior ). I created a procedure with a query and have tested inserting two equal values on the Key column to raise the error. But on the first time there i run the Procedure it runs without error, apparently updating with the first row found. On the second time there i run the procedure then Oracle raises the error.
Above you can see the code to simulate the issue:
-- creating the table
create TABLE teste
( ID NUMBER NOT NULL , DESCR VARCHAR2 (20 CHAR) , GRUPO VARCHAR2 (30 CHAR) );
-- inserting the pk in table
ALTER TABLE Teste
ADD CONSTRAINT DimTestec_PK PRIMARY KEY ( ID ) ;
-- inserting records in the table
insert into teste
select -2 AS id,'t-2' AS descr,'t-2g' AS grupo from dual
union all
select -1 AS id,'t-1' AS descr,'t-1g' AS grupo from dual
union all
select 1 AS id,'t1' AS descr,'t1g' AS grupo from Dual
union all
select 2 AS id,'t2' AS descr,'t2g' AS grupo from Dual
union all
select 3 AS id,'t3' AS descr,'t3g' AS grupo from Dual
union all
select 4 AS id,'t4' AS descr,'t4g' AS grupo from Dual
union all
select 5 AS id,'t5' AS descr,'t4g' AS grupo from Dual
--create the procedure to teste the merge
create or replace procedure mergeteste is
Begin
MERGE INTO teste testemerge
USING ( select -2 AS id,'t-2' AS descr,'t-2g' AS grupo from dual
union all
select -1 AS id,'t-1' AS descr,'t-1g' AS grupo from dual
union all
select 1 AS id,'t1' AS descr,'t1g' AS grupo from Dual
union all
select 2 AS id,'t2' AS descr,'t2g' AS grupo from Dual
union all
select 3 AS id,'t3' AS descr,'t3g' AS grupo from Dual
union all
select 4 AS id,'t4' AS descr,'t4g' AS grupo from Dual
union all
select 5 AS id,'t5' AS descr,'t4g' AS grupo from Dual
union all
select 5 AS id,'t6' AS descr,'t6' AS grupo from Dual ) testesource
ON (testemerge.id = testesource.id)
WHEN MATCHED THEN
UPDATE SET testemerge.descr = testesource.descr,
testemerge.grupo = testesource.grupo
WHEN NOT MATCHED THEN
INSERT ( testemerge.id, testemerge.descr, testemerge.grupo )
VALUES ( testesource.id, testesource.descr, testesource.grupo ) ;
commit work;
EXCEPTION
WHEN OTHERS THEN
begin
ROLLBACK;
dbms_output.put_line(dbms_utility.format_error_stack||dbms_utility.format_error_backtrace);
end;
end mergeteste;
-- the first time you execute the procedure, it runs without error - when it shouldn't run cause there's two id with value 5 on the testesource query.
-- the second time it raises the expected error.
Here's the oracle version:
1 Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
2 PL/SQL Release 11.2.0.3.0 - Production
3 CORE 11.2.0.3.0 Production
4 TNS for Linux: Version 11.2.0.3.0 - Production
5 NLSRTL Version 11.2.0.3.0 - Production
Thanks in advance.
Best Regards.
Renan RibeiroHi, Renan,
That sounds like a bug. In Oracle 11.1, I get the error the first time I run the procedure, but in Oracle 11.2, I get the same results you do (that is, no error the first time I run the procedure, error the second time). -
ORA-06508 - PL/SQL: could not find program unit being called
Hi,
I'm working on an Oracle Database 11g Release 11.1.0.6.0 - 64bit Production With the Real Application Clusters option.
Since 2 weeks I'm facing problems with a job.
The job executes
dispatch.pk_process.check_geofence;every 2 seconds, forces to run on instance 1.
Some time, now it's once a day, in a different moment, the job start failing returning the ORA-06508.
The job body is:
PROCEDURE check_geofence
IS
CURSOR tt IS
SELECT id_data, id_device, id_vehicle, date_event, date_write
FROM t_process
WHERE id_type_process = ln_process_geofence
ORDER BY date_event;
id_user_ NUMBER;
errc_ NUMBER;
errm_ VARCHAR2(500);
i NUMBER;
BEGIN
id_user_ := dispatch.pk_security.login_hard('process_geofence','process_geofence');
i := 0;
FOR t IN tt LOOP
BEGIN
pk_space_target.check_inout_space_target (
in_id_data => t.id_data,
in_id_device => t.id_device,
in_id_vehicle => t.id_vehicle,
id_date_event => t.date_event,
id_date_write => t.date_write
EXCEPTION
WHEN OTHERS THEN
errm_ := 'process geofence: '||SUBSTR(SQLERRM, 1, 500)||' - '||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
errc_ := SQLCODE;
INSERT INTO t_data_error (id_data, date_error, error_number, error_message)
VALUES (t.id_data, SYSDATE, errc_, errm_);
END;
DELETE FROM t_process WHERE id_data = t.id_data AND id_type_process = ln_process_geofence;
i := i + 1;
IF i mod 100 = 0 THEN COMMIT; END IF;
END LOOP;
id_user_ := dispatch.pk_security.logout;
END;the error is returned while executing the procedure
pk_space_target.check_inout_space_targetI know the ORA-06508 could happen on open connections after a recompile.
But I did not recompile anything.
The only solution that works is to compile package pk_space_target introducing some error (decompile it) and re-compile without the error.
Than to the same with pk_process.
After the last recompile, everything start to work fine again.
Do you have any suggestion on how/what investigate?
I cannot find any cause!!
Thanks in advance,
SamuelAt the end I opend a SR and the problem was a timestamp mistmatch between 2 packages:
Connected to:
Oracle Database 11g Release 11.1.0.6.0 - 64bit Production
With the Real Application Clusters option
SQL> alter session set nls_date_format='dd-mon-yy hh24:mi:ss';
Session altered.
SQL> select do.name dname, po.name pname, p_timestamp, po.stime p_stime
2 from sys.obj$ do, sys.dependency$ d, sys.obj$ po
3 where p_obj#=po.obj#(+)
4 and d_obj#=do.obj#
5 and do.status=1 /*dependent is valid*/
6 and po.status=1 /*parent is valid*/
7 and po.stime!=p_timestamp /*parent timestamp does not match*/
order by 2,1; 8
DNAME
PNAME
P_TIMESTAMP P_STIME
PK_EVOLUTION
PK_SPATIAL
15-sep-11 08:50:11 09-oct-12 10:01:32Then I re-compiled the pk_evolution, and the row disappeared:
SQL> r
1 select do.name dname, po.name pname, p_timestamp, po.stime p_stime
2 from sys.obj$ do, sys.dependency$ d, sys.obj$ po
3 where p_obj#=po.obj#(+)
4 and d_obj#=do.obj#
5 and do.status=1 /*dependent is valid*/
6 and po.status=1 /*parent is valid*/
7 and po.stime!=p_timestamp /*parent timestamp does not match*/
8* order by 2,1
no rows selectedThis solved the problem.
Samuel -
How to compare two tables data...need sql report or utility to find differe
Hi,
We have a requirement where we are asked to find data differences between two tables and one of the tables reside on remote database. The database version is same ( 10g ) and datatypes for the tables are similar.
The client is looking for a sql report or kind of utility to display the data differences for each column ( if possible count differences ) with some meaningful error messages.
Could anyone let me know the best possible way of doing it..?
Thanks
HitarthHi,
I found something for tables comparison but getting one error...can you check this please and let me know what is wrong
Here is the function:
CREATE OR REPLACE FUNCTION compare_query_results (
p_query1 IN VARCHAR2
, p_query2 IN VARCHAR2
, p_raise_error_if_not_equal IN BOOLEAN DEFAULT FALSE
, p_raise_error_if_no_rows IN BOOLEAN DEFAULT FALSE
RETURN NUMBER
IS
-- Constants
c_query_results_equal CONSTANT PLS_INTEGER := 0;
c_query_results_not_equal CONSTANT PLS_INTEGER := 1;
oracr CONSTANT VARCHAR2 (1) := CHR (10);
-- Variable Declaration
v_sql_stmt VARCHAR2 (32767);
v_record_count PLS_INTEGER;
v_return_code PLS_INTEGER;
v_record DUAL.dummy%TYPE;
v_result_set_has_rows BOOLEAN;
-- Ref Cursors
v_cursor sys_refcursor;
-- Custom Defined-Exceptions
result_sets_do_not_match EXCEPTION;
query_returns_no_rows EXCEPTION;
BEGIN
-- Get the count of differing records between p_query1 and p_query2
dbms_output.put_line('Start-1');
v_sql_stmt :=
' (SELECT /*+ materialize */'
|| SUBSTR (p_query1, INSTR (UPPER (p_query1)
, 'SELECT'
, 1
, 1
) + 6)
|| ')
, (SELECT /*+ materialize */'
|| SUBSTR (p_query2, INSTR (UPPER (p_query2)
, 'SELECT'
, 1
, 1
) + 6)
|| ')
SELECT ''X''
FROM (
(SELECT * FROM test1 MINUS SELECT * FROM test2)
UNION ALL
(SELECT * FROM test2 MINUS SELECT * FROM test1)
dbms_output.put_line('Start-2');
OPEN v_cursor
FOR v_sql_stmt;
dbms_output.put_line('Start-3');
FETCH v_cursor
INTO v_record;
dbms_output.put_line('Start-4');
v_result_set_has_rows := v_cursor%FOUND;
dbms_output.put_line('Start-5');
CLOSE v_cursor;
dbms_output.put_line('Start-6');
-- If there are rows - the result sets do NOT match...
IF v_result_set_has_rows
THEN
v_return_code := c_query_results_not_equal;
IF p_raise_error_if_not_equal
THEN
RAISE result_sets_do_not_match;
END IF;
-- If there are no rows - the result sets do match...
ELSIF NOT v_result_set_has_rows
THEN
IF p_raise_error_if_no_rows
THEN
-- Check to make sure that the queries contain rows if desired...
v_sql_stmt := 'SELECT ''X''
FROM (' || oracr || p_query1 || oracr || ')';
OPEN v_cursor
FOR v_sql_stmt;
FETCH v_cursor
INTO v_record;
IF v_cursor%NOTFOUND
THEN
CLOSE v_cursor;
RAISE query_returns_no_rows;
END IF;
CLOSE v_cursor;
END IF;
v_return_code := c_query_results_equal;
END IF;
RETURN v_return_code;
EXCEPTION
WHEN result_sets_do_not_match
THEN
raise_application_error (-20101, 'The Queries'' result sets do NOT match. Error returned
as requested.');
WHEN query_returns_no_rows
THEN
raise_application_error (-20102, 'The Queries'' result sets match, however they contain no
rows. Error returned as requested.');
WHEN OTHERS
THEN
-- Raise the error
raise_application_error (-20103
, 'There is a syntax or semantical error in one or both queries
preventing comparison.'
|| oracr
|| 'Error Stack :'
|| oracr
|| DBMS_UTILITY.format_error_stack ()
|| oracr
|| 'Error_Backtrace:'
|| oracr
|| DBMS_UTILITY.format_error_backtrace ());
END compare_query_results;
I have created two tables ( test1 and test2 ) with few columns and with the same datatypes and executed the above function...I am getting error as folliowing:
DECLARE
ERROR at line 1:
ORA-20103: There is a syntax or semantical error in one or both queries
preventing comparison.
Error Stack :
ORA-00900: invalid SQL statement
Error_Backtrace:
ORA-06512: at "ORAOWNER.COMPARE_QUERY_RESULTS", line 53
ORA-06512: at "ORAOWNER.COMPARE_QUERY_RESULTS", line 121
ORA-06512: at line 12
Could someone please help me fixing this error..It would be really appreciated
Thanks
Hitarth -
How to prevent duplication on a column with condition
Hello everyone,
I need some advice here. At work, we have an Oracle APEX app that allow user to add new records with the automatic increment decision number based on year and group name.
Says if they add the first record , group name AA, for year 2012, they get decision number AA 1 2013 as their displayed record casein the report page.
The second record of AA in 2013 will be AA 2 2013.
If they add about 20 records , it will be AA 20 2013.
The first record for 2014 will be AA 1 2014.
However, recently , we get a user complaint about two records from the same group name have the same decision number.
When I looked into the history table, and find that the time gap between 2 record is just about 0.1 seconds.
Besides, we have lookup table that allows admin user to update the Start Sequence number with the restraint that it has to be larger than the max number of the current group name of the current year.
This Start sequence number and group name is stored together in a table.
And in some other special case,user can add a duplicate decision number for related record. (this is a new function)
The current procedure logic to add new record on the application are
_Get max(decision_number) from record table with chosen Group Name and current year.
_insert into the record table the new entered record with decision number + 1
_ update sequence number to the just added decision number.
So rather than utitlising APEX built-in automatic table modification process, I write a procedure that combine all the three process.
I run some for loop to continuously execute this procedure, and it seems it can autotically generate new unique decision number with time gap about 0.1 second.
However, when I increase the number of entry to 200, and let two users run 100 each.
If the time gap is about 0.01 second, Duplicate decision numbers appear.
What can I do to prevent the duplication ?
I cannot just apply a unique constraint here even for all three columns with condition, as it can have duplicate value in some special condition. I don't know much about using lock and its impact.
This is the content of my procedure
create or replace
PROCEDURE add_new_case(
--ID just use the trigger
p_case_title IN varchar2,
p_year IN varchar2,
p_group_name IN VARCHAR2,
--decisionnumber here
p_case_file_number IN VARCHAR2,
--active
p_user IN VARCHAR2
AS
default_value NUMBER;
caseCount NUMBER;
seqNumber NUMBER;
previousDecisionNumber NUMBER;
BEGIN
--execute immediate q'[alter session set nls_date_format='dd/mm/yyyy']';
SELECT count(*)
INTO caseCount
FROM CASE_RECORD
WHERE GROUP_ABBR = p_group_name
AND to_number(to_char(create_date, 'yyyy')) = to_number(to_char(date_utils.get_current_date, 'yyyy'));
SELECT max(decision_number)
INTO previousDecisionNumber
FROM CASE_RECORD
WHERE GROUP_ABBR = p_group_name
AND to_number(to_char(create_date, 'yyyy')) = to_number(to_char(date_utils.get_current_date, 'yyyy'));
IF p_group_name IS NULL
THEN seqNumber := 0;
ELSE
SELECT seq_number INTO seqNumber FROM GROUP_LOOKUP WHERE ABBREVATION = p_group_name;
END IF;
IF caseCount > 0 THEN
default_value := greatest(seqNumber, previousdecisionnumber)+1;
ELSE
default_value := 1;
END IF;
INSERT INTO CASE_RECORD(case_title, decision_year, GROUP_ABBR, decision_number, case_file_number, active_yn, created_by, create_date)
VALUES(p_case_title, p_year, p_group_name, default_value, p_case_file_number, 'Y', p_user, sysdate );
--Need to update sequence here also
UPDATE GROUP_LOOKUP
SET SEQ_NUMBER = default_value
WHERE ABBREVATION = p_group_name;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
logger.error(p_message_text => SQLERRM
,p_message_code => SQLCODE
,p_stack_trace => dbms_utility.format_error_backtrace
RAISE;
END;
Many thanks in advance,
AnnWhy not using a sequence for populating the decision_number column ?
Sequence values are guaranteed to be unique so there's no need to lock anything.
You'll inevitably have gaps and no different groups will have the same decision_number in common.
Having to deal with consecutive numbers fixations you can proceed as
with
case_record as
(select 2012 decision_year,'AA' group_abbr,1 decision_number from dual union all
select 2012,'BB',2 from dual union all
select 2012,'AA',21 from dual union all
select 2012,'AA',22 from dual union all
select 2012,'BB',25 from dual union all
select 2013,'CC',33 from dual union all
select 2013,'CC',34 from dual union all
select 2013,'CC',36 from dual union all
select 2013,'BB',37 from dual union all
select 2013,'AA',38 from dual union all
select 2013,'AA',39 from dual union all
select 2013,'BB',41 from dual union all
select 2013,'AA',42 from dual union all
select 2013,'AA',43 from dual union all
select 2013,'BB',45 from dual
select decision_year,
group_abbr,
row_number() over (partition by decision_year,group_abbr order by decision_number) decision_number,
decision_number sequence_number -- not shown (noone needs to know you're using a sequence)
from case_record
order by decision_year,group_abbr,decision_number
DECISION_YEAR
GROUP_ABBR
DECISION_NUMBER
SEQUENCE_NUMBER
2012
AA
1
1
2012
AA
2
21
2012
AA
3
22
2012
BB
1
2
2012
BB
2
25
2013
AA
1
38
2013
AA
2
39
2013
AA
3
42
2013
AA
4
43
2013
BB
1
37
2013
BB
2
41
2013
BB
3
45
2013
CC
1
33
2013
CC
2
34
2013
CC
3
36
for retrieval (assuming decision_year,group_abbr,decision_number as being the key):
select decision_year,group_abbr,decision_number -- the rest of columns
from (select decision_year,
group_abbr,
-- the rest of columns
row_number() over (partition by decision_year,group_abbr order by decision_number) decision_number
from case_record
where decision_year = :decision_year
and group_abbr = :group_abbr
where decision_number = :decision_number
DECISION_YEAR
GROUP_ABBR
DECISION_NUMBER
2013
AA
4
if that's acceptable
Regards
Etbin -
SQL> create type string_table is table of varchar(100);
2 /
Type created.
declare
v_names string_table := string_table();
begin
v_names.EXTEND(3);
v_names(1) := 'name1';
v_names(2) := 'name2';
v_names(3) := 'name3';
dbms_output.put_line(v_names(1));
dbms_output.put_line(v_names(2));
dbms_output.put_line(v_names(3));
dbms_output.put_line(v_names.COUNT());
select * from table(v_names);
end;
select * from table(v_names);
ERROR at line 12:
ORA-06550: line 12, column 7:
PLS-00428: an INTO clause is expected in this SELECT statementselect * from table(v_names);
I guess ,here you were trying to put the content of the NT into another NT, or just trying to print it.
But, I don't think INTO Clause is mandatory here.
Please check your modified code (w/o INTO) and the output :
DECLARE
TYPE string_table IS TABLE OF VARCHAR (100);
v_names string_table := string_table ();
v_test string_table := string_table ();
BEGIN
v_names.EXTEND (3);
v_names (1) := 'name1';
v_names (2) := 'name2';
v_names (3) := 'name3';
DBMS_OUTPUT.put_line ('Old collection - '||v_names (1));
DBMS_OUTPUT.put_line ('Old collection - '||v_names (2));
DBMS_OUTPUT.put_line ('Old collection - '||v_names (3));
DBMS_OUTPUT.put_line ('Old collection - '||v_names.COUNT ());
DBMS_OUTPUT.put_line (CHR(10));
/* SELECT * FROM TABLE (v_names); */
v_test := v_names;
DBMS_OUTPUT.put_line ('New collection -- '||v_test (1));
DBMS_OUTPUT.put_line ('New collection -- '||v_test (2));
DBMS_OUTPUT.put_line ('New collection -- '||v_test (3));
DBMS_OUTPUT.put_line ('New collection -- '||v_test.COUNT ());
DBMS_OUTPUT.put_line (CHR(10));
/* Printing using FOR LOOP */
FOR i IN v_test.FIRST..v_test.LAST
LOOP
DBMS_OUTPUT.put_line ('In FOR Loop --- '||v_test (i));
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error ' ||SQLERRM|| DBMS_UTILITY.format_error_backtrace);
END;gives o/p :
Old collection - name1
Old collection - name2
Old collection - name3
Old collection - 3
New collection -- name1
New collection -- name2
New collection -- name3
New collection -- 3
In FOR Loop --- name1
In FOR Loop --- name2
In FOR Loop --- name3Refer this link -- http://docs.oracle.com/cd/E11882_01/appdev.112/e17126/tuning.htm#CIHGGBGF
Edited by: ranit B on Dec 26, 2012 2:29 PM
-- code modified
Edited by: ranit B on Dec 26, 2012 2:45 PM
-- code 'again' updated -- FOR LOOP added -
Error 420 "Can't call builtin routines remotely" while compiling a proc
I get the message above when I try to compile a Forms procedure with a call to specific functions in the DBMS_UTILITY package. I am using Forms 10.1.2.2.0 and 10g DB (10.2.0.4.0). I want to trace the PL/SQL path that my Forms application is taking and be able to report the line number of the failure when an exception is thrown. I am able to call some routines within the DBMS_UTILITY package, but not any of them that have "pragma interface (C, format_error_stack);" in the code. These include format_call_stack, format_error_stack, and format_error_backtrace; all of which I would like to use. I've tried creating my own DB package function to act as a wrapper; this allows me to compile the form, but the call to the function form my exception handler returns null. These are really useful functions, but I do need to be able to access the functionality from within Forms. Does anyone have a solution/workaround for this problem. Note, this is similar to the question in Link:[ http://forums.oracle.com/forums/thread.jspa?messageID=504922��]
Thanks JK.Nope, that does not work. See my first post above. I've tried using a wrapper, and whilst this allows my forms procedure to compile and my form to run, the wrapper procedure is returning null. Here's some code that may help to explain where I'm at. In the form, I've got -
DECLARE
l_bt VARCHAR2(2000); -- BackTrace
BEGIN
JEK_Raise_Exception; -- This is a DB procedure
EXCEPTION
WHEN OTHERS THEN
l_bt := KEYOWNER.Backtrace.generate_backtrace;
message('l_bt = '||l_bt); pause;
END;-- Then a DB procedure that just generates an exception
CREATE OR REPLACE PROCEDURE JEK_Raise_Exception IS
BEGIN
RAISE too_many_rows;
END;-- and the function from my Backtrace Package to return the backtrace data.
FUNCTION generate_backtrace
RETURN VARCHAR2
IS
l_bt VARCHAR2(2000);
BEGIN
l_bt := DBMS_UTILITY.format_error_backtrace;
RETURN l_bt; -- In my testing so far this has been NULL!!!
END; -
Unable to Create a file in a directory through a Job
Hi,
We have a anonymous block which uses utl_file package
It created a file in an oracle directory.
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
PL/SQL Release 11.1.0.7.0 - Production
CORE 11.1.0.7.0 Production
TNS for 32-bit Windows: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production
DECLARE
v_definition_clob CLOB;
v_codes VARCHAR2 (32767);
v_engine_name application.NAME%TYPE := 'CLAIMS';
v_knwldgebase_name knowledge_base.NAME%TYPE := 'CLAIMS';
v_rule_name VARCHAR2 (32767);
v_msg VARCHAR2 (200);
fid UTL_FILE.file_type;
BEGIN
fid :=
UTL_FILE.fopen ('MID5010_DOC1TEMP', 'Diagnosis_Report.csv', 'W', 32767);
UTL_FILE.put_line (fid, 'Rule Name ,Associated Codes');
FOR rule_name IN (SELECT DISTINCT rh.NAME, rh.rule_header_id
FROM rule_header rh,
knowledge_base kb,
application app
WHERE
app.application_id = kb.application_id
AND rh.knowledge_id = kb.knowledge_base_id
AND app.NAME = 'CLAIMS'
AND kb.NAME = 'CLAIMS')
LOOP
v_codes := NULL;
BEGIN
SELECT definition
INTO v_definition_clob
FROM rule_header
WHERE rule_header_id = rule_name.rule_header_id;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_definition_clob := EMPTY_CLOB ();
WHEN TOO_MANY_ROWS
THEN
v_definition_clob := EMPTY_CLOB ();
END;
DBMS_OUTPUT.ENABLE (50000000);
FOR code_indx IN (SELECT d.diagnosis_code AS code
FROM midev.diagnosis d
WHERE d.diag_ctgry_lkpcd = 'D' AND ROWNUM < 10
ORDER BY 1 ASC)
LOOP
IF REGEXP_INSTR (v_definition_clob, code_indx.code) > 0
THEN
v_codes := v_codes || code_indx.code || '|';
END IF;
END LOOP;
IF LENGTH (v_codes) > 0
THEN
v_codes := CHR (39) || v_codes;
END IF;
UTL_FILE.put_line (fid,
REPLACE (rule_name.NAME, ',', ' ')
|| ','
|| SUBSTR (v_codes, 1, LENGTH (v_codes) - 1)
END LOOP;
UTL_FILE.fclose (fid);
EXCEPTION
WHEN OTHERS
THEN
UTL_FILE.fclose (fid);
v_msg := DBMS_UTILITY.format_error_backtrace ();
DBMS_OUTPUT.put_line (v_msg || SQLCODE || ',' || SQLERRM);
END;
Now when i converted anonymous block into a procedure "DIAGNOSIS_REPORT_PROCEDURE" and calling it thorough a job its not creating the file. we are using the below code to create a job
BEGIN
--DBMS_SCHEDULER.drop_job (job_name => 'DIAGNOSIS_TESTING_REPORT_3');
DBMS_SCHEDULER.create_job
(job_name => 'DIAGNOSIS_TESTING_REPORT_3',
job_type => 'STORED_PROCEDURE',
job_action => 'DIAGNOSIS_REPORT_PROCEDURE',
start_date => to_Date('30-Mar-2012 16:44:03','dd-mon-yyyy hh24:mi:ss'),
--repeat_interval => 'freq=yearly',
enabled => TRUE,
comments => 'DIAGNOSIS_TESTING_REPORT_3'
END;Any help would be appreciated..
Thanks
P Prakash.I got the answer.
If we need to run a procedure through job then we must execute privilege . -
How to parse an XMl without using prefix in the namespace and elements?
Hi
The following is a sample of the xml that I need to parse.
Without the prefix in the namespace section I am getting an error but when i just put in the prefix it works fine. Any help here would be greatly appreciated.
I think i need to change something in the parser set up...may be the somewhere in the bolded lines....but i am clueless...
//Xml begins
<?xml version="1.0" encoding="utf-8" ?>
- <Statemessages xsi:schemaLocation="http://www.SomeLocation.com/SomeXSD.xsd" xmlns="http://www.abcd.com/BSN" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <FileControl>
<CreationDate>2008-08-11</CreationDate>
- <Source>
<SystemID>SAP4BSN</SystemID>
<MandantID>100</MandantID>
</Source>
- <Destination>
<SystemID>CWL</SystemID>
<MandantID>746</MandantID>
</Destination>
<SequenceNumber>000000004</SequenceNumber>
<Counter>000000001</Counter>
</FileControl>
- <Message>
- <PartyRegistrationID>
<ID>2101576347</ID>
<Type>RG</Type>
<ID>2101576347</ID>
<Type>AG</Type>
</PartyRegistrationID>
<CustomerGroupID>02</CustomerGroupID>
<Name>Lewicki</Name>
<Subname>Hans Bruno Michel</Subname>
<DateTime>2008-08-11T23:59:59</DateTime>
- <DefaultOfPayment>
<MessageID>00000001</MessageID>
<GrossAmountBefore>0.0</GrossAmountBefore>
<GrossAmountCurrent>-17.9</GrossAmountCurrent>
<Currency>EUR</Currency>
<SettlementOfBalance>Nein</SettlementOfBalance>
<IncludingSubsidiaryClaim>Ja</IncludingSubsidiaryClaim>
</DefaultOfPayment>
- <ContractsWithDefaultOfPayment>
<ContractID>0148863732</ContractID>
</ContractsWithDefaultOfPayment>
- <Messagedetails>
- <ReturnDebitNote>
<MessageID>00000002</MessageID>
<KindOf>BA</KindOf>
<Reason>E2</Reason>
<Date>2008-08-11</Date>
<GrossAmount>-15.4</GrossAmount>
<Currency>EUR</Currency>
</ReturnDebitNote>
</Messagedetails>
</Message>
</Statemessages>
//XML end
I am using the following stored procedure to try this;
create or replace PROCEDURE CompleteSaveXML_1 AS
XMLMessage2 XMLTYPE;
v_parser dbms_xmlparser.Parser;
v_clob CLOB;
v_sent DATE;
v_doc xmldom.DOMDocument;
v_nl xmldom.DOMNodeList;
v_nFCL xmldom.DOMNodeList;
v_nFCN xmldom.DOMNode;
v_nFCSourceL xmldom.DOMNodeList;
v_nFCSourceN xmldom.DOMNode;
v_nFCDestinationL xmldom.DOMNodeList;
v_nFCDestinationN xmldom.DOMNode;
m_nl xmldom.DOMNodeList;
m_n xmldom.DOMNode;
v_n xmldom.DOMNode;
v_n3 xmldom.DOMNodeList;
v_n4 xmldom.DOMNode;
v_b xmldom.DOMNode;
v_d xmldom.DOMNode;
v_a xmldom.DOMNodeList;
v_c xmldom.DOMNodeList;
m_prg xmldom.DOMNodeList;
m_pr xmldom.DOMNode;
condf_nl xmldom.DOMNodeList;
condf_n xmldom.DOMNode;
msgdtl_nl xmldom.DOMNodeList;
msgdtl_n xmldom.DOMNode;
rtndbt_nl xmldom.DOMNodeList;
rtndbt_n xmldom.DOMNode;
dnlt_nl xmldom.DOMNodeList;
dnlt_n xmldom.DOMNode;
cancl_nl xmldom.DOMNodeList;
cancl_n xmldom.DOMNode;
conid_nl xmldom.DOMNodeList;
conid_n xmldom.DOMNode;
canclid_nl xmldom.DOMNodeList;
canclid_n xmldom.DOMNode;
par_ref number(10) :=0;
msgnum number(20):=0;
var1 number(30):=0;
rtnnum number(20):=0;
dnnum number(20):=0;
tpmsg number(20):=0;
condfpmt number(20):=0;
canclnum number(20):=0;
--Added the next variable
sequence_no number(20):=0;
--These are the new variables
condfpmt1 number(20):=0;
rtnnum1 number(20):=0;
dnnum1 number(20):=0;
tpmsg1 number(20):=0;
canclnum1 number(20):=0;
--changing
part_refid_value number(20);
parid_typ_n xmldom.DOMNode;
parid_typ_nl xmldom.DOMNodeList;
parid_id_nl xmldom.DOMNodeList;
parid_id_n xmldom.DOMNode;
party_ref_node xmldom.DOMNode;
var_pr_reg_typ VARCHAR2(2);
msgrtdbt_nl xmldom.DOMNodeList;
msgrtdbt_n xmldom.DOMNode;
kndrtdbt_nl xmldom.DOMNodeList;
kndrtdbt_n xmldom.DOMNode;
rsnrtdbt_nl xmldom.DOMNodeList;
rsnrtdbt_n xmldom.DOMNode;
datrtdbt_nl xmldom.DOMNodeList;
datrtdbt_n xmldom.DOMNode;
grssrtdbt_nl xmldom.DOMNodeList;
grssrtdbt_n xmldom.DOMNode;
currtdbt_nl xmldom.DOMNodeList;
currtdbt_n xmldom.DOMNode;
rtnnum2 number(20):=0;
msgdnlt_nl xmldom.DOMNodeList;
msgdnlt_n xmldom.DOMNode;
lvdnlt_nl xmldom.DOMNodeList;
lvdnlt_n xmldom.DOMNode;
datdnlt_nl xmldom.DOMNodeList;
datdnlt_n xmldom.DOMNode;
grsdnlt_nl xmldom.DOMNodeList;
grsdnlt_n xmldom.DOMNode;
curdnlt_nl xmldom.DOMNodeList;
curdnlt_n xmldom.DOMNode;
limdnlt_nl xmldom.DOMNodeList;
limdnlt_n xmldom.DOMNode;
lvimp number(20);
nullchk varchar2(30) ;
chk_flseq number(10);
fl_seq number(30);
--these are the new variables
TYPE tab_type IS TABLE OF FileControl%ROWTYPE;
t_tab_FC tab_type := tab_type();
TYPE tab_type1 IS TABLE OF MessageTab%ROWTYPE;
t_tab1 tab_type1 := tab_type1();
TYPE tab_type2 IS TABLE OF ContractsWithDefaultOfPayment%ROWTYPE;
t_tab2 tab_type2 := tab_type2();
TYPE tab_type3 IS TABLE OF CancellationTab%ROWTYPE;
t_tab3 tab_type3 := tab_type3();
TYPE tab_type4 IS TABLE OF ReturnDebitNoteTab%ROWTYPE;
t_tab4 tab_type4 := tab_type4();
TYPE tab_type5 IS TABLE OF DunningLettersTab%ROWTYPE;
t_tab5 tab_type5 := tab_type5();
cursor MessageCursor is
select * from OM_BSN_STATEMSGS
where PROCESSED is null AND SENT in(Select min(SENT) from OM_BSN_STATEMSGS
where PROCESSED is null)
order by sent asc;
v_statemsgs OM_BSN_STATEMSGS%ROWTYPE;
BEGIN
DBMS_OUTPUT.put_line('creating parser');
-- v_parser := DBMS_XMLPARSER.NEWPARSER;
v_parser := DBMS_XMLPARSER.NEWPARSER();
DBMS_OUTPUT.put_line('done creating');
DBMS_XMLPARSER.setValidationMode(v_parser, true);
DBMS_XMLPARSER.showWarnings(v_parser, true);
open MessageCursor;
loop
fetch MessageCursor into v_statemsgs;
exit when MessageCursor%NOTFOUND;
DBMS_XMLPARSER.PARSECLOB(P => v_parser, DOC => v_statemsgs.MESSAGE);
-- xmlparser.parse(v_parser, File_Location);
v_doc := xmlparser.getDocument(v_parser);
dbms_xmlparser.freeParser(v_parser); DBMS_OUTPUT.put_line('Step 1');
v_nFCL := xslprocessor.selectNodes(xmldom.makeNode(v_doc),'/Statemessages/FileControl');
v_nFCN := xmldom.item(v_nFCL,0);
Source
v_nFCSourceL := xslprocessor.selectNodes(xmldom.makeNode(v_doc),'/Statemessages/FileControl/Source');
v_nFCSourceN := xmldom.item(v_nFCSourceL,0);
Destination
v_nFCDestinationL := xslprocessor.selectNodes(xmldom.makeNode(v_doc),'/Statemessages/FileControl/Destination');
v_nFCDestinationN := xmldom.item(v_nFCDestinationL,0);
-- Populate tab type for ORFC
t_tab_FC.extend;
t_tab_FC(t_tab_FC.last).creation_date := to_date(xslprocessor.valueOf(v_nFCN,'CreationDate'),'YYYY-MM-DD');
t_tab_FC(t_tab_FC.last).src_sys_id := xslprocessor.valueOf(v_nFCSourceN,'SystemID');
t_tab_FC(t_tab_FC.last).src_mandant_id := xslprocessor.valueOf(v_nFCSourceN,'MandantID');
t_tab_FC(t_tab_FC.last).dest_sys_id := xslprocessor.valueOf(v_nFCDestinationN,'SystemID');
t_tab_FC(t_tab_FC.last).dest_mandant_id := xslprocessor.valueOf(v_nFCDestinationN,'MandantID');
t_tab_FC(t_tab_FC.last).seq_no := xslprocessor.valueOf(v_nFCN,'SequenceNumber');
t_tab_FC(t_tab_FC.last).counter := xslprocessor.valueOf(v_nFCN,'Counter');
--Saving the value of this seq_no so that it can be inserted in the message tab.
sequence_no:= xslprocessor.valueOf(v_nFCN,'SequenceNumber');
--Insert into ORFC TAB
fl_seq := xslprocessor.valueOf(v_nFCN,'SequenceNumber');
select count(*) into chk_flseq from FileControl where SEQ_NO =fl_seq;
if (chk_flseq =0) then
FOR each_FC IN t_tab_FC.first .. t_tab_FC.last LOOP
INSERT INTO FileControl
creation_date,
src_sys_id,
src_mandant_id,
dest_sys_id,
dest_mandant_id,
seq_no,
counter)
VALUES
t_tab_FC(each_FC).creation_date,
t_tab_FC(each_FC).src_sys_id ,
t_tab_FC(each_FC).src_mandant_id,
t_tab_FC(each_FC).dest_sys_id,
t_tab_FC(each_FC).dest_mandant_id,
t_tab_FC(each_FC).seq_no,
t_tab_FC(each_FC).counter
END LOOP;
end if;
DBMS_OUTPUT.put_line('Step 2');
if (chk_flseq =0) then /* chk the xml's filecontrol seq exists in filecontrltab */
-- Use XPATH syntax to assign values to he elements of the collection.
v_nl := xslprocessor.selectNodes(xmldom.makeNode(v_doc),'/Statemessages/Message');
tpmsg := xmldom.getLength(v_nl);
DBMS_OUTPUT.put_line('Message node length'||tpmsg);
if (tpmsg>0) then
FOR cur_emp IN 0 .. xmldom.getLength(v_nl) - 1 LOOP
v_n := xmldom.item(v_nl, cur_emp);
select (BISON_OM_MessageID.NEXTVAL) into var1 from dual;
t_tab1.extend;
t_tab1(t_tab1.last).message_id := var1;
t_tab1(t_tab1.last).seq_no := sequence_no;
---party reg
m_prg := xslprocessor.selectNodes(v_n,'PartyRegistrationID');
FOR Ref_Id_Loop IN 0 .. xmldom.getLength(m_prg) - 1 LOOP
party_ref_node := xmldom.item(m_prg,0);
part_refid_value := xslprocessor.valueOf(party_ref_node,'.');
end loop;
m_pr := xmldom.item(m_prg, 0);
--changing
--chang id
parid_id_nl := xslprocessor.selectNodes(m_pr,'ID');
DBMS_OUTPUT.put_line('Going to read PartyRegistrationID');
FOR cur_parid_id IN 0 .. xmldom.getLength(parid_id_nl) - 1 LOOP
parid_id_n := xmldom.item(parid_id_nl,cur_parid_id);
DBMS_OUTPUT.put_line('Value of id:'|| xslprocessor.valueOf(parid_id_n,'.'));
t_tab1(t_tab1.last).party_ref_id := xslprocessor.valueOf(parid_id_n,'.');
exit;
end loop ;
---- change id
parid_typ_nl := xslprocessor.selectNodes(m_pr,'Type');
FOR cur_parid_typ IN 0 .. xmldom.getLength(parid_typ_nl) - 1 LOOP
parid_typ_n := xmldom.item(parid_typ_nl,cur_parid_typ);
var_pr_reg_typ := xslprocessor.valueOf(parid_typ_n,'.');
if var_pr_reg_typ='RG' then
t_tab1(t_tab1.last).PARTY_REG_TYPE_RG := var_pr_reg_typ;
elsif var_pr_reg_typ='AG' then
t_tab1(t_tab1.last).PARTY_REG_TYPE_AG := var_pr_reg_typ;
end if;
end loop;
--Chang
-- t_tab1(t_tab1.last).PARTY_REG_TYPE_AG := xslprocessor.valueOf(m_pr,'Type');
par_ref :=xslprocessor.valueOf(m_pr,'ID');
t_tab1(t_tab1.last).customer_grp_id := xslprocessor.valueOf(v_n,'CustomerGroupID');
t_tab1(t_tab1.last).name := xslprocessor.valueOf(v_n,'Name');
t_tab1(t_tab1.last).subname := xslprocessor.valueOf(v_n,'Subname');
t_tab1(t_tab1.last).datetime := xslprocessor.valueOf(v_n,'DateTime');
DBMS_OUTPUT.put_line('Step 3 ContractsWithDefaultOfPayment');
m_nl := xslprocessor.selectNodes(v_n,'DefaultOfPayment');
m_n := xmldom.item(m_nl, 0);
t_tab1(t_tab1.last).payment_msg_id := xslprocessor.valueOf(m_n,'MessageID');
t_tab1(t_tab1.last).gross_amt_before := xslprocessor.valueOf(m_n,'GrossAmountBefore');
t_tab1(t_tab1.last).gross_amt_current := xslprocessor.valueOf(m_n,'GrossAmountCurrent');
t_tab1(t_tab1.last).currency := xslprocessor.valueOf(m_n,'Currency');
t_tab1(t_tab1.last).settlemen_of_balance := xslprocessor.valueOf(m_n,'SettlementOfBalance');
t_tab1(t_tab1.last).including_subsidiary_claim := xslprocessor.valueOf(m_n,'IncludingSubsidiaryClaim');
condf_nl := xslprocessor.selectNodes(v_n,'ContractsWithDefaultOfPayment');
condf_n := xmldom.item(condf_nl,0);
condfpmt := xmldom.getLength(condf_nl);
if (condfpmt > 0) then
conid_nl := xslprocessor.selectNodes(condf_n,'ContractID');
FOR cur_conid IN 0 .. xmldom.getLength(conid_nl) - 1 LOOP
conid_n := xmldom.item(conid_nl,cur_conid);
t_tab2.extend;
t_tab2(t_tab2.last).message_id := var1;
t_tab2(t_tab2.last).contract_id := xslprocessor.valueOf(conid_n,'.');
end loop;
condfpmt1 := 1;
end if;
cancl_nl := xslprocessor.selectNodes(v_n,'Cancellation');
cancl_n := xmldom.item(cancl_nl,0);
DBMS_OUTPUT.put_line('No of cancellations'||xmldom.getLength(cancl_nl) );
canclnum := xmldom.getLength(cancl_nl) ;
if (canclnum > 0) then
canclid_nl := xslprocessor.selectNodes(cancl_n,'MessageID');
FOR cur_canclid IN 0 .. xmldom.getLength(canclid_nl) - 1 LOOP
canclid_n := xmldom.item(canclid_nl,cur_canclid);
t_tab3.extend;
t_tab3(t_tab3.last).message_id := var1;
t_tab3(t_tab3.last).cancellation_msg_id := xslprocessor.valueOf(canclid_n,'.');
end loop;
canclnum1 :=1;
end if; -- canclnum
msgdtl_nl := xslprocessor.selectNodes(v_n,'Messagedetails');
msgnum := xmldom.getLength(msgdtl_nl) ;
dbms_output.put_line('msgggg::::'||msgnum);
if (msgnum >0) then
msgdtl_n := xmldom.item(msgdtl_nl,0);
rtndbt_nl := xslprocessor.selectNodes(msgdtl_n,'ReturnDebitNote');
rtndbt_n := xmldom.item(rtndbt_nl,0);
rtnnum := xmldom.getLength(rtndbt_nl) ;
if (rtnnum >0) then
--return debit note
msgrtdbt_nl := xslprocessor.selectNodes(rtndbt_n,'MessageID');
kndrtdbt_nl := xslprocessor.selectNodes(rtndbt_n,'KindOf');
rsnrtdbt_nl := xslprocessor.selectNodes(rtndbt_n,'Reason');
datrtdbt_nl := xslprocessor.selectNodes(rtndbt_n,'Date');
grssrtdbt_nl := xslprocessor.selectNodes(rtndbt_n,'GrossAmount');
currtdbt_nl := xslprocessor.selectNodes(rtndbt_n,'Currency');
rtnnum2 :=0;
FOR cur_msgrtndbt IN 0 .. xmldom.getLength(msgrtdbt_nl) - 1 LOOP
msgrtdbt_n := xmldom.item(msgrtdbt_nl,cur_msgrtndbt);
kndrtdbt_n := xmldom.item(kndrtdbt_nl,cur_msgrtndbt);
rsnrtdbt_n := xmldom.item(rsnrtdbt_nl,cur_msgrtndbt);
datrtdbt_n := xmldom.item(datrtdbt_nl,cur_msgrtndbt);
grssrtdbt_n := xmldom.item(grssrtdbt_nl,cur_msgrtndbt);
currtdbt_n := xmldom.item(currtdbt_nl,cur_msgrtndbt);
t_tab4.extend;
t_tab4(t_tab4.last).message_id := var1;
t_tab4(t_tab4.last).ret_debitnote_msg_id := xslprocessor.valueOf(msgrtdbt_n,'.');
t_tab4(t_tab4.last).kind_of := xslprocessor.valueOf(kndrtdbt_n,'.');
t_tab4(t_tab4.last).Reason := xslprocessor.valueOf(rsnrtdbt_n,'.');
t_tab4(t_tab4.last).debit_note_date := to_date(xslprocessor.valueOf(datrtdbt_n,'.'),'YYYY-MM-DD');
t_tab4(t_tab4.last).gross_amt := xslprocessor.valueOf(grssrtdbt_n,'.');
t_tab4(t_tab4.last).currency := xslprocessor.valueOf(currtdbt_n,'.');
rtnnum1 :=rtnnum1 + 1;
rtnnum2 := rtnnum2 + 1;
dbms_output.put_line('message_id::::'||var1);
dbms_output.put_line('rtnnum2::::'||rtnnum2);
dbms_output.put_line('ret_debitnote_msg_id:::'||t_tab4(t_tab4.last).ret_debitnote_msg_id);
end loop;
----return debit note
t_tab4(t_tab4.last).message_id := var1 ;
t_tab4(t_tab4.last).ret_debitnote_msg_id := xslprocessor.valueOf(rtndbt_n,'MessageID');
t_tab4(t_tab4.last).kind_of := xslprocessor.valueOf(rtndbt_n,'KindOf');
t_tab4(t_tab4.last).reason := xslprocessor.valueOf(rtndbt_n,'Reason');
t_tab4(t_tab4.last).debit_note_date := to_date(xslprocessor.valueOf(rtndbt_n,'Date'),'YYYY-MM-DD');
t_tab4(t_tab4.last).gross_amt := xslprocessor.valueOf(rtndbt_n,'GrossAmount');
t_tab4(t_tab4.last).currency := xslprocessor.valueOf(rtndbt_n,'Currency');
rtnnum1 :=1;
end if;
dnlt_nl := xslprocessor.selectNodes(msgdtl_n,'DunningLetter');
dnlt_n := xmldom.item(dnlt_nl, 0);
dnnum := xmldom.getLength(dnlt_nl) ;
if (dnnum >0) then
-- t_tab5.extend;
--dunning letter
msgdnlt_nl := xslprocessor.selectNodes(dnlt_n,'MessageID');
lvdnlt_nl := xslprocessor.selectNodes(dnlt_n,'Level');
datdnlt_nl := xslprocessor.selectNodes(dnlt_n,'Date');
grsdnlt_nl := xslprocessor.selectNodes(dnlt_n,'GrossAmount');
curdnlt_nl := xslprocessor.selectNodes(dnlt_n,'Currency');
limdnlt_nl := xslprocessor.selectNodes(dnlt_n,'LevelImprovement');
FOR cur_msgdnlt IN 0 .. xmldom.getLength(msgdnlt_nl) - 1 LOOP
msgdnlt_n := xmldom.item(msgdnlt_nl,cur_msgdnlt);
lvdnlt_n := xmldom.item(lvdnlt_nl,cur_msgdnlt);
datdnlt_n := xmldom.item(datdnlt_nl,cur_msgdnlt);
grsdnlt_n := xmldom.item(grsdnlt_nl,cur_msgdnlt);
curdnlt_n := xmldom.item(curdnlt_nl,cur_msgdnlt);
limdnlt_n := xmldom.item(limdnlt_nl,cur_msgdnlt);
t_tab5.extend;
t_tab5(t_tab5.last).message_id := var1;
t_tab5(t_tab5.last).dunning_msg_id := xslprocessor.valueOf(msgdnlt_n,'.');
t_tab5(t_tab5.last).d_level := xslprocessor.valueOf(lvdnlt_n,'.');
t_tab5(t_tab5.last).dunning_date := to_date(xslprocessor.valueOf(datdnlt_n,'.'),'YYYY-MM-DD');
t_tab5(t_tab5.last).gross_amt := xslprocessor.valueOf(grsdnlt_n,'.');
t_tab5(t_tab5.last).currency := xslprocessor.valueOf(curdnlt_n,'.');
lvimp := xmldom.getLength(limdnlt_nl);
begin
t_tab5(t_tab5.last).level_improvement := xslprocessor.valueOf(limdnlt_n,'.');
EXCEPTION
WHEN OTHERS THEN
t_tab5(t_tab5.last).level_improvement := null;
end;
dnnum1 :=dnnum1 + 1;
-- dnnum2 := dnnum2 + 1;
dbms_output.put_line('message_id::::'||var1);
end loop;
----dunning letter
t_tab5(t_tab5.last).message_id := var1;
t_tab5(t_tab5.last).dunning_msg_id := xslprocessor.valueOf(dnlt_n,'MessageID');
t_tab5(t_tab5.last).d_level := xslprocessor.valueOf(dnlt_n,'Level');
t_tab5(t_tab5.last).dunning_date := to_date(xslprocessor.valueOf(dnlt_n,'Date'),'YYYY-MM-DD');
t_tab5(t_tab5.last).gross_amt := xslprocessor.valueOf(dnlt_n,'GrossAmount');
t_tab5(t_tab5.last).currency := xslprocessor.valueOf(dnlt_n,'Currency');
t_tab5(t_tab5.last).level_improvement := xslprocessor.valueOf(dnlt_n,'LevelImprovement');
dnnum1 :=1; */
end if;
end if;
END LOOP;
-- Insert data into the real EMP table from the table collection.
-- Form better performance multiple collections should be used to allow
-- bulk binding using the FORALL construct but this would make the code
-- too long-winded for this example.
DBMS_OUTPUT.put_line('Step 5');
FOR cur_emp IN t_tab1.first .. t_tab1.last LOOP
INSERT INTO MessageTab
message_id,
PARTY_REF_ID,
PARTY_REG_TYPE_AG,
party_reg_type_rg,
customer_grp_id,
name,
subname,
datetime,
payment_msg_id,
gross_amt_before,
gross_amt_current,
currency,
settlemen_of_balance,
including_subsidiary_claim,
seq_no)
VALUES
t_tab1(cur_emp).message_id,
t_tab1(cur_emp).PARTY_REF_ID,
t_tab1(cur_emp).PARTY_REG_TYPE_AG,
t_tab1(cur_emp).PARTY_REG_TYPE_RG,
t_tab1(cur_emp).customer_grp_id,
t_tab1(cur_emp).name,
t_tab1(cur_emp).subname,
t_tab1(cur_emp).datetime,
t_tab1(cur_emp).payment_msg_id,
t_tab1(cur_emp).gross_amt_before,
t_tab1(cur_emp).gross_amt_current,
t_tab1(cur_emp).currency,
t_tab1(cur_emp).settlemen_of_balance,
t_tab1(cur_emp).including_subsidiary_claim,
t_tab1(cur_emp).seq_no
END LOOP;
DBMS_OUTPUT.put_line('Step 6');
if (condfpmt1 > 0) then
FOR cur_cnf IN t_tab2.first .. t_tab2.last LOOP
INSERT INTO ContractsWithDefaultOfPayment
(message_id,contract_id)
values
(t_tab2(cur_cnf).message_id,t_tab2(cur_cnf).contract_id );
end loop;
end if; -- condfpmt
if (canclnum1 > 0) then
FOR cur_cancl IN t_tab3.first .. t_tab3.last LOOP
INSERT INTO CancellationTab
(message_id,cancellation_msg_id)
VALUES
(t_tab3(cur_cancl).message_id,t_tab3(cur_cancl).cancellation_msg_id);
END LOOP;
end if;
DBMS_OUTPUT.put_line('Step 7');
if (rtnnum1 >0) then
FOR cur_rtndb IN t_tab4.first .. t_tab4.last LOOP
INSERT INTO ReturnDebitNoteTab
(message_id,
ret_debitnote_msg_id,
kind_of,
reason,
debit_note_date,
gross_amt,
currency
VALUES
(t_tab4(cur_rtndb).message_id,
t_tab4(cur_rtndb).ret_debitnote_msg_id,
t_tab4(cur_rtndb).kind_of,
t_tab4(cur_rtndb).reason,
t_tab4(cur_rtndb).debit_note_date,
t_tab4(cur_rtndb).gross_amt,
t_tab4(cur_rtndb).currency);
END LOOP;
end if;
if (dnnum1 >0) then
FOR cur_dnl IN t_tab5.first .. t_tab5.last LOOP
INSERT INTO DunningLettersTab
(message_id,
dunning_msg_id,
d_level,
dunning_date,
gross_amt,
currency,
level_improvement)
VALUES
(t_tab5(cur_dnl).message_id,
t_tab5(cur_dnl).dunning_msg_id,
t_tab5(cur_dnl).d_level,
t_tab5(cur_dnl).dunning_date,
t_tab5(cur_dnl).gross_amt,
t_tab5(cur_dnl).currency,
t_tab5(cur_dnl).level_improvement
END LOOP;
DBMS_OUTPUT.put_line('Step 8');
end if; -- dnn
end if; -- top msg
end if; --- fl_seq chk
COMMIT;
-- Free any resources associated with the document now it
-- is no longer needed.
xmldom.freeDocument(v_doc);
/* refresh array */
t_tab_FC.delete;
t_tab1.delete;
t_tab2.delete;
t_tab3.delete;
t_tab4.delete;
t_tab5.delete;
/* refsh */
end loop;
close MessageCursor;
END ;
//Errors thrown by Oracle always show a line number (even if it points to the FOR loop that the error occurred within). When you run it, what is the error stack that is being returned. Copy and paste that, don't summarize it.
If you are still uncertain, add a final
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);to have it written out where your normal dbms_output goes. This is your friend in 10g for tracking down errors.
"But as soon as i add a prefix in the header everything works fine."
Is that header in the sample XML you provided? Regardless what are you adding? Your data is a clob so you can always tweak it before converting it to a DOMDocument just by doing simple string manipulation.
Since you are in 10g, you should be using dbms_xmldom instead of xmldom. I think xmldom is just a synonym for dbms_xmldom though. Review the dbms_xmldom documentation. You can go straight from a clob to a DOMDocument via DBMS_XMLDOM.NEWDOMDOCUMENT. You can also parse the document completely using dbms_xmldom calls instead of xslprocessor calls.
Other random things to evaluate:
Consider turning
FOR each_FC IN t_tab_FC.first .. t_tab_FC.last LOOP
INSERT INTO FileControl
into a
FORALL i IN t_tab_FC.first .. t_tab_FC.last LOOP
INSERT INTO FileControl
...Better performance because one two context switches (PL/SQL -> SQL -> PL/SQL) instead of 2*n switches.
I like this construct better
TYPE tab_type IS TABLE OF FileControl%ROWTYPE INDEX BY BINARY_INTEGER;
t_tab_FC tab_type := tab_type;because then you don't have to t_tab_FC.extend;you can just do something like index := 1;
LOOP
t_tab_FC(index).creation_date := <whatever>;
index := index + 1;
END LOOPYou also have the option of parsing your XML as a XMLType, including purely in SQL, but you can research that avenue at a later date.
Forgot to mention, wrap any code examples in [ pre ] [ pre ] (without the spaces) to retain your formatting. -
Regardin handling exception in a function, while using that function in sql
Hi gurus,
I have a question regarding logging exceptions while using functions.
I wrote a separate package to handle errors, where i have a procedure.
In this proc i'm logging my error into a table and then raise the error to the front end.
Ex:
proc_log_and_raise -- this proc... inserts my error into a table and then raisenow i included this error procedure in all functions and procedures.
consider an example with a sample procedure and function.
function func_1(( v_var varchar2) return varchar2 is
begin
select column2
from table2
where col1 = v_var;
exception
when others then
proc_log_and_raise;
end;
procedure proc_1( v_var varchar2) is
begin
select func_1(v_var) -- error occurs here..
from table_a
where col1 = v_var;
exception
when others then
proc_log_and_raise;
end; now i do
exec proc_1( v_var );but now my problem is, when an error occurs in func_1, i'm getting an error with DML operation ( as we are inserting into error table)
ORA-14551: cannot perform a DML operation inside a query.
so what i want to do is, log both function and procedure where error occured.
So is there any other better way, we can write our exception handling, so that i can log error and use function in a select statement.
thank you.I changed my procedure a little, to make it simple.
FUNCTION PKG_WEEKLY.FUNC_1
RETURN NUMBER IS
exc exception;
BEGIN
raise exc;
RETURN v_provr_rcoupt;
EXCEPTION
when exc then
PKG.PKG_ERROR.USP_LOG_AND_RAISE(
'batch_1',
'func_1',
SQLCODE,
DBMS_UTILITY.FORMAT_ERROR_STACK || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE());
END FUNC_1;
PROCEDURE PKG_WEEKLY.PROC_1(
cur_details OUT sys_refcursor) IS
BEGIN
OPEN cur_details FOR
SELECT NVL(PKG.PKG_WEEKLY.FUNC_1,0)) FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
REPORT_APP_PKG.PKG_REPORT_ERROR.USP_LOG_AND_RAISE(
'batch_1',
'PROC_1',
SQLCODE,
DBMS_UTILITY.FORMAT_ERROR_STACK || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE());
END PROC_1; Now i execute it.
exec PKG_WEEKLY.PROC_1(:cursor); Error logged into the table:
242 batch_1 func_1 ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "REPORT_APP_PKG.PKG_REPORT_WEEKLY_CAO", line 230
04/14/2009 16:09:25
ERRORS displayed to the front end:
ORA-20156: ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "PKG.PKG_WEEKLY", line 230
ORA-06512: at "PKG.PKG_ERROR", line 48
ORA-06512: at "PKG.PKG_ERROR", line 226
ORA-06512: at "PKG.PKG_WEEKLY", line 261
thank you -
Problem in Calling a function in sql statement.
hi,
I am having a function ops_safex_utl.EDIT_ASSC_CNTR_LOG(id number);
when i am trying to use this inside a sql statement as shown below, it is giving error (exception part inside the function).
SQL> select ops_safex_utl.EDIT_ASSC_CNTR_LOG(688) from dual;
OPS_SAFEX_UTL.EDIT_ASSC_CNTR_LOG(688)
-1 (-- exception )
when i am trying to call this function using a PL/SQL Block then it is woking fine as shown below.
SQL> DECLARE
2
3 x NUMBER(2);
4
5 BEGIN
6
7 x := ops_safex_utl.EDIT_ASSC_CNTR_LOG(688);
8
9 dbms_output.put_line('x '||' '||x);
10
11 END;
12 /
hi
insert into ops_assc_cntr_log
insert into ops_ac_ex_gratia_log
insert into ops_ac_sls_dlvry_slab_dtls_log
insert into ops_ac_sls_dlvry_slab_dtls_log
insert into ops_ac_sls_dlvry_slab_dtls_log
insert into ops_ac_sls_dlvry_slab_dtls_log
insert into ops_ac_sls_dlvry_slab_dtls_log
insert into ops_ac_spl_acct_dtls_log
insert into ops_ac_spl_acct_slab_dtls_log
insert into ops_ac_spl_acct_slab_dtls_log
insert into ops_ac_spl_acct_slab_dtls_log
insert into ops_ac_spl_acct_dtls_log
insert into ops_ac_spl_acct_slab_dtls_log
insert into ops_ac_spl_acct_slab_dtls_log
insert into ops_ac_spl_acct_slab_dtls_log
update ops_assc_cntr
success
x 0
PL/SQL procedure successfully completed.
when i am trying to run the SQL statement it is returning a exception from the function.
SELECT ops_safex_utl.EDIT_ASSC_CNTR_LOG(688) from dual --it is returning -1 (i.e exception).
My sql client version is 9.2.0.1.0. and my data base version is 10.2.0.2.0.
Please advice.Could you post the exception handler within the function.
It sounds like you return -1 if you experience an error - it would be easier to determine the cause of the problem if you return the Oracle error details, E.g:
EXCEPTION
WHEN OTHERS THEN
RETURN dbms_utility.format_error_backtrace;This will then return a meaningful error, identifying exactly what is causing the error to be generated. -
Is there an AUDIT option like AFTER SERVERERROR database trigger?
I want to log any and every error-exception in a test database for a period.
I have seen DBMS_UTILITY.FORMAT_ERROR_BACKTRACE article published on Oracle Magazine;
http://www.oracle.com/technology/oramag/oracle/05-mar/o25plsql.html
But before trying to build a custom application like this one;
http://apex.oracle.com/pls/otn/f?p=2853:4:1160653345033883::NO::P4_QA_ID:5922
1- I wanted to be sure if there is a specific WHENEVER NOT SUCCESSFUL Audit option for this need?
2- Also is there a way to capture NO_DATA_FOUND exception with AFTER SERVERERROR database trigger?
Thank you,
Best regards.some stuff like following;
1)
-- the right one is conn hr/hr
conn hr/eychar
2)
-- the right one is grant select on employees to public;
grant select onnnn employees to public;
3)
create or replace procedure p1 as
begin
raise_Application_error(-20001, 'catch me if you can');
end;
exec p1;
again thank you for your interest Michaels.
Maybe you are looking for
-
DPM 2012 SP1 and SharePoint 2013 on a SQL 2012 AlwaysOn AG
I am trying to protect a new SharePoint Foundation 2013 farm with it's databases stored on an SQL 2012 AlwaysOn Availability Group. I've run configureSharePoint.exe -EnableSharePointProtection on my WFE and SharePoint shows up in DPM when I try to a
-
Error in Loading Data In Planning Application
Hi we are getting the Following error in loading data by using Outline Load utility by specifying driver members on the Planning Data Load Administrator Page. Client Enable Status false com.hyperion.planning.InvalidMemberException: The member USD,BS,
-
How do I get numbers to automatically add the next date down a column in numbers?
How do I get numbers to automatically add the next date down a column in numbers?
-
Hello I removed the iphoto icon from the dock, and it went up in a "puff of smoke", and I thought i would be able to find it again in Applications. It's gone. The photos can be found in the desktop.....but no iphoto.
-
Hi, I have created a checkbox in a table of webdynpro view. On toggle, i have created an action in which i'm disabling a button when the user check the checkbox. That is working fine. But when i check on checkbox in the table, all of checkboxes in th