@@ -15,69 +15,118 @@ create or replace type body ut_data_value_anydata as
1515 See the License for the specific language governing permissions and
1616 limitations under the License.
1717 */
18- member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata) is
19- l_query sys_refcursor;
20- l_ctx number;
21- l_ut_owner varchar2(250) := ut_utils.ut_owner;
22- cursor_not_open exception;
23- l_cursor_number number;
24- l_anydata_type varchar2(100) := get_instance(a_value);
25- l_element_count number;
18+
19+ member function is_null(a_value in anydata) return number is
20+ l_result integer := 0;
21+ l_anydata_sql varchar2(4000);
22+ begin
23+ if a_value is not null and self.compound_type = 'object' then
24+ l_anydata_sql := '
25+ declare
26+ l_data '||self.data_type||';
27+ l_value anydata := :a_value;
28+ l_status integer;
29+ begin
30+ l_status := l_value.get'||self.compound_type||'(l_data);
31+ :l_data_is_null := case when l_data is null then 1 else 0 end;
32+ end;';
33+ execute immediate l_anydata_sql using in a_value, out l_result;
34+ --TODO : Refactor
35+ elsif a_value is not null and self.compound_type = 'collection' then
36+ l_anydata_sql := '
37+ declare
38+ l_data '||self.data_type||';
39+ l_value anydata := :a_value;
40+ l_status integer;
41+ begin
42+ l_status := l_value.get'||self.compound_type||'(l_data);
43+ :l_data_is_null := case
44+ when l_data is null then 1
45+ when l_data is empty then 1
46+ else 0 end;
47+ end;';
48+ execute immediate l_anydata_sql using in a_value, out l_result;
49+ else
50+ l_result := 1;
51+ end if;
52+ return l_result;
53+ end;
54+
55+ overriding member function get_object_info return varchar2 is
56+ begin
57+ return self.data_type || case when self.compound_type = 'collection' then ' [ count = '||self.elements_count||' ]' else null end;
58+ end;
59+
60+ member procedure get_cursor_from_anydata(a_value in anydata, a_refcursor out sys_refcursor) is
61+ l_anydata_sql varchar2(4000);
62+
63+ function resolve_name(a_object_name in varchar2) return varchar2 is
64+ l_schema varchar(250);
65+ l_object varchar(250);
66+ l_procedure_name varchar(250);
67+ begin
68+ ut_metadata.do_resolve(a_object_name,7,l_schema,l_object, l_procedure_name);
69+ return l_object;
70+ end;
71+
72+ function get_object_name(a_value anydata) return varchar2 is
73+ begin
74+ return resolve_name(ut_metadata.get_collection_element(a_value));
75+ end;
2676
27- --Used by dbms_utility...
28- l_type_name varchar2(250);
29- l_schema varchar(250);
30- l_part1 varchar(250);
31- l_part2 varchar(250);
32- l_dblink varchar(250);
33- l_part1_type number;
34- l_objectid number;
77+ function get_object_name(a_datatype in varchar2) return varchar2 is
78+ begin
79+ return resolve_name(a_datatype);
80+ end;
3581
3682 begin
37- self.data_type := case when a_value is not null then lower(a_value.gettypename()) else 'undefined' end;
38- self.data_id := sys_guid();
39- self.self_type := $$plsql_unit;
40- self.cursor_details := ut_cursor_details();
41- if a_value is not null then
42- --TODO : Move that to helper ??
43- dbms_utility.name_resolve(self.data_type,7, l_schema, l_part1, l_part2, l_dblink, l_part1_type, l_objectid);
44- --TODO: Refactor into something nicer
45- execute immediate '
83+ l_anydata_sql := '
4684 declare
4785 l_data '||self.data_type||';
4886 l_value anydata := :a_value;
4987 l_status integer;
5088 l_tmp_refcursor sys_refcursor;
5189 l_refcursor sys_refcursor;
5290 begin
53- l_status := l_value.get'||l_anydata_type||'(l_data);
54- :l_data_is_null := case when l_data is null then 1 else 0 end; '||
55- case when l_anydata_type = 'collection' then
56- ' open l_tmp_refcursor for select * from table(l_data);'
91+ l_status := l_value.get'||self.compound_type||'(l_data); '||
92+ case when self.compound_type = 'collection' then
93+ ' open l_tmp_refcursor for select value(x) as '||get_object_name(a_value)||' from table(l_data) x;'
5794 else
58- ' open l_tmp_refcursor for select l_data '||l_part1 ||' from dual;'
95+ ' open l_tmp_refcursor for select l_data '||get_object_name(self.data_type) ||' from dual;'
5996 end ||
60- q'[ :l_refcursor := l_tmp_refcursor;
61- if l_data is not null then
62- :l_count := ]'|| case when l_anydata_type = 'collection' then 'l_data.count; ' else '0; ' end ||
63- 'end if;
64- end;' using in a_value, out self.is_data_null, out l_query, out l_element_count;
65- else
66- self.is_data_null := 1;
97+ ' :l_refcursor := l_tmp_refcursor;
98+ end;';
99+ execute immediate l_anydata_sql using in a_value, out a_refcursor;
100+ end;
101+
102+ member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata) is
103+ l_refcursor sys_refcursor;
104+ l_ctx number;
105+ l_ut_owner varchar2(250) := ut_utils.ut_owner;
106+ cursor_not_open exception;
107+ l_cursor_number number;
108+
109+ begin
110+ self.data_type := case when a_value is not null then lower(a_value.gettypename()) else 'undefined' end;
111+ self.compound_type := get_instance(a_value);
112+ self.extract_path := '/*/*';
113+ self.data_id := sys_guid();
114+ self.self_type := $$plsql_unit;
115+ self.cursor_details := ut_cursor_details();
116+ self.is_data_null := is_null(a_value);
117+ self.elements_count := 0;
118+ if not self.is_null() then
119+ get_cursor_from_anydata(a_value,l_refcursor);
67120 end if;
121+
68122 ut_compound_data_helper.cleanup_diff;
69123 if not self.is_null() then
70- self.elements_count := 0;
71- if l_query%isopen then
72- self.extract_cursor(l_query);
73- --For collection we have to overwrite a number due to being calculated not correctly
74- if l_anydata_type = 'collection' then
75- self.elements_count := l_element_count;
76- end if;
77- l_cursor_number := dbms_sql.to_cursor_number(l_query);
124+ if l_refcursor%isopen then
125+ self.elements_count := self.extract_cursor(l_refcursor);
126+ l_cursor_number := dbms_sql.to_cursor_number(l_refcursor);
78127 self.cursor_details := ut_cursor_details(l_cursor_number);
79128 dbms_sql.close_cursor(l_cursor_number);
80- elsif not l_query %isopen then
129+ elsif not l_refcursor %isopen then
81130 raise cursor_not_open;
82131 end if;
83132 end if;
0 commit comments