ORA-02064: Distributed Operation Not Supported - Workarounds
ORA-02064: Distributed Operation Not Supported
Section titled “ORA-02064: Distributed Operation Not Supported”Error Overview
Section titled “Error Overview”Error Text: ORA-02064: distributed operation not supported
The ORA-02064 error is raised when an application attempts an operation over a database link that Oracle’s distributed execution engine cannot perform. Unlike ORA-02055, which signals a failure mid-transaction, ORA-02064 is raised immediately — Oracle detects the unsupported pattern before attempting execution and rejects it outright.
The error most commonly appears when developers attempt DDL statements over a database link, use Oracle sequences remotely in unsupported contexts, manipulate LOB columns through a link, or try to call certain PL/SQL constructs remotely. Understanding which operations are prohibited and applying the correct workaround pattern is the key to resolving this error without a full architectural change.
Common Causes
Section titled “Common Causes”1. DDL Statements Over a Database Link
Section titled “1. DDL Statements Over a Database Link”CREATE TABLE,DROP TABLE,ALTER TABLEcannot be executed remotely via a database linkCREATE INDEX,GRANT,REVOKEand other DDL are likewise blocked- Oracle’s distributed SQL engine only supports DML (INSERT, UPDATE, DELETE, SELECT) over links
2. Remote Sequence Access in Unsupported Contexts
Section titled “2. Remote Sequence Access in Unsupported Contexts”SELECT seq.NEXTVAL FROM dual@remote_linkis not supported in all versions and contexts- Using a remote sequence inside a trigger or PL/SQL block that also contains local DML
- Referencing a remote sequence in a subquery used for INSERT
3. LOB Column Operations Over Database Links
Section titled “3. LOB Column Operations Over Database Links”SELECTof a CLOB or BLOB column directly over a database link is restricted in older versions- UPDATE of a LOB column remotely is not supported without special handling
- BFILE operations are always local and cannot traverse a database link
4. Unsupported PL/SQL Remote Calls
Section titled “4. Unsupported PL/SQL Remote Calls”EXECUTE IMMEDIATEtargeting a remote database directly- Calling remote stored procedures that themselves perform DDL
- Using
DBMS_SQLacross a database link
5. Heterogeneous Service Restrictions
Section titled “5. Heterogeneous Service Restrictions”- Attempting Oracle-specific syntax against a non-Oracle database via a gateway
- Using Oracle-only functions (DECODE, CONNECT BY, etc.) in a pass-through context that the gateway cannot translate
- Attempting DML with RETURNING clause over a heterogeneous link
6. Unsupported Transaction Operations
Section titled “6. Unsupported Transaction Operations”- Using
SAVEPOINTfollowed by a distributed DML within the same transaction in certain configurations - Attempting
LOCK TABLEover a database link - Running
SELECT FOR UPDATEacross a link when the remote side cannot support it
Diagnostic Queries
Section titled “Diagnostic Queries”Identify the Failing Statement and Link
Section titled “Identify the Failing Statement and Link”-- Find the SQL that caused ORA-02064 in the current sessionSELECT sql_id, sql_text, executions, last_active_time, parsing_schema_nameFROM v$sqlWHERE sql_text LIKE '%@%' -- Contains DB link reference AND last_active_time > SYSDATE - 1/24ORDER BY last_active_time DESCFETCH FIRST 20 ROWS ONLY;Examine Database Link Definitions
Section titled “Examine Database Link Definitions”-- Review all database links to understand remote targetsSELECT owner, db_link, username, host, createdFROM dba_db_linksORDER BY owner, db_link;
-- Check for heterogeneous (non-Oracle) linksSELECT db_link, username, hostFROM dba_db_linksWHERE UPPER(host) LIKE '%HS%' OR UPPER(host) LIKE '%GATEWAY%' OR UPPER(host) LIKE '%ODBC%' OR UPPER(host) LIKE '%JDBC%';Check Remote Database Capabilities
Section titled “Check Remote Database Capabilities”-- Query the data dictionary of the remote database to confirm it is OracleSELECT banner FROM v$version@remote_db_link;
-- Check which Oracle version the remote database is runningSELECT version, version_fullFROM v$instance@remote_db_link;Detect LOB Columns in Remote Tables
Section titled “Detect LOB Columns in Remote Tables”-- Find LOB columns in the remote table causing the errorSELECT column_name, data_type, data_lengthFROM all_tab_columns@remote_db_linkWHERE table_name = UPPER('target_table') AND data_type IN ('CLOB', 'BLOB', 'NCLOB', 'BFILE', 'XMLTYPE')ORDER BY column_id;Review Error History
Section titled “Review Error History”-- Check alert log for ORA-02064 occurrencesSELECT originating_timestamp, message_textFROM v$diag_alert_extWHERE message_text LIKE '%ORA-02064%'ORDER BY originating_timestamp DESCFETCH FIRST 30 ROWS ONLY;Check Supported Remote Operations (Heterogeneous Services)
Section titled “Check Supported Remote Operations (Heterogeneous Services)”-- For heterogeneous links, view capabilities of the remote databaseSELECT capability_name, capability_description, is_supported, is_updateableFROM v$hs_capability@remote_non_oracle_linkORDER BY capability_name;Step-by-Step Resolution
Section titled “Step-by-Step Resolution”1. Identify the Exact Unsupported Operation
Section titled “1. Identify the Exact Unsupported Operation”Carefully examine the SQL or PL/SQL that raised ORA-02064 and determine which category of restriction applies. Common categories and their solutions:
| Operation Attempted Remotely | Supported via DB Link? | Workaround |
|---|---|---|
| SELECT (non-LOB) | Yes | None needed |
| INSERT / UPDATE / DELETE | Yes | None needed |
| DDL (CREATE, ALTER, DROP) | No | Use remote procedure |
| LOB SELECT (12c+) | Partially | Use remote function |
| SEQUENCE.NEXTVAL | Limited | Use remote procedure |
| EXECUTE IMMEDIATE | No | Use remote procedure |
| LOCK TABLE | No | Restructure transaction |
2. Workaround for DDL Over a Database Link
Section titled “2. Workaround for DDL Over a Database Link”DDL cannot be sent directly over a link. Create a stored procedure on the remote database that performs the DDL, then call it through the link:
-- On the REMOTE database: create a wrapper procedureCREATE OR REPLACE PROCEDURE remote_create_table( p_table_name IN VARCHAR2, p_ddl_suffix IN VARCHAR2) ASBEGIN EXECUTE IMMEDIATE 'CREATE TABLE ' || DBMS_ASSERT.SIMPLE_SQL_NAME(p_table_name) || ' (' || p_ddl_suffix || ')';END;/
-- On the LOCAL database: call the remote procedure through the linkBEGIN remote_create_table@remote_db_link('STAGING_TABLE', 'id NUMBER, col1 VARCHAR2(100)');END;/3. Workaround for Sequences Over a Database Link
Section titled “3. Workaround for Sequences Over a Database Link”Use a remote function that wraps the sequence call:
-- On the REMOTE database: create a function to vend sequence valuesCREATE OR REPLACE FUNCTION get_next_seq_val RETURN NUMBER ASBEGIN RETURN remote_sequence.NEXTVAL;END;/
-- On the LOCAL database: call the function through the linkDECLARE v_next_id NUMBER;BEGIN v_next_id := get_next_seq_val@remote_db_link(); INSERT INTO local_table (id, col1) VALUES (v_next_id, 'value'); COMMIT;END;/4. Workaround for LOB Columns Over a Database Link
Section titled “4. Workaround for LOB Columns Over a Database Link”For LOB data, retrieve it using a remote function that converts the LOB to VARCHAR2 chunks or uses a staging approach:
-- For small CLOBs: cast to VARCHAR2 in a remote view or functionCREATE OR REPLACE FUNCTION get_clob_as_varchar(p_id IN NUMBER) RETURN VARCHAR2AS v_clob_text CLOB; v_result VARCHAR2(32767);BEGIN SELECT clob_column INTO v_clob_text FROM remote_table WHERE id = p_id;
v_result := SUBSTR(TO_CHAR(v_clob_text), 1, 32767); RETURN v_result;END;/
-- Call remotelySELECT get_clob_as_varchar@remote_db_link(42) FROM dual;For large LOBs, use a staging table approach:
-- Stage data locally first, then processINSERT INTO local_staging (id, varchar_chunk)SELECT id, SUBSTR(clob_col, 1, 4000)FROM remote_table@remote_db_linkWHERE id = :target_id;
COMMIT;5. Workaround Using Remote Stored Procedures for Complex Operations
Section titled “5. Workaround Using Remote Stored Procedures for Complex Operations”Encapsulate all unsupported operations in a remote stored procedure:
-- On the REMOTE databaseCREATE OR REPLACE PROCEDURE process_remote_batch( p_batch_id IN NUMBER, p_status OUT VARCHAR2) ASBEGIN -- All DDL, sequence usage, LOB operations happen locally on remote DB INSERT INTO batch_log (batch_id, processed_at) VALUES (p_batch_id, SYSDATE); COMMIT; p_status := 'SUCCESS';EXCEPTION WHEN OTHERS THEN ROLLBACK; p_status := 'ERROR: ' || SQLERRM;END;/
-- On the LOCAL database: invoke it through the linkDECLARE v_status VARCHAR2(200);BEGIN process_remote_batch@remote_db_link(1001, v_status); DBMS_OUTPUT.PUT_LINE('Remote result: ' || v_status);END;/6. Workaround for Heterogeneous (Non-Oracle) Database Links
Section titled “6. Workaround for Heterogeneous (Non-Oracle) Database Links”For non-Oracle databases, use passthrough SQL via the DBMS_HS_PASSTHROUGH package:
-- Execute passthrough SQL against a non-Oracle remote databaseDECLARE v_cursor INTEGER; v_rows INTEGER;BEGIN v_cursor := DBMS_HS_PASSTHROUGH.OPEN_CURSOR@remote_non_oracle_link;
DBMS_HS_PASSTHROUGH.PARSE@remote_non_oracle_link( v_cursor, 'CREATE TABLE staging_table (id INT, col1 VARCHAR(100))' );
v_rows := DBMS_HS_PASSTHROUGH.EXECUTE_NON_QUERY@remote_non_oracle_link(v_cursor);
DBMS_HS_PASSTHROUGH.CLOSE_CURSOR@remote_non_oracle_link(v_cursor);END;/Prevention Strategies
Section titled “Prevention Strategies”1. Audit Remote Operations Before Deployment
Section titled “1. Audit Remote Operations Before Deployment”Before deploying code that uses database links, review every statement for unsupported patterns:
-- Find all SQL in the library cache that uses DB linksSELECT sql_id, SUBSTR(sql_text, 1, 200) as sql_snippet, executions, last_active_timeFROM v$sqlWHERE sql_text LIKE '%@%' AND ( UPPER(sql_text) LIKE 'CREATE%' OR UPPER(sql_text) LIKE 'ALTER%' OR UPPER(sql_text) LIKE 'DROP%' OR UPPER(sql_text) LIKE 'EXECUTE%' )ORDER BY last_active_time DESC;2. Encapsulate All Remote Operations in PL/SQL Packages
Section titled “2. Encapsulate All Remote Operations in PL/SQL Packages”Create a dedicated package on the remote database for every operation the local database needs to invoke. This eliminates ad-hoc DB-link SQL and makes the interface explicit and maintainable:
-- Remote database: remote_ops packageCREATE OR REPLACE PACKAGE remote_ops AS PROCEDURE insert_record(p_id IN NUMBER, p_val IN VARCHAR2); PROCEDURE delete_record(p_id IN NUMBER); FUNCTION get_status(p_id IN NUMBER) RETURN VARCHAR2;END;/3. Test Against Remote Database Type and Version
Section titled “3. Test Against Remote Database Type and Version”Always test operations against the actual remote database type (Oracle vs non-Oracle) and version during development. Capabilities differ across versions and gateway configurations:
-- Confirm the remote target is Oracle before assuming full SQL supportSELECT banner FROM v$version@remote_db_link;4. Use Views on the Remote Database to Abstract LOB Complexity
Section titled “4. Use Views on the Remote Database to Abstract LOB Complexity”-- On the REMOTE database: create a view that converts LOBs to VARCHAR2CREATE OR REPLACE VIEW v_remote_data_no_lob ASSELECT id, name, SUBSTR(description_clob, 1, 4000) AS description_varchar, created_atFROM remote_data_table;
-- SELECT from the view over the link (no LOB restriction)SELECT * FROM v_remote_data_no_lob@remote_db_link WHERE id = :id;Diagnostic Scripts
Section titled “Diagnostic Scripts”These Oracle Day by Day utility scripts are relevant to diagnosing distributed operation issues:
- gvsess.sql — Session-level diagnostics for active distributed operations
Related Errors
Section titled “Related Errors”- ORA-02055 - Distributed update failed; rollback required
- ORA-02063 - Preceding line from database link
- ORA-02067 - Transaction or savepoint rollback required
- ORA-02069 - GLOBAL_NAMES parameter must be TRUE
- ORA-02070 - Database does not support operation in this context
- ORA-02049 - Timeout: distributed transaction waiting for lock
Emergency Response
Section titled “Emergency Response”Quick Fixes
Section titled “Quick Fixes”-
Identify the unsupported operation and stop the failing call
-- Kill the session issuing the unsupported operationALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; -
Verify the database link target is reachable and is Oracle
SELECT banner FROM v$version@remote_db_link; -
Wrap the unsupported operation in a remote stored procedure immediately
-- Quick temporary wrapper on the remote databaseCREATE OR REPLACE PROCEDURE temp_remote_ddl ASBEGINEXECUTE IMMEDIATE 'ALTER TABLE target_table ADD (new_col VARCHAR2(100))';END;/-- Call from local:EXECUTE temp_remote_ddl@remote_db_link;
Post-Resolution Cleanup
Section titled “Post-Resolution Cleanup”-- Verify no lingering in-doubt transactions from the failed attemptSELECT COUNT(*) FROM dba_2pc_pending;
-- Confirm the link is fully operational after workaround is in placeSELECT SYSDATE FROM dual@remote_db_link;
-- Document the remote capability boundary for the teamSELECT db_link, username, hostFROM dba_db_linksWHERE db_link = 'REMOTE_DB_LINK';