Oracle Reference
0. Connection & Basics
0.1 Client Connect
Connecting to an Oracle instance via the
sqlplus CLI.
# Connect using Easy Connect syntax
sqlplus hr/password@localhost:1521/orclpdb
# Connect as SYSDBA (requires OS-level authentication)
sqlplus / as sysdba
# Execute a script and exit
sqlplus hr/password@db_alias @script.sqlSQL*Plus: Release 21.0.0.0.0 - Production on Wed May 22 10:00:00 2024
Connected to: Oracle Database 21c Express Edition
0.2 CLI Meta-commands
Internal sqlplus commands for session
configuration and introspection.
DESC employees; -- Describe table/view structure
SET PAGESIZE 100; -- Set rows per page
SET LINESIZE 200; -- Set line width
COLUMN salary FORMAT $99,999;-- Format specific column output
SPOOL report.txt; -- Write output to a file
SPOOL OFF; -- Close the spool file
EXIT; -- Quit sqlplus(Table description or configuration applied)
0.3 Comments
Annotating SQL code.
-- Single-line comment for a quick note
/* Multi-line comment
block for complex logic */
SELECT * FROM dual; -- Dual is a special one-row, one-column tableDUMMY
-----
X
1. Data Types
1.1 Numerics
The NUMBER type handles both integers and
floating-point numbers.
SELECT
CAST(1234.56 AS NUMBER(6, 2)) AS p_fixed, -- Precision 6, scale 2
CAST(123456 AS NUMBER(6)) AS p_int, -- 6-digit integer
1.23f AS p_float, -- BINARY_FLOAT (32-bit)
1.23d AS p_double -- BINARY_DOUBLE (64-bit)
FROM dual; P_FIXED P_INT P_FLOAT P_DOUBLE
---------- ---------- ---------- ----------
1234.56 123456 1.23 1.23
1.2 Strings & Binaries
Oracle uses VARCHAR2 (max 4000 bytes in SQL,
32k in PL/SQL) for strings.
SELECT
CAST('Fixed' AS CHAR(10)) AS c_char, -- Space-padded
CAST('Variable' AS VARCHAR2(20)) AS c_v2, -- Standard string
TO_CLOB('Long Text') AS c_clob, -- Character Large Object
HEXTORAW('DEADBEEF') AS c_blob -- Binary data (RAW/BLOB)
FROM dual;C_CHAR C_V2 C_CLOB C_BLOB
---------- ---------- ---------- --------
Fixed Variable Long Text DEADBEEF
1.3 Date & Time
The DATE type includes both date and time
(to the second).
SELECT
SYSDATE, -- Current date and time
SYSTIMESTAMP, -- High precision with TZ
CURRENT_DATE, -- Session-specific date
INTERVAL '1' YEAR - INTERVAL '2' MONTH, -- YM Interval
INTERVAL '10' DAY + INTERVAL '5' MINUTE -- DS Interval
FROM dual;SYSDATE SYSTIMESTAMP CURRENT_DATE
--------- --------------------------------- ---------
22-MAY-24 22-MAY-24 10:00:00.123456 +00:00 22-MAY-24
1.4 Booleans & Enums
Oracle SQL lacks a native BOOLEAN type. Use
NUMBER(1) or CHAR(1) with
constraints.
CREATE TABLE app_flags (
is_active NUMBER(1) CHECK (is_active IN (0, 1)), -- 0=False, 1=True
status CHAR(1) CHECK (status IN ('A', 'I', 'P')), -- Enum-like check
not_null_col VARCHAR2(10) NOT NULL
);Table created.
2. Basic Querying (DQL)
2.1 SELECT & Aliases
Retrieving data using aliases and the DUAL
table.
SELECT
first_name || ' ' || last_name AS "Full Name", -- Double quotes for case
salary * 1.1 AS increased_salary,
'Static Value' AS note
FROM employees;Full Name INCREASED_SALARY NOTE
-------------------- ---------------- ------------
Steven King 26400 Static Value
2.2 WHERE Filtering
Filtering results with standard and Oracle-specific operators.
SELECT * FROM employees
WHERE department_id IN (10, 20)
AND last_name LIKE 'S%'
AND salary BETWEEN 5000 AND 10000
AND commission_pct IS NOT NULL;(Filtered employee records)
2.3 ORDER BY
Sorting results with null placement control.
SELECT last_name, salary, commission_pct
FROM employees
ORDER BY salary DESC, commission_pct ASC NULLS LAST;(Sorted records)
2.4 LIMIT / OFFSET
Pagination using FETCH (12c+) or legacy
ROWNUM.
-- Modern (12c+) syntax
SELECT employee_id FROM employees
ORDER BY employee_id
OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY;
-- Legacy ROWNUM (requires subquery for correct ordering)
SELECT * FROM (
SELECT e.*, ROWNUM rnum FROM (SELECT * FROM employees ORDER BY id) e
WHERE ROWNUM <= 15
) WHERE rnum > 10;(5 rows)
3. Joins & Set Operations
3.1 Inner & Outer Joins
Standard ANSI joins are preferred over legacy Oracle
(+) syntax.
SELECT e.last_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id
LEFT OUTER JOIN locations l ON d.location_id = l.location_id;(Joined employee and department data)
3.2 Cross & Self Joins
Generating Cartesian products or hierarchical self-references.
-- Self Join
SELECT e.last_name AS emp, m.last_name AS mgr
FROM employees e
JOIN employees m ON e.manager_id = m.employee_id;
-- Cross Join
SELECT * FROM departments CROSS JOIN regions;EMP MGR
---------- ----------
Whalen Kochhar
3.3 UNION, INTERSECT, MINUS
Oracle uses MINUS instead of
EXCEPT.
SELECT email FROM customers
UNION -- Distinct values (UNION ALL for duplicates)
SELECT email FROM leads
MINUS
SELECT email FROM blocked_users;(Distinct list of active emails)
3.4 JOIN with Subqueries
Using inline views as join targets.
SELECT d.department_name, avg_sal.val
FROM departments d
JOIN (
SELECT department_id, AVG(salary) AS val
FROM employees GROUP BY department_id
) avg_sal ON d.department_id = avg_sal.department_id;(Departments with their average salaries)
4. Aggregation & Grouping
4.1 GROUP BY
Aggregating rows into buckets.
SELECT department_id, job_id, SUM(salary)
FROM employees
GROUP BY department_id, job_id;DEPARTMENT_ID JOB_ID SUM(SALARY)
------------- ---------- -----------
90 AD_VP 34000
4.2 HAVING
Filtering aggregated results.
SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 10;(Departments with more than 10 employees)
4.3 Aggregate Functions
Standard and Oracle-specific aggregation (like
LISTAGG for string concat).
SELECT
COUNT(DISTINCT department_id) AS dept_count,
ROUND(AVG(salary), 2) AS avg_sal,
LISTAGG(last_name, '; ') WITHIN GROUP (ORDER BY last_name) AS names
FROM employees
WHERE department_id = 30;DEPT_COUNT AVG_SAL NAMES
---------- ---------- ----------------------------------------
1 4150 Baida; Colmenares; Himuro; Khoo; Raphaely
4.4 DISTINCT
Removing duplicate rows from the output.
SELECT DISTINCT job_id FROM employees;JOB_ID
----------
AD_PRES
IT_PROG
5. Advanced Querying
5.1 Subqueries
Correlated and non-correlated subqueries.
-- Scalar subquery in SELECT
SELECT last_name, (SELECT MAX(salary) FROM employees) AS top_sal
FROM employees;
-- Correlated subquery in WHERE
SELECT last_name FROM employees e
WHERE salary > (
SELECT AVG(salary) FROM employees WHERE department_id = e.department_id
);(Employees earning above their department average)
5.2 Common Table Expressions (WITH)
Using WITH to simplify complex queries.
WITH dept_costs AS (
SELECT department_id, SUM(salary) AS total
FROM employees GROUP BY department_id
)
SELECT department_id FROM dept_costs
WHERE total > (SELECT AVG(total) FROM dept_costs);(High-cost department IDs)
5.3 Recursive CTEs (CONNECT BY vs WITH)
Oracle’s traditional CONNECT BY vs modern
recursive WITH.
-- Traditional CONNECT BY
SELECT LEVEL, last_name, manager_id
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;
-- Modern Recursive WITH (11gR2+)
WITH emp_hierarchy(id, name, mgr_id, lvl) AS (
SELECT employee_id, last_name, manager_id, 1 FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.employee_id, e.last_name, e.manager_id, h.lvl + 1
FROM employees e JOIN emp_hierarchy h ON e.manager_id = h.id
)
SELECT * FROM emp_hierarchy;(Tree-structured employee hierarchy)
6. Window Functions
6.1 OVER & PARTITION BY
Computing values across a set of rows.
SELECT
last_name, department_id, salary,
SUM(salary) OVER(PARTITION BY department_id) AS dept_total,
ROUND(salary / SUM(salary) OVER(PARTITION BY department_id) * 100, 2) AS pct
FROM employees;LAST_NAME DEPT SALARY DEPT_TOTAL PCT
---------- ---- ------ ---------- ------
King 90 24000 58000 41.38
6.2 Ranking
Assigning ranks based on a window.
SELECT
last_name, salary,
ROW_NUMBER() OVER(ORDER BY salary DESC) AS row_num,
RANK() OVER(ORDER BY salary DESC) AS rnk,
DENSE_RANK() OVER(ORDER BY salary DESC) AS drnk
FROM employees;LAST_NAME SALARY ROW_NUM RNK DRNK
---------- ---------- ---------- ---------- ----------
King 24000 1 1 1
Kochhar 17000 2 2 2
De Haan 17000 3 2 2
6.3 Analytics (LEAD / LAG)
Accessing data from adjacent rows.
SELECT
last_name, hire_date,
LAG(last_name) OVER(ORDER BY hire_date) AS prev_hired,
LEAD(last_name) OVER(ORDER BY hire_date) AS next_hired
FROM employees;LAST_NAME HIRE_DATE PREV_HIRED NEXT_HIRED
---------- --------- ---------- ----------
King 17-JUN-03 Whalen
Whalen 17-SEP-03 King Mavris
7. Data Modification (DML)
7.1 INSERT
Standard insert and multi-table insert.
-- Single row
INSERT INTO departments (department_id, department_name)
VALUES (300, 'Data Science');
-- Conditional multi-table insert
INSERT ALL
WHEN salary > 10000 THEN INTO high_earners (id, sal) VALUES (eid, sal)
ELSE INTO low_earners (id, sal) VALUES (eid, sal)
SELECT employee_id eid, salary sal FROM employees;1 row created.
107 rows created.
7.2 UPDATE & DELETE
Standard data modification.
UPDATE employees SET salary = salary * 1.05
WHERE department_id = 90;
DELETE FROM job_history
WHERE end_date < TO_DATE('01-JAN-2010', 'DD-MON-YYYY');3 rows updated.
12 rows deleted.
7.3 Upsert / Merge
Merging source data into a target table.
MERGE INTO target_table t
USING source_table s ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.val = s.val, t.updated_at = SYSDATE
WHEN NOT MATCHED THEN
INSERT (id, val, created_at) VALUES (s.id, s.val, SYSDATE);5 rows merged.
8. Schema Definition (DDL)
8.1 CREATE & ALTER Table
Defining table structure and identity columns (12c+).
CREATE TABLE projects (
project_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR2(100) NOT NULL,
budget NUMBER(12, 2) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
ALTER TABLE projects ADD (status VARCHAR2(20));
ALTER TABLE projects MODIFY (budget NUMBER(15, 2));Table created.
Table altered.
8.2 Constraints
Ensuring data integrity at the schema level.
ALTER TABLE projects ADD CONSTRAINT uq_proj_name UNIQUE (name);
ALTER TABLE projects ADD CONSTRAINT ck_budget CHECK (budget >= 0);
-- Foreign Key with Cascade Delete
ALTER TABLE tasks ADD CONSTRAINT fk_task_proj
FOREIGN KEY (project_id) REFERENCES projects(project_id) ON DELETE CASCADE;Table altered.
8.3 Indexes & Performance
Optimizing data access.
CREATE INDEX idx_proj_name ON projects(name);
CREATE BITMAP INDEX idx_emp_gender ON employees(gender); -- For low cardinality
CREATE UNIQUE INDEX idx_emp_email ON employees(email);Index created.
8.4 Views & Materialized Views
Stored queries and persisted snapshots.
-- Standard View
CREATE VIEW v_high_sal AS
SELECT * FROM employees WHERE salary > 15000;
-- Materialized View (cached result)
CREATE MATERIALIZED VIEW mv_dept_sal_summary
BUILD IMMEDIATE
REFRESH COMPLETE ON DEMAND
AS SELECT department_id, SUM(salary) total FROM employees GROUP BY department_id;
EXEC DBMS_MVIEW.REFRESH('mv_dept_sal_summary');View created.
Materialized view created.
9. Logic & Administration
9.1 Transactions
Oracle uses implicit transaction starts and manual commits.
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
SAVEPOINT sp1; -- Create intermediate rollback point
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- If error: ROLLBACK TO sp1;
COMMIT; -- Finalize all changesCommit complete.
9.2 Triggers & PL/SQL Basics
Server-side procedural logic.
-- Row-level trigger to audit changes
CREATE OR REPLACE TRIGGER trg_audit_sal
BEFORE UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
INSERT INTO sal_audit (emp_id, old_sal, new_sal, change_date)
VALUES (:OLD.employee_id, :OLD.salary, :NEW.salary, SYSDATE);
END;
/Trigger created.
9.3 Explain Plan
Analyzing query execution performance.
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE last_name = 'King';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 2 | 136 | 2 (0)|
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 2 | 136 | 2 (0)|
|* 2 | INDEX RANGE SCAN | EMP_NAME_IX | 2 | | 1 (0)|
9.4 Roles & Permissions
Security management.
CREATE ROLE report_user;
GRANT SELECT ON hr.employees TO report_user;
GRANT report_user TO jsmith;
REVOKE DELETE ON hr.departments FROM report_user;Role created.
Grant succeeded.