Building Idempotent Database Scripts with Oracle 23ai IF [NOT] EXISTS

Idempotent database migrations — scripts you can safely run multiple times — are a CI/CD best practice. Oracle 23ai’s IF [NOT] EXISTS syntax makes this achievable without PL/SQL wrappers. Here’s a complete migration script template.

Idempotent schema creation script:

-- ============================================================
-- Migration: v2.5.0 - Customer Preferences Schema
-- Safe to run multiple times
-- ============================================================

-- 1. Create table if it doesn't exist
CREATE TABLE customer_preferences (
    preference_id   NUMBER         GENERATED ALWAYS AS IDENTITY,
    customer_id     NUMBER         NOT NULL,
    preference_key  VARCHAR2(100)  NOT NULL,
    preference_val  VARCHAR2(4000),
    created_at      TIMESTAMP      DEFAULT SYSTIMESTAMP,
    CONSTRAINT pk_cust_pref PRIMARY KEY (preference_id),
    CONSTRAINT uq_cust_pref_key UNIQUE (customer_id, preference_key)
) IF NOT EXISTS;

-- 2. Add columns if they don't exist (new in 23ai)
ALTER TABLE customer_preferences
    ADD (updated_at TIMESTAMP) IF NOT EXISTS;

ALTER TABLE customer_preferences
    ADD (updated_by VARCHAR2(100)) IF NOT EXISTS;

-- 3. Create index if needed
CREATE INDEX IF NOT EXISTS idx_cust_pref_customer
    ON customer_preferences (customer_id);

-- 4. Create sequence if it doesn't exist (for legacy patterns)
CREATE SEQUENCE IF NOT EXISTS seq_pref_legacy
    START WITH 1 INCREMENT BY 1 NOCACHE;

-- 5. Create or replace views (always safe, no IF needed)
CREATE OR REPLACE VIEW active_preferences AS
SELECT * FROM customer_preferences
WHERE preference_val IS NOT NULL;

-- End of migration

Why this matters for DevOps:

With Flyway or Liquibase, each migration file should run exactly once. But in some environments (re-running failed migrations, cross-environment synchronization), idempotency provides a safety net. Oracle 23ai’s native IF [NOT] EXISTS removes the need for tool-specific workarounds and makes the intent clear in the script itself.

Discover more from grepOra

Subscribe now to keep reading and get access to the full archive.

Continue reading