PL/SQL   «Prev  Next»

Lesson 1

Querying and Modifying LOBs

A document-management application needs more than document numbers and titles. It may also store the text of a report, its original PDF, and an associated image. Oracle large object types, usually called LOBs, provide a way to represent these larger values alongside the ordinary columns that describe them. This module introduces the types and the operations used to work with their contents.

The objective is to understand how to query and modify LOB data in Oracle. You will connect familiar SQL operations with PL/SQL interfaces, distinguish database content from external files, and prepare for examples involving object tables and loading utilities. Begin with the purpose of the data, then select its type and access method. The size of a file alone does not determine the correct design.

Choosing a LOB type

LOB names describe a family of types, not a single type called LOB that you use in every declaration. A table column or PL/SQL variable has a concrete type, such as CLOB or BLOB. The following comparison provides the starting point for choosing one.

Oracle large object types
TypeContentStorage and access
BLOBBinary bytes, such as a PDF or photographInternal LOB, with read and write operations
CLOBText in the database character setInternal character LOB
NCLOBText in the national character setInternal national-character LOB
BFILEA reference to an external binary fileFile outside database tablespaces; Oracle accesses its contents read-only

For the document application, the report's searchable text and original PDF serve different purposes. A CLOB can represent the text, while a BLOB preserves the PDF bytes. Putting the PDF into a character column would confuse a file format with character data. Conversely, storing ordinary text as uninterpreted bytes makes the application responsible for interpreting its encoding when reading it.

A CLOB is not limited to single-byte characters. Its text uses the database character set, which can support Unicode. An NCLOB uses the national character set. Choose between them according to the application's character-set requirements rather than assuming that every multilingual document requires NCLOB. A binary value can also contain Unicode-encoded bytes, but those bytes do not acquire character semantics merely because they reside in a BLOB.

Understanding values and locators

Distinguish the content from the reference used to access it. The content is the LOB value; a locator lets a supported interface identify and operate on that value. When working with locator-based operations, obtaining the locator does not mean that your application has already copied the entire document into a small string variable.

Consider an application that displays a report title before opening its contents. It can first retrieve identifying information, then retrieve the content when the reader requests it. This separates browsing records from transferring documents. The same distinction helps explain why a routine may work with part of a LOB instead of receiving the whole value as one buffer.

Internal LOB content can be stored within the table row or outside it, depending on its size and storage settings. Out-of-line storage is still database storage. It does not turn a CLOB into an external file, and it does not change its declared type. The physical placement of the bytes and the application's logical choice of datatype answer different questions.

Internal LOBs and external files

BLOB, CLOB, and NCLOB values stored in table rows are persistent internal LOBs. Their changes participate in database transactions. BFILE content lives outside database tablespaces, and its bytes are not managed by the database transaction or included in database backups. This distinction matters when deciding who is responsible for keeping a document available.

A BFILE locator identifies a file through an Oracle directory object and a filename. Access requires suitable database privileges and operating-system permissions. A reference can become unusable if the file is moved or the database server cannot read it. Changing the stored reference and changing the external file are separate actions.

For example, a document application might reference externally maintained source material while storing approved report text internally. The design should say which system owns each copy and how each copy is recovered. Treating an external path as though it guarantees a preserved database document would leave that responsibility unclear.

Modern storage and legacy terminology

Oracle AI Database 26ai continues to support LOBs. SecureFiles is the recommended modern storage mechanism for internal LOBs and is the default under the applicable configuration and tablespace requirements. It is a storage implementation, not another datatype to substitute for CLOB or BLOB in a declaration. BasicFiles is older storage that you may encounter when maintaining existing databases.

Do not carry the historical blanket limit of 4 GB into a modern design. Oracle's current LOB guide describes maximum LOB sizes ranging from 8 TB to 128 TB, depending on database configuration. That is a capacity overview, not a promise that every installation or interface can handle the largest value. It also should not be applied to external BFILE capacity.

