ORA-02267 - Column Type Incompatible with Referenced Column
ORA-02267: Column Type Incompatible with Referenced Column
Section titled “ORA-02267: Column Type Incompatible with Referenced Column”The ORA-02267 error occurs when creating a foreign key constraint where the data types of the referencing column and the referenced column are incompatible. Oracle requires exact data type matching for foreign key relationships.
Error Details
Section titled “Error Details”- Error Code: ORA-02267
- Error Message: “column type incompatible with referenced column”
- Error Type: Constraint Creation Error
- Severity: Compilation Error
Common Causes
Section titled “Common Causes”1. Data Type Mismatch
Section titled “1. Data Type Mismatch”The foreign key column has a different data type than the referenced primary key column.
2. Length Mismatch
Section titled “2. Length Mismatch”VARCHAR2 columns with different lengths.
3. Precision/Scale Mismatch
Section titled “3. Precision/Scale Mismatch”NUMBER columns with different precision or scale.
4. Character Set Differences
Section titled “4. Character Set Differences”CHAR vs VARCHAR2 or different character sets.
5. NULL Constraints
Section titled “5. NULL Constraints”Different nullability constraints between columns.
Examples and Solutions
Section titled “Examples and Solutions”Example 1: Data Type Mismatch
Section titled “Example 1: Data Type Mismatch”Problem:
-- Parent table with NUMBER primary keyCREATE TABLE departments ( dept_id NUMBER(4) PRIMARY KEY, dept_name VARCHAR2(50));
-- Child table with VARCHAR2 foreign keyCREATE TABLE employees ( emp_id NUMBER(6), emp_name VARCHAR2(100), dept_id VARCHAR2(10) -- Wrong data type);
-- This will failALTER TABLE employeesADD CONSTRAINT fk_emp_deptFOREIGN KEY (dept_id) REFERENCES departments(dept_id);-- ORA-02267: column type incompatible with referenced column
Solution:
-- Fix: Change foreign key column to match parentALTER TABLE employees MODIFY dept_id NUMBER(4);
-- Now add the constraintALTER TABLE employeesADD CONSTRAINT fk_emp_deptFOREIGN KEY (dept_id) REFERENCES departments(dept_id);
Example 2: VARCHAR2 Length Mismatch
Section titled “Example 2: VARCHAR2 Length Mismatch”Problem:
-- Parent tableCREATE TABLE countries ( country_code VARCHAR2(3) PRIMARY KEY, country_name VARCHAR2(100));
-- Child table with different lengthCREATE TABLE regions ( region_id NUMBER, region_name VARCHAR2(50), country_code VARCHAR2(10) -- Different length);
-- This will failALTER TABLE regionsADD CONSTRAINT fk_region_countryFOREIGN KEY (country_code) REFERENCES countries(country_code);-- ORA-02267: column type incompatible with referenced column
Solution:
-- Fix: Match the exact lengthALTER TABLE regions MODIFY country_code VARCHAR2(3);
-- Add the constraintALTER TABLE regionsADD CONSTRAINT fk_region_countryFOREIGN KEY (country_code) REFERENCES countries(country_code);
Example 3: NUMBER Precision/Scale Mismatch
Section titled “Example 3: NUMBER Precision/Scale Mismatch”Problem:
-- Parent tableCREATE TABLE products ( product_id NUMBER(8,0) PRIMARY KEY, product_name VARCHAR2(100));
-- Child table with different precisionCREATE TABLE order_items ( order_id NUMBER, line_number NUMBER, product_id NUMBER(6,0), -- Different precision quantity NUMBER);
-- This will failALTER TABLE order_itemsADD CONSTRAINT fk_item_productFOREIGN KEY (product_id) REFERENCES products(product_id);-- ORA-02267: column type incompatible with referenced column
Solution:
-- Fix: Match the exact precision and scaleALTER TABLE order_items MODIFY product_id NUMBER(8,0);
-- Add the constraintALTER TABLE order_itemsADD CONSTRAINT fk_item_productFOREIGN KEY (product_id) REFERENCES products(product_id);
Example 4: CHAR vs VARCHAR2
Section titled “Example 4: CHAR vs VARCHAR2”Problem:
-- Parent table with CHARCREATE TABLE status_codes ( status_code CHAR(2) PRIMARY KEY, description VARCHAR2(50));
-- Child table with VARCHAR2CREATE TABLE orders ( order_id NUMBER PRIMARY KEY, order_date DATE, status_code VARCHAR2(2) -- Different character type);
-- This will failALTER TABLE ordersADD CONSTRAINT fk_order_statusFOREIGN KEY (status_code) REFERENCES status_codes(status_code);-- ORA-02267: column type incompatible with referenced column
Solution:
-- Fix: Use the same character typeALTER TABLE orders MODIFY status_code CHAR(2);
-- Add the constraintALTER TABLE ordersADD CONSTRAINT fk_order_statusFOREIGN KEY (status_code) REFERENCES status_codes(status_code);
Example 5: Composite Foreign Key Mismatch
Section titled “Example 5: Composite Foreign Key Mismatch”Problem:
-- Parent table with composite keyCREATE TABLE order_headers ( company_id NUMBER(4), order_id NUMBER(8), order_date DATE, PRIMARY KEY (company_id, order_id));
-- Child table with mismatched typesCREATE TABLE order_lines ( line_id NUMBER, company_id VARCHAR2(10), -- Wrong type order_id NUMBER(6), -- Wrong precision product_id NUMBER);
-- This will failALTER TABLE order_linesADD CONSTRAINT fk_line_headerFOREIGN KEY (company_id, order_id)REFERENCES order_headers(company_id, order_id);-- ORA-02267: column type incompatible with referenced column
Solution:
-- Fix: Match all column types exactlyALTER TABLE order_lines MODIFY company_id NUMBER(4);ALTER TABLE order_lines MODIFY order_id NUMBER(8);
-- Add the constraintALTER TABLE order_linesADD CONSTRAINT fk_line_headerFOREIGN KEY (company_id, order_id)REFERENCES order_headers(company_id, order_id);
Diagnostic Queries
Section titled “Diagnostic Queries”Check Column Data Types
Section titled “Check Column Data Types”-- Compare data types between parent and child tablesSELECT 'PARENT' AS table_type, table_name, column_name, data_type, data_length, data_precision, data_scale, nullableFROM user_tab_columnsWHERE table_name = 'PARENT_TABLE'AND column_name = 'PRIMARY_KEY_COLUMN'
UNION ALL
SELECT 'CHILD' AS table_type, table_name, column_name, data_type, data_length, data_precision, data_scale, nullableFROM user_tab_columnsWHERE table_name = 'CHILD_TABLE'AND column_name = 'FOREIGN_KEY_COLUMN'ORDER BY table_type, column_name;
Find Existing Foreign Keys
Section titled “Find Existing Foreign Keys”-- Check existing foreign key constraintsSELECT c.constraint_name, c.table_name AS child_table, cc.column_name AS child_column, c.r_constraint_name, rc.table_name AS parent_table, rcc.column_name AS parent_columnFROM user_constraints cJOIN user_cons_columns cc ON c.constraint_name = cc.constraint_nameJOIN user_constraints rc ON c.r_constraint_name = rc.constraint_nameJOIN user_cons_columns rcc ON rc.constraint_name = rcc.constraint_nameWHERE c.constraint_type = 'R'AND cc.position = rcc.positionORDER BY c.table_name, cc.position;
Verify Constraint Readiness
Section titled “Verify Constraint Readiness”-- Check if foreign key can be createdWITH parent_cols AS ( SELECT column_name, data_type, data_length, data_precision, data_scale FROM user_tab_columns WHERE table_name = 'PARENT_TABLE' AND column_name = 'PARENT_COLUMN'),child_cols AS ( SELECT column_name, data_type, data_length, data_precision, data_scale FROM user_tab_columns WHERE table_name = 'CHILD_TABLE' AND column_name = 'CHILD_COLUMN')SELECT CASE WHEN p.data_type = c.data_type AND NVL(p.data_length, 0) = NVL(c.data_length, 0) AND NVL(p.data_precision, 0) = NVL(c.data_precision, 0) AND NVL(p.data_scale, 0) = NVL(c.data_scale, 0) THEN 'COMPATIBLE' ELSE 'INCOMPATIBLE' END AS compatibility, 'Parent: ' || p.data_type || CASE WHEN p.data_precision IS NOT NULL THEN '(' || p.data_precision || CASE WHEN p.data_scale IS NOT NULL THEN ',' || p.data_scale END || ')' WHEN p.data_length IS NOT NULL THEN '(' || p.data_length || ')' END AS parent_definition, 'Child: ' || c.data_type || CASE WHEN c.data_precision IS NOT NULL THEN '(' || c.data_precision || CASE WHEN c.data_scale IS NOT NULL THEN ',' || c.data_scale END || ')' WHEN c.data_length IS NOT NULL THEN '(' || c.data_length || ')' END AS child_definitionFROM parent_cols p, child_cols c;
Resolution Strategies
Section titled “Resolution Strategies”1. Modify Child Table Column
Section titled “1. Modify Child Table Column”-- Most common solution: change foreign key columnALTER TABLE child_tableMODIFY foreign_key_column parent_column_datatype;
-- Examples:ALTER TABLE employees MODIFY dept_id NUMBER(4);ALTER TABLE regions MODIFY country_code VARCHAR2(3);
2. Modify Parent Table Column (If Possible)
Section titled “2. Modify Parent Table Column (If Possible)”-- Less common: change parent table if no data/constraints conflictALTER TABLE parent_tableMODIFY primary_key_column new_datatype;
-- Note: This may affect other foreign keys
3. Add Conversion Function
Section titled “3. Add Conversion Function”-- Create view with conversion if direct modification isn't possibleCREATE VIEW employees_v ASSELECT emp_id, emp_name, TO_NUMBER(dept_id) AS dept_id -- Convert VARCHAR2 to NUMBERFROM employees;
-- Use view for foreign key relationship
4. Recreate Tables
Section titled “4. Recreate Tables”-- For complex scenarios, recreate with correct structure-- 1. Export dataCREATE TABLE employees_temp AS SELECT * FROM employees;
-- 2. Drop and recreate with correct typesDROP TABLE employees;CREATE TABLE employees ( emp_id NUMBER(6) PRIMARY KEY, emp_name VARCHAR2(100), dept_id NUMBER(4) -- Correct type);
-- 3. Import data with conversionINSERT INTO employeesSELECT emp_id, emp_name, TO_NUMBER(dept_id)FROM employees_temp;
-- 4. Create foreign keyALTER TABLE employeesADD CONSTRAINT fk_emp_deptFOREIGN KEY (dept_id) REFERENCES departments(dept_id);
Prevention Best Practices
Section titled “Prevention Best Practices”1. Design Standards
Section titled “1. Design Standards”-- Establish data type standards-- Use consistent naming conventions-- Document foreign key relationships
-- Example standards:-- IDs: NUMBER(10)-- Codes: VARCHAR2(10)-- Flags: CHAR(1)
2. Create Tables with Constraints
Section titled “2. Create Tables with Constraints”-- Define foreign keys during table creationCREATE TABLE employees ( emp_id NUMBER(6) PRIMARY KEY, emp_name VARCHAR2(100), dept_id NUMBER(4), CONSTRAINT fk_emp_dept FOREIGN KEY (dept_id) REFERENCES departments(dept_id));
3. Use DESCRIBE Command
Section titled “3. Use DESCRIBE Command”-- Always check column definitions before creating constraintsDESCRIBE parent_table;DESCRIBE child_table;
4. Documentation
Section titled “4. Documentation”-- Document all foreign key relationships-- Include data type requirements-- Maintain data dictionary
Related Errors
Section titled “Related Errors”- ORA-02270: No Matching Unique or Primary Key
- ORA-02291: Integrity Constraint Violated
- ORA-00001: Unique Constraint Violated
- ORA-02264: Name Already Used by Existing Constraint
Summary
Section titled “Summary”ORA-02267 occurs when foreign key and referenced columns have incompatible data types. Resolution requires ensuring exact data type matching including length, precision, and scale. The most common solution is modifying the foreign key column to match the referenced column’s data type exactly.