| Lesson 4 | The DBMS_LOB package |
| Objective | Describe the components of the DBMS_LOB package. |
Creating a table with a LOB column defines where an application can store a photograph, document, or other large value. The next question is how a program works with that value. Oracle AI Database 26ai provides the DBMS_LOB package for reading, searching, modifying, and managing large objects through PL/SQL.
The package supports internal binary and character LOBs, external file references, and temporary LOBs. Its routines can operate on part of a value without requiring the application to place the entire document in one scalar variable. Learning the package therefore means understanding both the available operations and the locators, buffers, offsets, and resources those operations use.
A LOB locator identifies a LOB value for an operation. It is not an ordinary character string containing the whole document. For example, a variable declared as CLOB can identify a large text value, while a VARCHAR2 buffer holds a bounded piece of text read from it. Similarly, a BLOB locator and a RAW buffer serve different roles when processing binary data.
Before choosing a routine, identify the content and its lifetime. BLOB holds binary content. CLOB and NCLOB hold character content with their respective character-set semantics. A persistent internal LOB belongs to stored database data, whereas a temporary LOB supports intermediate processing. SecureFiles is a storage implementation, not an additional PL/SQL content datatype.
A BFILE is different: its locator references an external server-side file. DBMS_LOB provides read-only access to that file's content. An application cannot treat a BFILE as a destination for the same WRITE operations used with a BLOB. File availability and permissions remain part of the external-file environment.
Declaring a locator variable does not create a usable LOB value. A program must obtain a suitable locator, for example by selecting an existing LOB column or creating a temporary LOB. This distinction explains why a declaration alone is insufficient preparation for a write.
The package contains several kinds of components. Functions return values that can be assigned to variables or used in expressions. Procedures perform operations and may return information through OUT or IN OUT parameters. Constants give readable names to operation modes and lifetime choices. Exceptions signal failures that the calling program must handle appropriately.
For instance, GETLENGTH returns a number, while READ fills a caller-provided buffer and reports the amount read through a parameter. WRITEAPPEND changes a destination LOB rather than returning a new string. Recognizing these differences helps you read a routine's signature and avoid treating every package member as an interchangeable function.
Use qualified names such as DBMS_LOB.GETLENGTH in code. The package prefix makes the source of the operation clear, especially when a name resembles a SQL string function. Check the overload for your LOB type because a familiar routine name does not imply that every datatype accepts the same arguments.
The first group answers questions about existing content. A program might inspect a document's length, display a short preview, search for a marker, or compare selected regions. These operations have different outputs even when they examine the same value.
| Routine | Kind | Purpose |
|---|---|---|
GETLENGTH | Function | Return the length of the LOB value. |
READ | Procedure | Read a requested region into a buffer and report the amount read. |
SUBSTR | Function | Return a bounded portion beginning at an offset. |
INSTR | Function | Locate a specified occurrence of a pattern. |
COMPARE | Function | Compare two values or selected regions of them. |
GETLENGTH measures binary LOBs and BFILEs in bytes, but character LOBs in characters. Offsets begin at 1. In a CLOB containing Hello LOB, the first character is H, the sixth character is a space, and the total length is nine characters. This small example makes the unit and starting position explicit.
SUBSTR is convenient for a preview because it returns a bounded result directly. READ is useful when the program manages a buffer and processes successive portions. When processing a large value, track how much was actually read and advance the offset accordingly. Do not assume that every call returns the originally requested amount.
COMPARE returns zero when the compared regions are equal. The chosen offsets and amount determine what was compared; comparing a prefix does not establish equality of two complete documents. Also distinguish a valid unequal result from NULL or an invalid-argument condition. Consult the individual routine's contract instead of applying one universal rule to every return value.
A large LOB can exceed the capacity of a PL/SQL scalar buffer. The package reference specifies a maximum buffer size of 32,767 bytes for these PL/SQL LOB operations. Character amounts must still fit within that byte capacity, so a request for 32,767 multibyte characters is not automatically valid.
Choose a buffer and amount that match the datatype and encoding, then process larger values in pieces. This is different from limiting the size of the stored document. A document may require many bounded reads even though each individual operation is valid. The same distinction matters when writing data from buffers into a LOB.
The modification routines operate on writable internal LOBs. Choose the operation according to the source of the new content and what should happen to the destination. Appending another LOB, appending a buffer, and replacing a region are separate tasks.
| Procedure | Operation |
|---|---|
WRITE | Write buffer content beginning at a specified offset. |
WRITEAPPEND | Write buffer content at the end of the destination. |
APPEND | Append the contents of a source LOB to a destination LOB. |
COPY | Copy a selected source region to a destination offset. |
ERASE | Replace a region with filler bytes or spaces without shortening the value. |
TRIM | Reduce the LOB to a specified shorter length. |
APPEND and WRITEAPPEND differ in the source they accept. Use APPEND when the source is another compatible LOB. Use WRITEAPPEND when the source is a buffer, such as a short piece of report text constructed by PL/SQL. This distinction is more useful than memorizing two nearly identical names.
ERASE and TRIM also have different effects. ERASE replaces a region with zero-byte fillers in a BLOB or spaces in a character LOB; it does not remove a table row or shift subsequent content to close a gap. TRIM shortens the value. A program that needs a smaller document must not assume that erasing characters reduces its length.
COPY and WRITE should not be interpreted as text-editor insertion commands that automatically push the remaining content forward. Decide whether the application needs replacement, appending, shortening, or a specialized fragment operation before selecting the routine. Matching the operation to the intended result prevents subtle content errors.
When modifying a persistent internal LOB through the package, obtain the appropriate row lock before changing the value. A common approach is SELECT ... FOR UPDATE to retrieve the locator while locking its row. Opening a LOB is not a substitute for locking the row that contains it.
Keep locator acquisition, modification, and the transaction outcome together in the application design. Do not scatter commits through low-level helper routines without understanding the caller's transaction. Temporary LOBs are different because they are not persistent table rows; their resource lifecycle must not be confused with the rollback behavior of stored data.
A BFILE locator combines a directory-object reference with a filename. The actual bytes remain in the server's filesystem. A file-loading program therefore depends on more than a valid database row: the directory must be configured, the user must have the necessary access, and the server process must be able to read the file.
| Routine | Purpose |
|---|---|
FILEOPEN | Open the referenced file for read-only access. |
FILECLOSE | Close the file associated with a locator. |
FILECLOSEALL | Close the session's previously opened BFILEs. |
FILEISOPEN | Check the file's open state for the locator. |
FILEEXISTS | Check whether the referenced file exists. |
FILEGETNAME | Obtain the directory alias and filename. |
A file-existence check and a successful read are different observations. An external file can become unavailable between operations, and access problems still need handling. Programs should close files they open on both normal and exceptional paths. Prefer closing the specific resource owned by a routine rather than casually using FILECLOSEALL in reusable code.
The package also provides OPEN, CLOSE, and ISOPEN for supported LOB operations. Consult the relevant overload and mode when using these more general routines. Opening a resource establishes an access state; it neither initializes missing content nor grants permissions the caller lacks.
Loading an external file into an internal LOB changes where the application keeps the content. Use LOADBLOBFROMFILE for binary loading and LOADCLOBFROMFILE when loading character data with the required character-set handling. Older code may contain LOADFROMFILE; new examples should use the more explicit loading routines.
CONVERTTOBLOB and CONVERTTOCLOB address conversion between binary and character representations. Conversion requires attention to encoding, offsets, and warnings. A BLOB containing text bytes is not automatically a correctly interpreted CLOB, and assigning a content-type label does not convert those bytes.
CLOB2FILE supports exporting character content to a server-side file under the appropriate directory and permission rules. This export capability does not make a BFILE locator a writable internal LOB. Treat export as a separate file operation with its own destination and failure handling.
Temporary LOBs are useful for assembling a report, transforming text, or preparing content before storing it elsewhere. Three package routines describe their basic lifecycle: CREATETEMPORARY creates the value, ISTEMPORARY checks its temporary status, and FREETEMPORARY releases it when the program no longer needs it.
Choose a suitable lifetime with the CALL or SESSION constant, but still release application-created temporary LOBs promptly. A long-lived session can perform many operations; leaving every intermediate value until session termination is poor resource management. COMMIT is not a replacement for freeing temporary LOB resources.
The following demonstration creates a short temporary CLOB, appends text, inspects it, and frees it. It requires no customer table or operating-system file. The example is documentation-reviewed instructional code, not a report of execution against your database.
SET SERVEROUTPUT ON
DECLARE
l_text CLOB;
BEGIN
DBMS_LOB.CREATETEMPORARY(
lob_loc => l_text,
cache => TRUE,
dur => DBMS_LOB.CALL
);
DBMS_LOB.WRITEAPPEND(
l_text, LENGTH('Hello LOB'), 'Hello LOB'
);
DBMS_OUTPUT.PUT_LINE(
'Length: ' || DBMS_LOB.GETLENGTH(l_text)
);
DBMS_OUTPUT.PUT_LINE(DBMS_LOB.SUBSTR(l_text, 5, 1));
DBMS_LOB.FREETEMPORARY(l_text);
EXCEPTION
WHEN OTHERS THEN
IF DBMS_LOB.ISTEMPORARY(l_text) = 1 THEN
DBMS_LOB.FREETEMPORARY(l_text);
END IF;
RAISE;
END;
/
The expected text output is:
Length: 9
Hello
CREATETEMPORARY supplies the usable locator. WRITEAPPEND receives the text buffer and its character count. GETLENGTH examines the resulting value, while SUBSTR requests five characters beginning at position 1. Finally, FREETEMPORARY ends the example's ownership of that temporary resource.
The exception handler checks for an allocated temporary LOB before attempting cleanup and then re-raises the error. Cleanup should not turn a failed operation into apparent success. SET SERVEROUTPUT ON and the terminating slash are SQL*Plus or SQLcl client commands; they are not SQL text to send unchanged through an application driver.
Named constants make intent clearer than unexplained numbers. LOB_READONLY and LOB_READWRITE identify supported internal LOB open modes; FILE_READONLY describes external-file access. CALL and SESSION describe temporary lifetime choices. Choose the constant appropriate to the routine instead of assuming that similar numeric values are interchangeable documentation.
Package exceptions and application exception handlers are different things. The package can report invalid arguments, unusable locators, file errors, or restricted operations. The caller decides whether to clean up, retry, report a useful message, or propagate the failure. The exact behavior belongs to the individual subprogram's contract.
When troubleshooting, start with a short sequence of questions: was the locator initialized, are the amount and offset valid, does the buffer fit, and does the caller have the necessary access? For persistent writes, also check the row lock. For external files, check the directory and actual server-side file rather than a similarly named file on the client computer.
Suppose an application needs to display the beginning of a customer's textual report. It should first obtain the correct character LOB locator, then request a bounded preview with SUBSTR. It should not assume that the preview contains the complete report, nor should it select a binary operation merely because both BLOB and CLOB belong to the LOB family.
Now suppose the application assembles a report from several short messages. WRITEAPPEND matches a buffer-based construction process. If the source is already another compatible LOB, APPEND expresses that relationship more directly. The application still owns decisions about separators, headings, and character encoding; the package does not invent the report's document structure.
Finally, consider a photograph held in an external directory. Inspecting the file reference and loading its bytes into a BLOB are separate steps. The file routines address the source resource, while a loading routine addresses the transfer into database storage. Closing the file after use and handling a failed load are part of that operation's design.
These scenarios provide a useful selection method: identify the source, identify the destination, decide whether the operation reads or changes content, and then determine the necessary initialization and cleanup. Only after those choices should you fill in parameters such as amount and offset. This keeps routine selection tied to the application's actual task.
Additional routines inspect SecureFiles properties, manage content-type metadata, perform fragment operations, or work with DBFS links and remote locators. These are useful extensions after the core read, write, and lifecycle patterns are understood. Their availability does not mean that every feature applies to every LOB or environment.
GETOPTIONS can inspect supported options, but SETOPTIONS cannot toggle encryption. Its compression and deduplication controls depend on column-level availability. The DBMS_LOB deduplication-ratio routine is deprecated in favor of the corresponding DBMS_SECUREFILES routine. Consult the current reference before copying specialist examples from older material.
For signatures, overloads, limits, and exceptions, use the Oracle 26ai DBMS_LOB package reference. In the next lesson, you will apply these distinctions when retrieving and displaying LOB data.