Older schemas may use LONG for character data or LONG RAW for binary data. These are legacy types rather than members of the four-type comparison above. RAW is not the name for legacy long character text. When reviewing an older schema, identify its actual column definitions before planning a migration; an introductory example cannot establish that existing application code is migration-ready.

A small relational example

LOBs do not require object tables. The following illustrative example uses an ordinary relational table so that the relationship between metadata and content remains visible. Later object-table examples can apply the same type distinctions to attributes. These statements are learning examples and have not been executed as part of this lesson preparation.

CREATE TABLE lesson_documents (
    document_id NUMBER PRIMARY KEY,
    title       VARCHAR2(200) NOT NULL,
    body        CLOB
);

INSERT INTO lesson_documents (document_id, title, body)
VALUES (1, 'LOB introduction', TO_CLOB('First draft.'));

COMMIT;

The numeric identifier provides a compact way to find the row. The title is short descriptive text, and the body is the document content. The initial value is deliberately small so that the example is readable. A short demonstration value does not imply that a CLOB is needed for every short sentence; the column represents a document whose contents may grow.

The example assumes a practice schema with permission and space to create a table of this name. Keep such demonstrations separate from application tables. In a real design, choose names, constraints, privileges, and storage settings according to the surrounding application rather than copying an isolated example unchanged.

Querying metadata and content

A useful first query asks which document is present and how much content it contains. DBMS_LOB.GETLENGTH reports the length of a CLOB in characters. A small DBMS_LOB.SUBSTR request can produce a preview without requesting the entire document.

SELECT document_id,
       title,
       DBMS_LOB.GETLENGTH(body) AS body_length,
       DBMS_LOB.SUBSTR(body, 80, 1) AS body_preview
FROM lesson_documents
WHERE document_id = 1;

Here, the preview requests up to 80 characters starting at position 1. It is a sample of the contents, not a replacement for the document. A user interface should make that distinction clear: a shortened preview must not be mistaken for evidence that the stored value was truncated.

LOBs do not support every operation available for smaller scalar values. For example, directly ordering or grouping by a LOB column is restricted, as is selecting distinct LOB values. Sort a document list by appropriate metadata such as title or identifier. Consult the supported-operation rules before using a familiar SQL expression on the content itself.

Replacing content with SQL

Updating a complete document value can be expressed with ordinary SQL. The WHERE clause identifies the intended row, while the SET clause supplies its replacement content. This is conceptually different from changing a selected portion of the existing document.

UPDATE lesson_documents
SET body = TO_CLOB('Revised introduction to Oracle LOBs.')
WHERE document_id = 1;

COMMIT;

In this example, the earlier text is replaced. It is not preserved automatically as a previous revision in an application history table. If users need version history, design that feature explicitly. The presence of a large-object column does not by itself define document approval, revision naming, or retention rules.

Transaction boundaries remain important. An application should commit when its complete logical change is ready, which may include both document content and related metadata. The standalone COMMIT makes this teaching example explicit; it is not a requirement to commit after every statement inside a larger business operation.

Introducing piecewise PL/SQL operations

The DBMS_LOB package provides operations for reading and manipulating LOB contents. For a persistent internal LOB, a typical editing sequence obtains a locator, locks the row for modification, performs the change, and completes the transaction. This allows a program to express an operation such as appending text without constructing a replacement for the complete document.

DECLARE
    l_body CLOB;
    l_note VARCHAR2(100) := ' Reviewed.';
BEGIN
    SELECT body
      INTO l_body
      FROM lesson_documents
     WHERE document_id = 1
       FOR UPDATE;

    DBMS_LOB.WRITEAPPEND(l_body, LENGTH(l_note), l_note);
END;
/
COMMIT;

This example assumes that the preceding row exists and that its body is populated. The appended buffer contains simple characters, and LENGTH supplies its character count. The slash is a script execution delimiter used by clients such as SQL*Plus; it is not part of the PL/SQL block submitted through every application interface.

For larger or multilingual transfers, consult the routine's buffer, amount, offset, and character-boundary requirements. Binary operations measure their data differently from character operations. Error handling and transaction recovery also belong in a production routine. The short block illustrates the sequence without pretending to provide a complete document-editing service.

