-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathF_BLOB_TO_LIST.sql
77 lines (57 loc) · 2.38 KB
/
F_BLOB_TO_LIST.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
create or replace function F_BLOB_TO_LIST ( I_BLOB in blob
) return T_STRING_LIST PIPELINED is
/********************************************************************************************************************
The F_BLOB_TO_LIST creates list of lines from the BLOB input parameter.
It can manage LF or CR+LF line delimiters.
Sample:
-------
select * from table( F_BLOB_TO_LIST ( clob_to_blob( 'hello'||chr(13)||chr(10)||'bello' ) ) )
Result:
-------
hello
bello
History of changes
yyyy.mm.dd | Version | Author | Changes
-----------+---------+----------------+-------------------------
2017.01.16 | 1.0 | Ferenc Toth | Created
********************************************************************************************************************/
V_LINE varchar2( 32000 );
V_OFFSET number := 1;
V_AMOUNT number := 4000;
V_LENGTH number;
V_BUFFER varchar2( 32000 );
V_STRING_LIST T_STRING_LIST := T_STRING_LIST();
begin
-- check
V_LENGTH := dbms_lob.getlength( I_BLOB );
if V_LENGTH > 0 then
while V_OFFSET < V_LENGTH loop
-- get the next part of blob
V_BUFFER := utl_raw.cast_to_varchar2( dbms_lob.substr( I_BLOB, V_AMOUNT, V_OFFSET ) );
V_BUFFER := replace( V_BUFFER, chr( 13 ), null );
-- crate a list from it
V_STRING_LIST.delete;
for L_R in ( select * from table( F_CSV_TO_LIST( V_BUFFER, chr( 10 ), null ) ) )
loop
V_STRING_LIST.extend;
V_STRING_LIST( V_STRING_LIST.count ) := L_R.COLUMN_VALUE;
end loop;
-- go through the list elements
for L_I in 1..V_STRING_LIST.count
loop
V_LINE := V_LINE || V_STRING_LIST( L_I );
if L_I < V_STRING_LIST.count then -- the last row should be truncated
PIPE ROW( V_LINE );
V_LINE := '';
end if;
end loop;
V_OFFSET := V_OFFSET + V_AMOUNT;
end loop;
-- put out the last one as well
if V_LINE is not null then
PIPE ROW( V_LINE );
end if;
end if;
return;
end;
/