Oracle users, roles and tablespaces: setup script and usage report (SQL)
A SQL*Plus/SQLcl script that creates a tablespace, a role and an application user inside a PDB, then reports tablespace usage from the DBA_ views.
Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?
What this changes
In the connected PDB it creates tablespace app_data with a 500 MB datafile (autoextend to 10 GB), role app_rw with five system privileges, and user appuser with unlimited quota and an expired password. Then it prints read-only reports.
How to undo it
As a DBA in the same PDB: DROP USER appuser CASCADE; (deletes its objects), DROP ROLE app_rw; and DROP TABLESPACE app_data INCLUDING CONTENTS AND DATAFILES;. Check that nothing else uses them first.
In Oracle a user and a schema are almost the same thing: creating user APPUSER also creates the schema APPUSER that owns its tables. Roles bundle privileges. Tablespaces are logical storage areas backed by one or more data files; each user has a default tablespace for new objects and needs a quota there to store data.
Before you run it
- Connect to the PDB, not the root. A local user name like
appuseris refused inCDB$ROOT, where names must start withC##. The first query prints the container so you can check. DATAFILE SIZE 500Mwithout a file name relies on Oracle Managed Files (DB_CREATE_FILE_DESTis set). Otherwise give a path, for exampleDATAFILE '/u02/oradata/ORCLCDB/orclpdb1/app_data01.dbf' SIZE 500M.- Change the password. Oracle passwords are case-sensitive;
PASSWORD EXPIREforces the user to choose a new one at first login.
The script
-- app_user_setup.sql - tablespace, role and application user in a PDB, plus a usage report.
-- Run in SQL*Plus or SQLcl as a DBA connected to the PDB. License: CC0-1.0
SET ECHO ON
WHENEVER SQLERROR EXIT SQL.SQLCODE
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS container FROM dual;
CREATE TABLESPACE app_data
DATAFILE SIZE 500M
AUTOEXTEND ON NEXT 100M MAXSIZE 10G;
CREATE ROLE app_rw;
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SEQUENCE, CREATE PROCEDURE TO app_rw;
CREATE USER appuser
IDENTIFIED BY "CHANGE_ME_Str0ng#1"
DEFAULT TABLESPACE app_data
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON app_data
PASSWORD EXPIRE;
GRANT app_rw TO appuser;
WHENEVER SQLERROR CONTINUE
COLUMN tablespace_name FORMAT A20
COLUMN used_mb FORMAT 999,999,990.0
COLUMN max_mb FORMAT 999,999,990.0
COLUMN used_pct FORMAT 990.0
SELECT m.tablespace_name,
m.used_space * t.block_size / 1024 / 1024 AS used_mb,
m.tablespace_size * t.block_size / 1024 / 1024 AS max_mb,
m.used_percent AS used_pct
FROM dba_tablespace_usage_metrics m
JOIN dba_tablespaces t ON t.tablespace_name = m.tablespace_name
ORDER BY m.used_percent DESC;
COLUMN file_name FORMAT A60
SELECT tablespace_name,
file_name,
ROUND(bytes / 1024 / 1024) AS size_mb,
autoextensible,
ROUND(maxbytes / 1024 / 1024) AS maxsize_mb
FROM dba_data_files
ORDER BY tablespace_name, file_name;
SELECT username, account_status, default_tablespace, temporary_tablespace
FROM dba_users
WHERE username = 'APPUSER';
sql [email protected]:1521/orclpdb1.example.com @app_user_setup.sql
sqlplus [email protected]:1521/orclpdb1.example.com @app_user_setup.sql
What each part does
AUTOEXTEND ON NEXT 100M MAXSIZE 10Glets the data file grow in 100 MB steps up to 10 GB instead of filling up at 500 MB.- The role
app_rwholds the system privileges an application owner needs: log in (CREATE SESSION) and create its own objects. Prefer a role you define over broad built-in roles. QUOTA UNLIMITED ON app_datalets the user store data in that tablespace only. Without a quota,CREATE TABLEsucceeds but inserting rows fails.TEMPORARY TABLESPACE tempis used for sorts and hash joins;TEMPis the usual default name.
Reading the usage report
DBA_TABLESPACE_USAGE_METRICS reports USED_SPACE and TABLESPACE_SIZE in database blocks, which is why the query joins DBA_TABLESPACES for BLOCK_SIZE. For tablespaces with autoextensible files, TABLESPACE_SIZE is the maximum size the tablespace can grow to (taking free storage into account), so USED_PERCENT is measured against that maximum, not against the current file size. The second query lists the data files with their current size, autoextend flag and MAXBYTES.
Queried inside a PDB these views show that PDB’s tablespaces. To see every container at once, connect to the root as a common DBA and use the matching CDB_ views, which add a CON_ID column.
Later changes
ALTER USER appuser QUOTA 2G ON app_data;
ALTER TABLESPACE app_data ADD DATAFILE SIZE 1G AUTOEXTEND ON NEXT 100M MAXSIZE 30G;
REVOKE CREATE VIEW FROM app_rw;
ALTER USER appuser ACCOUNT LOCK;
Warning: DROP USER appuser CASCADE deletes the user and every object in its schema, and DROP TABLESPACE ... INCLUDING CONTENTS AND DATAFILES deletes the data and the files. Check what you would lose first with SELECT object_type, COUNT(*) FROM dba_objects WHERE owner = 'APPUSER' GROUP BY object_type and make sure a current backup exists.
Official documentation
Did this work for you?
No votes yet. Be the first.
If it did not work, the report form below tells the editors what went wrong.
See also
- 0200 PostgreSQL roles, privileges and default privileges Create login and group roles, grant access to databases, schemas and tables, and use ALTER DEFAULT PRIVILEGES so tables created later get… Intermediate · Step by step · Linux Article Roles & administration · Security & access 15 Oct 2026
- 0201 pg_hba.conf and PostgreSQL authentication methods pg_hba.conf decides who may connect from where and how they must prove who they are. Rules are checked top to bottom and… Intermediate · Explains an idea · Linux Article Install & connect · Security & access 15 Oct 2026
- 0209 Fix: FATAL: password authentication failed for user PostgreSQL reached the server and found a matching pg_hba.conf rule, but the password check failed. Usually a wrong password, a role without… Intermediate · Fixes an error · Any system Article Roles & administration · Security & access 15 Oct 2026
- 0210 Fix: FATAL: no pg_hba.conf entry for host The server received the connection but no pg_hba.conf rule matches this client address, user, database and SSL mode. Add or correct a… Intermediate · Fixes an error · Linux Article Install & connect · Security & access 15 Oct 2026
- 0214 MySQL users and privileges: CREATE USER, GRANT and authentication plugins A MySQL account is a user name plus the host it connects from. You create it with CREATE USER, give it rights… Beginner · Step by step · Linux Article Administration · Security & access 15 Oct 2026
- 0220 Fix: ERROR 1045 (28000): Access denied for user ‘appuser’@’localhost’ (using password: YES) The server rejected the user, host and password combination. Usually it is a wrong password, a host part that does not match,… Beginner · Fixes an error · Linux Article Administration · Security & access 15 Oct 2026
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Dominik +4,659 chars