@@ -126,27 +126,33 @@ create or replace package body ut_utils is
126126 return case a_value when 1 then true when 0 then false end;
127127 end;
128128
129- function string_to_table(a_string varchar2, a_delimiter varchar2:= chr(10)) return ut_output_varchar2_list is
129+ function string_to_table(a_string varchar2, a_delimiter varchar2:= chr(10), a_skip_leading_delimiter varchar2 := 'N' ) return ut_output_varchar2_list pipelined is
130130 l_offset integer := 1;
131131 l_length integer;
132- l_result ut_output_varchar2_list := ut_output_varchar2_list();
133132 l_delimiter_position integer;
133+ l_skip_leading_delimiter boolean := coalesce(a_skip_leading_delimiter = 'Y',false);
134134 begin
135- if a_string is not null and a_delimiter is not null then
136- l_length := length(a_string);
137- loop
138- l_result.extend;
139- l_delimiter_position := instr(a_string, a_delimiter, l_offset);
135+ if a_string is null then
136+ return;
137+ end if;
138+ if a_delimiter is null then
139+ pipe row(a_string);
140+ return;
141+ end if;
142+ l_length := length(a_string);
143+ loop
144+ l_delimiter_position := instr(a_string, a_delimiter, l_offset);
145+ if not (l_delimiter_position = 1 and l_skip_leading_delimiter) then
140146 if l_delimiter_position > 0 then
141- l_result(l_result.last) := substr(a_string, l_offset, l_delimiter_position - l_offset);
147+ pipe row( substr(a_string, l_offset, l_delimiter_position - l_offset) );
142148 else
143- l_result(l_result.last) := substr(a_string, l_offset);
149+ pipe row( substr(a_string, l_offset) );
144150 end if;
145- exit when l_delimiter_position = 0 ;
146- l_offset := l_delimiter_position + 1 ;
147- end loop ;
148- end if ;
149- return l_result ;
151+ end if ;
152+ exit when l_delimiter_position = 0 ;
153+ l_offset := l_delimiter_position + 1 ;
154+ end loop ;
155+ return;
150156 end;
151157
152158 function clob_to_table(a_clob clob, a_delimiter varchar2:= chr(10), a_max_amount integer := 32767) return ut_output_varchar2_list pipelined is
@@ -155,26 +161,37 @@ create or replace package body ut_utils is
155161 l_amount integer := a_max_amount;
156162 l_buffer varchar2(32767);
157163 l_last_line varchar2(32767);
158- l_results ut_output_varchar2_list;
159- l_is_last_line boolean;
164+ l_results ut_output_varchar2_list;
165+ l_has_last_line boolean;
166+ l_skip_leading_delimiter varchar2(1) := 'N';
160167 begin
161168 while l_offset <= l_length loop
162169 l_amount := a_max_amount - coalesce( length(l_last_line), 0 );
163170 dbms_lob.read(a_clob, l_amount, l_offset, l_buffer);
164171 l_offset := l_offset + l_amount;
165172
166- l_results := string_to_table( l_last_line || l_buffer, a_delimiter );
167- l_is_last_line := false;
173+ select column_value
174+ bulk collect into l_results
175+ from table( string_to_table( l_last_line || l_buffer, a_delimiter, l_skip_leading_delimiter ) );
168176 for i in 1 .. l_results.count loop
169- if i < l_results.count or l_results.count = 1 then
177+ --if a split of lines was not done or not at the last line
178+ if l_results.count = 1 or i < l_results.count then
170179 pipe row( l_results(i) );
171- else
172- l_is_last_line := true;
173- l_last_line := l_results(i);
174180 end if;
175181 end loop;
182+
183+ --check if we need to append the last line to the next element
184+ if l_results.count = 1 then
185+ l_has_last_line := false;
186+ l_last_line := null;
187+ elsif l_results.count > 1 then
188+ l_has_last_line := true;
189+ l_last_line := l_results(l_results.count);
190+ end if;
191+
192+ l_skip_leading_delimiter := 'Y';
176193 end loop;
177- if l_is_last_line then
194+ if l_has_last_line then
178195 pipe row( l_last_line );
179196 end if;
180197 return;
0 commit comments