@@ -22,16 +22,55 @@ create or replace type body ut_data_value_refcursor as
2222 return;
2323 end;
2424
25- member procedure init (self in out nocopy ut_data_value_refcursor, a_value sys_refcursor) is
25+ member procedure extract_cursor (self in out nocopy ut_data_value_refcursor, a_value sys_refcursor) is
2626 c_bulk_rows constant integer := 10000;
2727 l_cursor sys_refcursor := a_value;
2828 l_ctx number;
2929 l_xml xmltype;
30- l_current_date_format varchar2(4000);
31- cursor_not_open exception;
3230 l_ut_owner varchar2(250) := ut_utils.ut_owner;
3331 l_set_id integer := 0;
32+ begin
33+ -- We use DBMS_XMLGEN in order to:
34+ -- 1) be able to process data in bulks (set of rows)
35+ -- 2) be able to influence the ROWSET/ROW tags
36+ -- 3) be able to influence the way NULL values are handled (empty TAG)
37+ -- 4) be able to influence the way TIMESTAMP is formatted.
38+ -- Due to Oracle feature/bug, it is not possible to change the DATE formatting of cursor data
39+ -- AFTER the cursor was opened.
40+ -- The only solution for this is to change NLS settings before opening the cursor.
41+ --
42+ -- This would work fine if we could use DBMS_XMLGEN.restartQuery.
43+ -- The restartQuery fails however if PLSQL variables of TIMESTAMP/INTERVAL or CLOB/BLOB are used.
44+ ut_expectation_processor.set_xml_nls_params();
45+ l_ctx := dbms_xmlgen.newContext(l_cursor);
46+ dbms_xmlgen.setNullHandling(l_ctx, dbms_xmlgen.empty_tag);
47+ dbms_xmlgen.setMaxRows(l_ctx, c_bulk_rows);
48+
49+ loop
50+ l_xml := dbms_xmlgen.getxmltype(l_ctx);
51+ exit when dbms_xmlgen.getNumRowsProcessed(l_ctx) = 0;
52+
53+ self.elements_count := self.elements_count + dbms_xmlgen.getNumRowsProcessed(l_ctx);
54+ execute immediate
55+ 'insert into ' || l_ut_owner || '.ut_compound_data_tmp(data_id, item_no, item_data) ' ||
56+ 'values (:self_guid, :self_row_count, :l_xml)'
57+ using in self.data_id, l_set_id, l_xml;
58+
59+ l_set_id := l_set_id + c_bulk_rows;
60+ end loop;
61+
62+ ut_expectation_processor.reset_nls_params();
63+ dbms_xmlgen.closeContext(l_ctx);
64+ exception
65+ when others then
66+ ut_expectation_processor.reset_nls_params();
67+ dbms_xmlgen.closeContext(l_ctx);
68+ raise;
69+ end;
3470
71+ member procedure init(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor) is
72+ l_cursor sys_refcursor := a_value;
73+ cursor_not_open exception;
3574 begin
3675 self.is_data_null := ut_utils.boolean_to_int(a_value is null);
3776 self.self_type := $$plsql_unit;
@@ -41,46 +80,13 @@ create or replace type body ut_data_value_refcursor as
4180
4281 if l_cursor is not null then
4382 if l_cursor%isopen then
44- --Get some more info regarding cursor, including if it containts collection columns and what is their name
45-
83+ --Get some more info regarding cursor, including if it containts collection columns and what is their name
4684 self.elements_count := 0;
4785 self.cursor_details := ut_cursor_details(l_cursor);
48- -- We use DBMS_XMLGEN in order to:
49- -- 1) be able to process data in bulks (set of rows)
50- -- 2) be able to influence the ROWSET/ROW tags
51- -- 3) be able to influence the way NULL values are handled (empty TAG)
52- -- 4) be able to influence the way TIMESTAMP is formatted.
53- -- Due to Oracle feature/bug, it is not possible to change the DATE formatting of cursor data
54- -- AFTER the cursor was opened.
55- -- The only solution for this is to change NLS settings before opening the cursor.
56- --
57- -- This would work fine if we could use DBMS_XMLGEN.restartQuery.
58- -- The restartQuery fails however if PLSQL variables of TIMESTAMP/INTERVAL or CLOB/BLOB are used.
59-
60- ut_expectation_processor.set_xml_nls_params();
61- l_ctx := dbms_xmlgen.newContext(l_cursor);
62- dbms_xmlgen.setNullHandling(l_ctx, dbms_xmlgen.empty_tag);
63- dbms_xmlgen.setMaxRows(l_ctx, c_bulk_rows);
64-
65- loop
66- l_xml := dbms_xmlgen.getxmltype(l_ctx);
67- exit when dbms_xmlgen.getNumRowsProcessed(l_ctx) = 0;
68-
69- self.elements_count := self.elements_count + dbms_xmlgen.getNumRowsProcessed(l_ctx);
70- execute immediate
71- 'insert into ' || l_ut_owner || '.ut_compound_data_tmp(data_id, item_no, item_data) ' ||
72- 'values (:self_guid, :self_row_count, :l_xml)'
73- using in self.data_id, l_set_id, l_xml;
74-
75- l_set_id := l_set_id + c_bulk_rows;
76- end loop;
77-
78- ut_expectation_processor.reset_nls_params();
86+ extract_cursor(l_cursor);
7987 if l_cursor%isopen then
8088 close l_cursor;
81- end if;
82- dbms_xmlgen.closeContext(l_ctx);
83-
89+ end if;
8490 elsif not l_cursor%isopen then
8591 raise cursor_not_open;
8692 end if;
@@ -89,11 +95,9 @@ create or replace type body ut_data_value_refcursor as
8995 when cursor_not_open then
9096 raise_application_error(-20155, 'Cursor is not open');
9197 when others then
92- ut_expectation_processor.reset_nls_params();
9398 if l_cursor%isopen then
9499 close l_cursor;
95100 end if;
96- dbms_xmlgen.closeContext(l_ctx);
97101 raise;
98102 end;
99103
0 commit comments