And look, all the querying, joining, and updating in the world doesn’t help if the tables themselves are wrong—missing columns, bad data types, or no constraints so people can enter “banana” as a salary. DDL is where you define what the database is, not just what’s inside it.
This lesson is about the structure: tables, columns, and constraints.
You will learn to:
- Categorize the main database objects (tables, views, sequences, indexes, synonyms).
- Review table structure with
DESCand data dictionary views. - List the common Oracle column data types.
- Create simple tables with
CREATE TABLE. - Define constraints (NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY, CHECK) at creation time.
1. Database Objects and Naming Rules
Common Oracle schema objects:
- Tables – primary storage for data, organized into rows and columns.
- Views – virtual tables defined by
SELECTqueries. - Sequences – generators for numeric values (often used for keys).
- Indexes – structures that speed up lookups and sorts.
- Synonyms – alternative names for objects (shortcuts/abstractions).
Naming rules for tables and columns:
- Must begin with a letter.
- Length: 1–30 characters.
- Allowed characters:
A–Z,a–z,0–9,_,$,#. - Must not duplicate another object name owned by the same user.
- Must not be an Oracle reserved word (e.g., don’t call a table
VARCHAR2).
So employees, dept_80, and job_history are fine. select and table are not.
2. CREATE TABLE – Defining Structure
To create a table you need:
- The
CREATE TABLEsystem privilege. - Enough quota on a tablespace (storage area).
Syntax (basic):
CREATE TABLE dept (
deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13),
create_date DATE DEFAULT SYSDATE
);
Key points:
- Each column definition includes: name, data type, and often size.
DEFAULT SYSDATEoncreate_datemeans:- If you insert a row without specifying
create_date, Oracle fills in the current date.
You can inspect the structure of a table with:
DESC dept;
…and of course with the SQL Developer UI or USER_TAB_COLUMNS data dictionary view.
3. Common Oracle Data Types
Character and numeric types:
VARCHAR2(size)– variable‑length character data.CHAR(size)– fixed‑length character data (padded with spaces).NUMBER(p, s)– numeric data with precisionpand scales.NUMBER(no arguments) – general numeric type.
Date and time:
DATE– date and time (to the second).TIMESTAMP[(fractional_seconds)]– date + time + fractional seconds.INTERVAL YEAR TO MONTH– spans of years and months.INTERVAL DAY TO SECOND– spans of days, hours, minutes, seconds.
Large objects and others (high level):
LONG– legacy variable‑length character data (up to 2 GB; generally avoid in new designs).CLOB– character large object.BLOB– binary large object.BFILE– pointer to external binary file.RAW,LONG RAW– raw binary data.ROWID– encoded physical address of a row.
In most application tables you’ll use NUMBER, VARCHAR2, DATE, and occasionally TIMESTAMP and LOBs.
4. DEFAULT Values
You can specify a default for a column in CREATE TABLE:
CREATE TABLE employees_demo (
employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL,
hire_date DATE DEFAULT SYSDATE,
status VARCHAR2(10) DEFAULT 'ACTIVE'
);
Rules:
- Defaults can be literals or expressions/functions like
SYSDATE. - You cannot reference other columns or pseudocolumns in a default.
- The default’s data type must be compatible with the column type.
Default values apply when no value is supplied in the INSERT for that column.
5. Constraints – Enforcing Rules on Data
Constraints enforce business rules and maintain data integrity.
Core types:
NOT NULL– column must have a value.UNIQUE– column (or combination) must be unique across the table.PRIMARY KEY– uniqueness + NOT NULL; main identifier for a row.FOREIGN KEY– column references primary/unique key in another table.CHECK– arbitrary condition must be satisfied.
5.1 Where and when you can define constraints
- At table creation (
CREATE TABLE). - After creation using
ALTER TABLE. - At column level or table level:
- Column level: constraint defined inline with the column.
- Table level: constraint defined after all column definitions.
NOT NULL is always a column‑level constraint.
If you don’t name a constraint, Oracle invents one (SYS_C009876 etc.), which is how you end up hating yourself when debugging. Naming them is strongly recommended.
5.2 Column‑level constraints
Defined inline with the column:
CREATE TABLE employees_demo (
employee_id NUMBER(6)
CONSTRAINT emp_emp_id_pk PRIMARY KEY,
last_name VARCHAR2(25) CONSTRAINT emp_lname_nn NOT NULL,
email VARCHAR2(25),
salary NUMBER(8,2)
);
emp_emp_id_pkis a PRIMARY KEY onemployee_id.emp_lname_nnis a NOT NULL onlast_name.
5.3 Table‑level constraints
Defined after all columns; useful for composite keys or when you prefer to group constraints together:
CREATE TABLE employees_demo (
employee_id NUMBER(6),
first_name VARCHAR2(20),
last_name VARCHAR2(25),
email VARCHAR2(25),
salary NUMBER(8,2),
CONSTRAINT emp_pk PRIMARY KEY (employee_id),
CONSTRAINT emp_email_uk UNIQUE (email)
);
For composite primary keys:
CONSTRAINT emp_name_pk PRIMARY KEY (employee_id, first_name)
Table‑level constraints always reference one or more existing columns by name.
5.4 NOT NULL
Ensures a column cannot be NULL.
last_name VARCHAR2(25) CONSTRAINT emp_lname_nn NOT NULL
- Attempting to insert a row without
last_nameraises an error. NOT NULLis always column‑level.
5.5 UNIQUE
Ensures each non‑NULL value is unique in the column (or column set).
Example – prevent duplicate emails:
CONSTRAINT emp_email_uk UNIQUE (email)
- First insert of
smith@example.comsucceeds. - Second insert with the same email fails with a unique‑constraint violation.
5.6 PRIMARY KEY and FOREIGN KEY
PRIMARY KEY:
- Uniquely identifies each row.
- Implies
UNIQUE+NOT NULL.
Example:
CONSTRAINT dept_pk PRIMARY KEY (department_id)
FOREIGN KEY:
- Enforces a relationship to a parent table.
- Child values must match an existing parent key (or be
NULL, unless restricted).
Example – table‑level foreign key:
CREATE TABLE employees_demo (
employee_id NUMBER(6) PRIMARY KEY,
last_name VARCHAR2(25) NOT NULL,
department_id NUMBER(4),
CONSTRAINT emp_dept_fk
FOREIGN KEY (department_id)
REFERENCES departments (department_id)
);
department_idinemployees_demomust either beNULLor match adepartment_idindepartments.- The referenced column must have a PRIMARY KEY or
UNIQUEconstraint defined first.
Options:
ON DELETE CASCADE– deleting a parent row automatically deletes matching child rows.ON DELETE SET NULL– deleting a parent row sets matching child foreign keys toNULL.
Good for enforcing referential integrity; dangerous if you forget you added CASCADE.
5.7 CHECK
Validates that a condition is true for each row. It cannot reference columns in other tables.
Example – salary must be > 0:
CONSTRAINT emp_salary_chk
CHECK (salary > 0)
Another example – restrict job_id to a set of codes:
CONSTRAINT emp_job_chk
CHECK (job_id IN ('SA_REP', 'IT_PROG', 'AD_PRES'))
If you violate a constraint, Oracle tells you which constraint you violated—another good reason to name them.
6. Creating Tables with Subqueries (CTAS)
You can create a table and populate it at the same time using CREATE TABLE ... AS SELECT (CTAS).
Example – create dept80 from employees in department 80:
CREATE TABLE dept80 AS
SELECT employee_id,
last_name,
salary * 12 AS annsal,
hire_date
FROM employees
WHERE department_id = 80;
Key points:
- Column names and types are derived from the
SELECTlist. - Expressions must have aliases that are valid column names (
annsalinstead ofsalary*12). - Data is copied at creation time.
- Only explicit NOT NULL constraints are carried over; other constraints (PK, FK, UNIQUE, CHECK) are not copied and must be redefined with
ALTER TABLElater if needed.
7. ALTER TABLE – Changing Existing Structure
Use ALTER TABLE to:
- Add new columns.
- Modify column definitions (type, size, default).
- Add or drop constraints.
- Drop or mark columns as unused.
- Set a table to read‑only or back to read/write.
7.1 ADD columns
ALTER TABLE dept80
ADD (job_id VARCHAR2(9));
- New columns are added to the end of the table.
- Existing rows get
NULLin the new column.
7.2 MODIFY columns
ALTER TABLE dept80
MODIFY (last_name VARCHAR2(30));
Rules:
- You can increase the length of a character or number column (if compatible).
- Decreasing length is only allowed if no existing values violate the new size.
- Changing data types is restricted if existing data can’t be converted.
- Changing a default affects only future inserts, not existing rows.
7.3 DROP columns
ALTER TABLE dept80
DROP COLUMN job_id;
- Permanently removes the column and its data.
- Can be time‑consuming for large tables and may impact concurrent DML.
7.4 SET UNUSED and DROP UNUSED COLUMNS
Alternative to DROP COLUMN for large tables:
ALTER TABLE dept80 SET UNUSED (job_id);
-- Later...
ALTER TABLE dept80 DROP UNUSED COLUMNS;
SET UNUSEDmarks columns as logically removed but leaves data physically for now.DROP UNUSED COLUMNSremoves all unused columns (maybe during a maintenance window).ONLINEkeyword can allow DML while marking unused (in Enterprise features).
7.5 READ ONLY / READ WRITE
You can lock a table’s structure and data against change during maintenance:
ALTER TABLE employees READ ONLY;
-- table can be queried, but not modified or altered
-- When done
ALTER TABLE employees READ WRITE;
Useful when you want to freeze a table while still letting people run reports.
8. DROP TABLE and the Recycle Bin
DROP TABLE removes a table and its data.
DROP TABLE dept80;
By default (in modern Oracle with Recycle Bin enabled):
- The table is moved into the Recycle Bin.
- You can recover it using
FLASHBACK TABLE ... TO BEFORE DROP. - Dependent objects become invalid and must be recompiled or recreated.
- Object privileges on the table are removed.
To bypass the Recycle Bin and remove the table permanently:
DROP TABLE dept80 PURGE;
- No flashback possible; table is gone.
Flashback example:
FLASHBACK TABLE dept80 TO BEFORE DROP;
After which you can DESC dept80 and see the structure again.
9. What You Should Now Be Able to Do
By the end of this lesson, you should be able to:
- Identify and categorize core database objects like tables, views, sequences, indexes, and synonyms.
- Review table structures using
DESCand related dictionary views. - Choose appropriate Oracle data types for columns.
- Create tables with
CREATE TABLE, including default values. - Define constraints (NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY, CHECK) at creation or later with
ALTER TABLE. - Use
CREATE TABLE AS SELECTto clone structure and data. - Modify and remove tables with
ALTER TABLEandDROP TABLE(with an awareness of the Recycle Bin).
You now have the power not just to query data, but to shape the schema itself—which is how you go from “SQL user” to “person everyone blames when a table disappears.”