Skip to content
Home Database PL/SQL Variables — Hard-Coded VARCHAR2 Overflows Batch

PL/SQL Variables — Hard-Coded VARCHAR2 Overflows Batch

Where developers are forged. · Structured learning · Free forever.
📍 Part of: PL/SQL → Topic 2 of 27
A column change from VARCHAR2(30) to VARCHAR2(60) caused a production ORA-06502 due to a hard-coded variable.
🧑‍💻 Beginner-friendly — no prior Database experience needed
In this tutorial, you'll learn
A column change from VARCHAR2(30) to VARCHAR2(60) caused a production ORA-06502 due to a hard-coded variable.
  • Variables store temporary data; constants enforce immutability – use the right tool for the job.
  • Always use %TYPE for variables that hold column values – it prevents schema-migration-induced failures.
  • Uninitialized variables are NULL – explicitly initialize everything to avoid silent NULL propagation.
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
Quick Answer
  • PL/SQL Variables: named memory locations that hold values that can change during program execution
  • Constants: fixed values declared with CONSTANT — must be initialized and cannot change
  • Data Types: define the kind of data (scalar, composite, reference, LOB) and the operations allowed
  • %TYPE anchors a variable to a column's data type — schema changes propagate automatically
  • %ROWTYPE holds an entire row — reduces code maintenance when table structure changes
  • Production trap: hard-coded VARCHAR2(20) breaks when the column expands to VARCHAR2(50) — ORA-06502
🚨 START HERE

Quick Debug Cheat Sheet: PL/SQL Variable and Data Type Errors

Immediate commands and fixes for the three most common variable-related production issues.
🟡

ORA-06502 on variable assignment

Immediate ActionRun the failing block with DBMS_OUTPUT turned on to see the exact value being assigned.
Commands
SET SERVEROUTPUT ON; EXEC DBMS_OUTPUT.PUT_LINE('Value: ' || v_some_variable);
SELECT data_length FROM all_tab_columns WHERE table_name = 'SUPPLIERS' AND column_name = 'SUPPLIER_NAME';
Fix NowReplace hard-coded size with %TYPE: v_supplier_name suppliers.supplier_name%TYPE;
🟡

NULL result from arithmetic with uninitialized variable

Immediate ActionCheck if any variable in the expression was declared without DEFAULT.
Commands
SELECT DUMP(v_counter) FROM DUAL; -- shows NULL if uninitialized
Check package body for package-level variable declarations.
Fix NowAdd DEFAULT 0 or NVL(v_counter, 0) to the expression.
🟡

PLS-00302: variable name ambiguous with column

Immediate ActionAdd procedure/function name prefix or rename variable.
Commands
SHOW ERRORS; -- displays exact line and column
SELECT text FROM user_source WHERE name = 'PROCEDURE_NAME' AND line = [error_line];
Fix NowUse a naming convention like v_variable_name to avoid clashes.
Production Incident

The Silent VARCHAR2 Overflow That Took Down Month-End Processing

A hard-coded variable size caused ORA-06502 after a schema migration, corrupting a batch of financial transactions.
SymptomMonth-end batch processing started throwing ORA-06502 errors on a row that had always worked before. The error pointed to a variable in a stored procedure that had been unchanged for years.
AssumptionThe developers assumed that since the variable declaration had not changed, the error must be due to bad input data from a new upstream system.
Root causeA recent schema change altered the supplier_name column from VARCHAR2(30) to VARCHAR2(60). The PL/SQL block used a hard-coded VARCHAR2(30) variable instead of %TYPE. When a supplier name longer than 30 characters was inserted, the assignment overflowed the variable.
FixChanged the variable declaration to use %TYPE: v_supplier_name suppliers.supplier_name%TYPE. Also added an exception handler to log the actual value that caused the overflow.
Key Lesson
Never hard-code variable lengths – use %TYPE to anchor to the source column.Always handle VALUE_ERROR in PL/SQL blocks that process data from external inputs.Schema migrations must include impact analysis on PL/SQL code, especially variable declarations.
Production Debug Guide

Quick symptom-to-action reference for common variable-related failures

