Here it is as part of a package. Apologies for the rush job at the time; inelegant, but it was worth it...
gi_chunk_length integer := 0;
gv_chunk varchar2(32767);
-- add a character value to the CLOB being built up; catch null values
-- NOTE - final flush is done elsewhere
-- and we assume max(length(av_value)) < ki_maxchunksize
PROCEDURE lob_append (at_doc_clob IN OUT NOCOPY CLOB, av_value IN VARCHAR2)
IS
li_value_length integer;
li_new_chunk_length integer;
ki_maxchunksize constant integer := 32000;
BEGIN
-- prt_common_pkg.print_xml_string(av_value);
IF av_value IS NOT NULL THEN
li_value_length := length(av_value);
li_new_chunk_length := gi_chunk_length + li_value_length;
if li_new_chunk_length >= ki_maxchunksize
then
-- pad out the chunk as much as possible
gv_chunk := gv_chunk || substr(av_value,1,ki_maxchunksize - gi_chunk_length);
-- write out
DBMS_LOB.append (at_doc_clob, gv_chunk);
-- initialise remainder into next chunk
gi_chunk_length := li_new_chunk_length - ki_maxchunksize;
gv_chunk := substr(av_value,li_value_length +1 - gi_chunk_length);
else
gv_chunk := gv_chunk || av_value;
gi_chunk_length := li_new_chunk_length;
end if;
ELSE
prt_common_pkg.LOG ('lob_append null ignored',
prt_common_pkg.klog_ret
);
END IF;
END;
The final flush of the last chunk of a LOB is called like this:
IF gi_chunk_length > 0 THEN
-- flush out the last chunk of the CLOB
dbms_lob.append(at_doc_clob, gv_chunk);
gi_chunk_length := 0;
gv_chunk := null;
END IF;
1 comment:
I made this VBScript-version of your StringBuilder.
My conclusion is that this technique does not work well in VBScript. You need to concatenate the small strings "normally" first, and use the StringBuilder when the accumulated length of the small strings reaches a few hundred characters.
Regards,
Jens Ulrik
Class clsStringBuilderArr
Private arr, strAdd, lngSize, lngCount, strChunk, lngChunck, lngChunckNew, lngAdd, lngChunckMax
Public Property Get Length
Length = Len(Value)
End Property
Public Property Get Value
Value = Join(arr, "") & strChunk
End Property
Public Sub Add(ByRef pstrAdd)
strAdd = "" & pstrAdd
lngAdd = Len(strAdd)
If (lngAdd = 0) Then Exit Sub
lngChunckNew = lngChunck + lngAdd
If (lngChunckNew >= lngChunckMax) Then
If (lngCount > lngSize - 1) Then lngSize = 2 * lngSize: ReDim Preserve arr(lngSize - 1)
arr(lngCount) = strChunk & strAdd
lngCount = lngCount + 1
lngChunck = 0
strChunk = ""
Else
strChunk = strChunk & strAdd
lngChunck = lngChunckNew
End If
End Sub
Public Sub Clear()
Class_Initialize
End Sub
Private Sub Class_Initialize()
lngSize = 32768
lngCount = 0
lngChunck = 0
strChunk = ""
lngChunckMax = 1024
ReDim arr(lngSize - 1)
End Sub
End Class
Post a Comment