Missing, empty, and populated values

An internal LOB can be NULL, initialized but empty, or populated. These states should have distinct meanings in your application. A NULL body might mean that no document has been supplied. An empty body might mean that a document has been initialized but contains no content yet.

For a CLOB column, EMPTY_CLOB() can initialize an empty LOB in an INSERT or UPDATE. An empty stored LOB has length zero and is not NULL. Do not assume that testing IS NOT NULL proves a document contains text, or that an empty value and a missing value are interchangeable.

When using locator-based writes, obtain a suitable locator for the stored LOB, for example through a query or a DML RETURNING clause. Do not simply pass the direct result of EMPTY_CLOB() to DBMS_LOB and expect it to identify a writable stored document. Initialization and retrieval of an appropriate locator are separate parts of the workflow.

Deleting rows and planning document lifecycle

A DELETE statement removes the selected database row. For the practice example, DELETE FROM lesson_documents WHERE document_id = 1 selects the row by its identifier. Run that only when you intend to finish using the example, because subsequent queries and updates will no longer find the row after the deletion is committed.

Application requirements may call for retaining an inactive document instead of deleting its row. Decide that from the business rule, then implement the corresponding status or history design. The datatype does not make that decision. Similarly, deleting a database row containing a BFILE reference does not delete the external operating-system file.

Loading and application interfaces

SQL*Loader provides a route for loading data into Oracle tables, including tables with LOB content. A loading plan must connect each document with its identifying metadata. For the report application, that means making sure the title, identifier, and content all describe the same document. The later loading lesson develops the mechanics.

OCI is Oracle's C-language database interface, while JDBC provides database access for Java applications. PL/SQL programs use database-side facilities such as DBMS_LOB. These interfaces address different application environments; choosing one does not change whether the underlying content is character data, binary data, or an external file.

When planning a load or an application transfer, ask how errors will be detected and which operation can be retried. A file arriving successfully is not enough if it becomes associated with the wrong document number. Reliable LOB handling includes the ordinary relational discipline of identifying the right row and preserving its relationships.

Reviewing a LOB design before implementation

Work through a document's lifecycle before writing a larger program. Start with creation: does a user upload a binary file, enter editable text, or provide a reference to a file managed elsewhere? Next consider retrieval: does the application show a title list, a preview, or the complete contents? Finally consider change: is the document replaced as a whole, extended with additional text, or retained as a fixed record?

These questions help separate application behavior from storage choices. A title list does not need to download every attachment. An approval operation may need to update both the document and its status together. A system that retains an original upload may need another value for edited text rather than repeatedly replacing the original bytes.

Use the same questions when reviewing the examples in this module. Identify the target row, the intended type, the requested operation, and the transaction boundary. If an example uses an external file, identify who controls that file and whether the database server can access it. If it uses an internal LOB, distinguish replacing its contents from changing its metadata.

A useful learning check is to describe the expected result before executing a statement. After an append, the old text should remain with new text at the end. After a replacement, the new value should stand alone. After a preview query, the stored document should remain unchanged. This habit makes later exercises easier to reason about and helps reveal mistakes that a successful statement execution alone would not expose.

Module objectives

As you continue through this module, use the document example to connect the new operations with familiar database work. By the end, you should be able to:

  1. Choose among BLOB, CLOB, NCLOB, and BFILE for a stated content requirement.
  2. Explain the relationship between a LOB value, its locator, and its storage location.
  3. Create tables, including object-table examples, with appropriate LOB columns or attributes.
  4. Query content and metadata, modify internal LOBs, and manage rows containing them.
  5. Describe how SQL*Loader and application interfaces support LOB workflows.

Before moving on, consider a report with both editable text and an original scanned image. Which type fits each value? Would an external reference satisfy a requirement that the database retain the only authoritative copy? Answering those questions establishes the purpose of the design before you choose individual SQL or PL/SQL operations.

In the next lesson, Types of Oracle LOBs, you will compare these types more closely and build on the distinctions introduced here.

Oracle documentation

SEMrush Software 1 SEMrush Banner 1