ORA-06502: PL/SQL numeric or value errorCheck the variable's declared size vs the value being assigned. Use %TYPE to match the source column. Enable detailed error logging with DBMS_UTILITY.FORMAT_ERROR_BACKTRACE.
Unexpected NULL in calculations or comparisonsVerify all variables are initialized explicitly. A variable declared without default is NULL. Use NVL or COALESCE to handle possible NULLs from database columns.
Memory usage grows unexpectedly in a sessionReview package-level global variables. They persist for the session. Consider using local variables or session-specific collections. Monitor with V$MYSTAT for PGA memory.
Compilation error: PLS-00302: component must be declaredCheck if the variable name conflicts with a column name in a SQL statement. Use a naming convention like v_ for variables to avoid ambiguity.

PL/SQL Variables, Constants and Data Types is a fundamental concept in Database development. In PL/SQL, every piece of information must be held in a named storage location with a specific format. By mastering these building blocks, you can create programs that are not only functional but also highly maintainable and less prone to data-related errors.

In this guide we'll break down exactly what PL/SQL Variables, Constants and Data Types is, why it was designed this way to ensure strict data integrity within the Oracle engine, and how to use it correctly in real projects.

By the end you'll have both the conceptual understanding and practical code examples to use PL/SQL Variables, Constants and Data Types with confidence.

What Is PL/SQL Variables, Constants and Data Types and Why Does It Exist?

PL/SQL Variables, Constants and Data Types is a core feature of PL/SQL. It was designed to solve the problem of temporary data storage during procedural execution. Unlike standard SQL, which processes sets of data, PL/SQL needs a way to hold individual values, calculation results, and database records in memory. Variables allow for dynamic changes, while Constants protect values that must remain fixed (like a tax rate or API version). Data types (Scalar, Large Object, Composite, and Reference) exist to tell the compiler how much memory to allocate and what operations are valid on that data.

This may seem obvious, but the real power lies in how PL/SQL enforces data integrity. A variable's type determines what you can do with it – you cannot accidentally store a date where a number is expected. The compiler catches these mismatches at compile time, not at 3 AM in production.

ForgeVariableBasics.sql · SQL
1234567891011121314151617181920212223
-- io.thecodeforge: Standard Variable and Constant Declaration
DECLARE
    -- Scalar Variable
    v_employee_name VARCHAR2(100) := 'TheCodeForge Developer';
    
    -- Constant: Must be initialized and cannot be changed
    gc_tax_rate CONSTANT NUMBER(3,2) := 0.05;
    
    -- Anchored Type: Dynamically matches the column type in the DB
    v_project_id forge_projects.project_id%TYPE;
    
    -- Rowtype: Holds an entire row from a table
    v_project_rec forge_projects%ROWTYPE;
BEGIN
    v_project_id := 101;
    
    -- Selective Assignment
    SELECT * INTO v_project_rec 
    FROM forge_projects 
    WHERE project_id = v_project_id;

    DBMS_OUTPUT.PUT_LINE('Processing: ' || v_project_rec.project_name);
END;
▶ Output
Processing: Forge Core API
💡Key Insight:
The most important thing to understand about PL/SQL Variables, Constants and Data Types is the problem it was designed to solve. Always ask 'why does this exist?' before asking 'how do I use it?' Use anchored types (%TYPE) as much as possible to ensure your code remains 'linked' to your database schema changes.
📊 Production Insight
Hard-coded variable lengths are the #1 cause of production VALUE_ERROR bugs after schema migrations.
When a column expands from VARCHAR2(30) to VARCHAR2(60), every hard-coded VARCHAR2(30) variable in your codebase silently becomes a ticking bomb.
Rule: always use %TYPE for variables that read from database columns.
🎯 Key Takeaway
Variables store temporary data; constants protect fixed values.
Data types enforce compile-time integrity – let the compiler catch your mistakes.
Anchored types (%TYPE, %ROWTYPE) keep your code in sync with the schema automatically.

Common Mistakes and How to Avoid Them

When learning PL/SQL Variables, Constants and Data Types, most developers hit the same set of gotchas. A frequent mistake is hard-coding variable lengths (e.g., VARCHAR2(20)) instead of using %TYPE. If the database column later expands to 50 characters, your code will throw a 'Value Error'. Another common error is failing to initialize variables, leading to unexpected NULL logic in calculations.

Knowing these in advance saves hours of debugging production 'Buffer Overflow' and 'Constraint Violation' errors.

But there's a deeper one: using package-level global variables when local variables would suffice. These globals persist across calls within the same session, and if your code relies on their previous values, you're in for a debugging nightmare. A change in one procedure can affect another unintentionally.

