Ваш код штраф (верхняя и нижняя версия).
Смотрите Oracle Documentation: PL/SQL Semantics for LOBs:
CLOB Переменные в PL/SQL
1 declare
2 myStory CLOB;
3 revisedStory CLOB;
4 myGist VARCHAR2(100);
5 revisedGist VARCHAR2(100);
6 BEGIN
7 -- select a CLOB column into a CLOB variable
8 SELECT Story INTO myStory FROM print_media WHERE product_id=10;
9 -- perform VARCHAR2 operations on a CLOB variable
10 revisedStory := UPPER(SUBSTR(myStory, 100, 1));
11 -- revisedStory is a temporary LOB
12 -- Concat a VARCHAR2 at the end of a CLOB
13 revisedStory := revisedStory || myGist;
14 -- The following statement will raise an error because myStory is
15 -- longer than 100 bytes
16 myGist := myStory;
17 END;
Пожалуйста, обратите внимание, что в строке 10 "CLOB переменных в PL/SQL", временный CLOB
является неявно созданный и на который указывает revisedStory
CLOB
локатор. В текущем интерфейсе линия может быть расширена, как:
buffer VARCHAR2(32000)
DBMS_LOB.CREATETEMPORARY(revisedStory);
buffer := UPPER(DBMS_LOB.SUBSTR(myStory,100,1));
DBMS_LOB.WRITE(revisedStory,length(buffer),1, buffer);
В строке 13, myGist
добавляется к концу временного LOB
, который имеет тот же эффект:
DBMS_LOB.WRITEAPPEND(revisedStory, myGist, length(myGist));
Поэтому вам не нужно вызывать процедуры DBMS_LOB
, так как PL/SQL будет неявно преобразовывать ваш код в соответствующие вызовы DBMS_LOB
.
Вам также не нужно освободить значения, как:
Временных LOBs, созданных в программном блоке в результате SELECT
или присваивания освобождаются автоматически в конце PL/SQL блок/функция/процедура. Вы можете освободить временные LOB до для восстановления системных ресурсов и временного табличного пространства путем вызова DBMS_LOB.FREETEMPORARY
в переменной CLOB
.
Но вы можете вручную называть это, если хотите контролировать, когда память освобождается (как и в нижней версии).
Спасибо! Как же глобальные CLOB? Является ли DBMS_LOB.FREETEMPORARY и назначает CLOB для NULL одинаковым? – superigno
@superigno Это неясно из документации. Я бы подумал, что они немного отличаются (т.е. «DBMS_LOB.FREETEMPORARY()» может освободить всю память, но присвоение «NULL» должно сохранить некоторую память, чтобы знать, что это значение «NULL», а не какое-то другое значение, но может освободить большинство памяти, которая ранее была выделена для текста), однако без доступа к внутренним работам, которые являются предположениями. – MT0