CommonMistakes.sql · SQL
123456789101112131415
-- io.thecodeforge: Avoiding hard-coded data types
-- WRONG: Risk of ORA-06502 if the DB column expands
-- v_name VARCHAR2(10);

-- CORRECT: Using %TYPE to stay synchronized
DECLARE
    v_forge_user_name forge_users.username%TYPE;
    v_current_total   NUMBER(10,2) := 0.00; -- Initialize to avoid NULL arithmetic
BEGIN
    SELECT username INTO v_forge_user_name 
    FROM forge_users 
    WHERE user_id = 1;
    
    v_current_total := v_current_total + 150.50;
END;
▶ Output
// Variable v_forge_user_name automatically adopts the DB column width.
⚠ Watch Out:
The most common mistake with PL/SQL Variables, Constants and Data Types is using it when a simpler alternative would work better. Avoid creating 'Global' variables in package specifications unless they truly need to persist across the session, as this can lead to memory bloat and difficult-to-trace state changes.
📊 Production Insight
Package-level variables that persist across calls are a frequent source of 'action at a distance' bugs.
A stored procedure called twice in the same session may behave differently if the global variable was mutated by another procedure.
Rule: prefer local variables inside procedures; use package globals only for true session-level state like a user context.
🎯 Key Takeaway
Hard-code variable sizes = schedule a production outage.
Uninitialized variables default to NULL – NULL + number = NULL.
Package globals are shared state; they're useful but dangerous – use sparingly.

Variables vs Constants – When to Use Each

Choosing between a variable and a constant is straightforward: use a constant when the value must never change. That sounds obvious, but developers often use variables for values that are logically fixed – like a maximum retry count, a cutoff date, or a conversion factor.

Constants improve readability and prevent accidental modification. They also help the compiler optimise memory usage. In PL/SQL, a constant must be declared with the CONSTANT keyword and initialized immediately. After that, any attempt to assign a new value raises a compilation error. That's a good thing – it's a contract your code makes with itself.

But there's a nuance: a constant can hold a value fetched from the database at declaration time, but that value becomes fixed for the duration of the block. If the underlying data changes, the constant still holds the old value. Use constants for truly static values, not for session-level configuration you might want to refresh.

VariablesVsConstants.sql · SQL
12345678910111213141516
-- io.thecodeforge: Proper use of constants vs variables
DECLARE
    -- Constant: tax rate never changes mid-calculation
    gc_tax_rate CONSTANT NUMBER(3,2) := 0.07;
    
    -- Variable: running total changes
    v_gross_amount NUMBER(10,2) := 0.00;
    v_net_amount   NUMBER(10,2) := 0.00;
BEGIN
    v_gross_amount := 1150.00;
    v_net_amount   := v_gross_amount * (1 - gc_tax_rate);
    
    DBMS_OUTPUT.PUT_LINE('Net: ' || v_net_amount);
    
    -- This would fail to compile: gc_tax_rate := 0.06;
END;
▶ Output
Net: 1069.5
🔥Why Constants Matter:
Constants turn a 'don't change this' comment into a compiler-enforced rule. They also make code self-documenting – a reader immediately knows this value is a fixed reference.
📊 Production Insight
Using a variable for a logically constant value opens the door for accidental overwrites by future developers.
In one incident, a 'variable' that was supposed to hold the fiscal year start date was changed inadvertently by a batch process, causing all reports for the next month to use the wrong date.
Rule: if the value must never change, declare it CONSTANT.
🎯 Key Takeaway
If it should not change, make it CONSTANT – the compiler will enforce it.
Constants are documentation that cannot lie.
Initialise constants at declaration; they cannot be assigned later.

Anchored Types: %TYPE and %ROWTYPE for Schema Resilience

Anchored types are PL/SQL's solution to the schema coupling problem. When you declare a variable with %TYPE, you tell the compiler: 'Find the data type of this column and use that.' If the column later changes, your code automatically adapts – no manual edits needed.

%ROWTYPE goes further: it declares a variable that holds an entire row. You can SELECT INTO a %ROWTYPE variable and access each column by name. This eliminates the need to list all columns individually. When you add a column to the table, your %ROWTYPE variables include it automatically (though you may need to adjust SELECT * to include the new column).

The performance cost is negligible – the compiler resolves the type at compile time, not runtime. The real cost saved is maintenance hours. A 200-line procedure that uses %ROWTYPE instead of 20 individual variable declarations is vastly easier to maintain and less error-prone.

But there's a catch: %ROWTYPE cannot be used for columns from joins – it only maps to a single table or cursor. For joins, you need to define a custom record type or use individual variables.

AnchoredTypes.sql · SQL
123456789101112131415161718
-- io.thecodeforge: Using %TYPE and %ROWTYPE for resilience
DECLARE
    -- %TYPE: single column
    v_order_total forge_orders.total_amount%TYPE;
    
    -- %ROWTYPE: entire row
    v_customer_rec forge_customers%ROWTYPE;
BEGIN
    SELECT total_amount INTO v_order_total 
    FROM forge_orders 
    WHERE order_id = 1001;
    
    SELECT * INTO v_customer_rec
    FROM forge_customers
    WHERE customer_id = 202;
    
    DBMS_OUTPUT.PUT_LINE('Customer: ' || v_customer_rec.name || ' - Order Total: ' || v_order_total);
END;
▶ Output
Customer: Acme Corp - Order Total: 4500.75
Mental Model
Think of %TYPE as a Smart Pointer
Just as a smart pointer in C++ auto-adapts to the object type, %TYPE adapts to the column type.
  • %TYPE is a compile-time placeholder that resolves to the column's actual data type.
  • If the column changes from VARCHAR2(30) to VARCHAR2(60), your variable changes too – no code change.
  • %ROWTYPE bundles all columns into a single record – like a struct that auto-updates.
  • Use %ROWTYPE for SELECT * INTO statements; never use individual variables for every column.
📊 Production Insight
A schema migration that changes a column length will silently break every hard-coded variable that reads from it.
Without %TYPE, you're forced to grep through all PL/SQL code and manually update lengths – a slow and error-prone process.
Rule: if a variable holds data from a column, use %TYPE. Period.
🎯 Key Takeaway
%TYPE ties your variable to the column – schema changes propagate automatically.
%ROWTYPE captures an entire row – less code, fewer merge conflicts.
Anchored types do not hurt performance – they save maintenance hours.

Data Type Categories and Their Memory Implications

PL/SQL data types fall into four categories: Scalar, Composite, Reference, and LOB (Large Object). Each has distinct memory and performance characteristics.

Scalar types (NUMBER, VARCHAR2, DATE, BOOLEAN) are the simplest – they hold a single value. A VARCHAR2 variable can hold up to 32,767 bytes in PL/SQL, but only 4,000 bytes in SQL. That's a common tripwire: you can build a large string in PL/SQL, but passing it to a SQL context truncates it silently. Use CLOB for larger text.

Composite types (records, collections) consume memory proportional to their elements. A collection of 100,000 NUMBER items can use hundreds of kilobytes. If you declare such a collection at the package level, it persists for the session and can lead to PGA memory exhaustion under high concurrency.

LOB types (CLOB, BLOB) are stored outside the PGA, with a locator in the variable. They're efficient for large data but have slower access than scalars. Reference types (REF CURSOR, REF) hold pointers to data – useful for passing result sets between programs.

Knowing these memory implications helps you avoid performance surprises. A naive variable choice can turn a fast procedure into a memory hog.

DataTypesMemory.sql · SQL
123456789101112131415161718192021222324
-- io.thecodeforge: Understanding data type memory
DECLARE
    -- Scalar: small, fast
    v_small VARCHAR2(100) := 'Hi';
    
    -- Composite: collection can be large
    TYPE num_table IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
    v_big num_table;
    
    -- LOB: large data, uses locator
    v_clob CLOB := 'This is large text...';
    
    -- Reference: pointer to cursor
    v_cursor SYS_REFCURSOR;
BEGIN
    -- Fill collection with 10000 numbers
    FOR i IN 1..10000 LOOP
        v_big(i) := i;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('Count: ' || v_big.COUNT);
    
    -- Open ref cursor
    OPEN v_cursor FOR 'SELECT * FROM dual';
END;
▶ Output
Count: 10000
⚠ Memory Trap:
Package-level collections persist for the entire user session. If you load 100,000 rows into a PL/SQL table and the procedure is called 100 times concurrently, you can exhaust the shared pool or PGA. Always assess concurrency when choosing data structures.
📊 Production Insight
A VARCHAR2(32000) declared in a package body will consume heap space once, but if you use an associative array of 1000 strings each 1KB, that's ~1MB per session.
With 200 concurrent sessions, that's 200MB of PGA – enough to cause ORA-04030 (out of memory).
Rule: batch load collections with LIMIT clause; use LOBs for truly large text.
🎯 Key Takeaway
Scalar types are small; composite types can be huge – know your memory budget.
PL/SQL VARCHAR2 max is 32767, but SQL VARCHAR2 max is 4000 – silent truncation awaits.
LOB type variables use locators, not the full data – efficient for large content.

Scope, Lifetime, and Variable Visibility

A variable's scope determines where it can be accessed; its lifetime determines how long it exists. In PL/SQL, these depend on where you declare the variable.

Local variables inside a BEGIN-END block exist only during that block's execution. They are created when the block starts and destroyed when it ends. This is the safest scope – no unintended side effects.

Package-level variables declared in a package specification are visible to any caller. They live for the duration of the user session. If you modify a package variable in one procedure, any subsequent call to another procedure in the same session sees the modified value. This is both a feature (for session context like user ID) and a danger (for accidental state corruption).

Package body variables (declared in the body but not in the spec) are private – only procedures within the package can see them. That's a good middle ground: session-persistent but encapsulated.

The golden rule: declare variables at the smallest possible scope. Start with local. If you need to share state, use package body variables. Use package spec variables only when external callers need to read or set them.

ScopeLifetime.sql · SQL
12345678910111213141516171819202122
-- io.thecodeforge: Scope and lifetime examples
CREATE OR REPLACE PACKAGE forge_session_ctx IS
    -- Package spec variable: visible to all callers, session lifetime
    g_user_id NUMBER;
    g_user_role VARCHAR2(30);
END forge_session_ctx;
/

CREATE OR REPLACE PACKAGE BODY forge_session_ctx IS
    -- Private package body variable: only visible inside this package
    g_last_access TIMESTAMP;
    
    PROCEDURE set_context(p_user_id NUMBER, p_role VARCHAR2) IS
        -- Local variable: only visible within this procedure
        v_local_counter NUMBER := 0;
    BEGIN
        g_user_id := p_user_id;
        g_user_role := p_role;
        g_last_access := SYSTIMESTAMP;
        v_local_counter := v_local_counter + 1;
    END;
END forge_session_ctx;
▶ Output
// Package compiled successfully
🔥Visibility Rule:
A variable declared in a package spec is effectively a global variable. Use it sparingly and document the intended lifecycle. Prefer passing parameters over relying on global state.
📊 Production Insight
A package spec variable reset by one procedure but read by another creates hidden dependencies that are invisible in the calling code.
This caused a production incident where the 'g_user_role' variable was set by a login procedure but never reset on logout, leaking privileges across connections.
Rule: always clear package-level session variables at the start of each request if they represent user context.
🎯 Key Takeaway
Smallest scope wins – local over package body over package spec.
Package spec variables are global – treat them with care.
Session-persistent variables can cause privilege leaks if not reset properly.
FeatureVariableConstantAnchored Type (%TYPE)
Value ModificationCan be updated anytimeImmutable once declaredDepends on usage
InitializationOptional (Defaults to NULL)MandatoryOptional
MaintenanceManual updates requiredSingle point of changeAutomatic via Schema
ScopeLocal or GlobalLocal or GlobalLinked to DB Object
Best Use CaseCounters, flags, temp dataConfiguration, Pi, Tax ratesDatabase data retrieval

🎯 Key Takeaways

  • Variables store temporary data; constants enforce immutability – use the right tool for the job.
  • Always use %TYPE for variables that hold column values – it prevents schema-migration-induced failures.
  • Uninitialized variables are NULL – explicitly initialize everything to avoid silent NULL propagation.
  • Package-level variables persist across calls – use them intentionally and clear session context between requests.
  • PL/SQL VARCHAR2 max (32767) != SQL VARCHAR2 max (4000) – mind the difference when mixing contexts.

⚠ Common Mistakes to Avoid

    Hard-coding variable lengths instead of using %TYPE
    Symptom

    ORA-06502 occurs when a column expands beyond the hard-coded value, often during batch processing that passes long strings.

    Fix

    Replace hard-coded VARCHAR2(N) with column%TYPE. This automatically adapts to schema changes.

    Not initializing variables (assuming they default to 0 or empty string)
    Symptom

    Calculations unexpectedly return NULL. For example, v_total := v_total + 100 returns NULL if v_total was never initialized.

    Fix

    Always initialize scalar variables: NUMBER := 0, VARCHAR2 := '', or use a sensible default. Document the default in comments.

    Using package-level variables when local variables suffice
    Symptom

    Unexpected state changes across procedure calls within the same session. A variable set in one procedure affects another procedure that reads it.

    Fix

    Declare variables at the smallest possible scope. Use package body variables for shared session state, and pass values as parameters rather than relying on globals.

    Confusing PL/SQL VARCHAR2 max (32767) with SQL VARCHAR2 max (4000)
    Symptom

    Silent truncation when passing a large PL/SQL string to a SQL statement or storing it in a table column.

    Fix

    Use CLOB for text larger than 4000 bytes that must interact with SQL. When possible, keep SQL constraints in mind by checking variable sizes.

Interview Questions on This Topic

  • QWhat is the difference between %TYPE and %ROWTYPE?JuniorReveal
    %TYPE anchors a single variable to the data type of a specific column in a table or cursor. %ROWTYPE declares a record variable that represents an entire row from a table, cursor, or view. %TYPE is for individual columns; %ROWTYPE is for complete rows. Use %ROWTYPE when you need to fetch all columns from a table, as it reduces maintenance when the table structure changes.
  • QWhy should you use a CONSTANT instead of a regular variable for fixed values?JuniorReveal
    Constants prevent accidental modification and make the code self-documenting. The compiler enforces immutability – any attempt to assign a new value to a constant raises a compilation error. This catches bugs at compile time rather than in production. Constants also signal intent to other developers: 'this value is a fixed reference, don't change it.'
  • QHow does PL/SQL handle uninitialized variables by default?JuniorReveal
    A variable declared without a DEFAULT clause is initialized to NULL. This includes all scalar types (NUMBER, VARCHAR2, DATE, etc.). NULL arithmetic always yields NULL – so an expression like v_total + v_increment where v_total is NULL returns NULL. The best practice is to explicitly initialize variables with a default value that makes sense for your logic.
  • QWhat are the benefits and trade-offs of using anchored data types (%TYPE, %ROWTYPE)?Mid-levelReveal
    Benefits: automatic schema synchronization – code adapts when columns change; reduced maintenance – no need to update variable declarations manually; improved readability – the variable's origin is clear. Trade-offs: minor compile-time overhead; cannot be used for columns from joins (use custom record types); %ROWTYPE includes all columns, which may be more than needed for some operations (but the memory cost is minimal). Overall, the benefits far outweigh the costs for production code.
  • QWhat is the maximum size of a VARCHAR2 variable in PL/SQL and how does it differ from SQL?SeniorReveal
    In PL/SQL, VARCHAR2 can hold up to 32,767 bytes. In SQL (table columns or SQL statements), VARCHAR2 is limited to 4,000 bytes. If you declare a VARCHAR2(32767) in PL/SQL and try to use it in a SQL query, you may get an error or silent truncation. For text larger than 4,000 bytes that needs to interact with SQL, use CLOB. This is a frequent gotcha for developers moving between PL/SQL and SQL contexts.

Frequently Asked Questions

Is it mandatory to initialize a constant in PL/SQL?

Yes. A constant must be initialized at declaration. You cannot assign a value later. Example: gc_rate CONSTANT NUMBER := 0.05; is required.

Can I change a variable declared with %TYPE after declaration?

Yes, %TYPE affects only the data type, not the mutability. You can assign new values to the variable as long as they are compatible with the anchored type.

What happens if I try to assign a value larger than the variable's size?

You get ORA-06502 (PL/SQL numeric or value error). The runtime raises this exception. It can be caught with an exception handler, but it's better to avoid it by using %TYPE or ensuring sizes are adequate.

How do I declare a variable that holds a row from a join?

You cannot use %ROWTYPE for joins directly. Instead, create a custom record type: TYPE join_rec IS RECORD (col1 table1.col1%TYPE, col2 table2.col2%TYPE); v_rec join_rec; Then SELECT into v_rec.

🔥
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousIntroduction to PL/SQLNext →PL/SQL Control Structures — IF, LOOP, WHILE
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged