- Section 1: Database Concepts
- Section 2: Download & Installation
- Section 3: Retrieving Data
- Section 4: Restricting Data
- Section 5: Sorting Data
- Section 6: Using Subsitution Variables
- Section 7: Single-row Functions
- Section 8: Conversion Functions
- Section 10: Group Functions
- Section 11: Grouping Data
- Section 12: Joining Multiple Tables
- General Notes
- What is a join
- Join Types
- NATURAL JOIN
- Join With The USING Clause (Equijoin)
- INNER JOIN
- Multiple JOIN Operations
- Restricting Joins
- SELF JOIN
- Non-Equijoins (Joining Unequal Tables)
- OUTER JOIN
- Older Join Syntax (Non-ANSI Standard)
- Differences Between Inner / Outer Joins and Equi / Non-Equi Joins
- Which Join Should You Use
- Entity-Relationship Model in DBMS
- Section 13: Using Subqueries (Nested Queries)
- Section 14: Working With The Oracle SET Operators
- Section 15: Data Definition Language (DDL)
- Section 16: Data Manipulation Language (DML)
- Section 17: Constraints
- Section 18: Database Views
- Section 19: Data Dictionary Views
- What's In A Data Dictionary View?
- Dictionary View
- USER, DBA, ALL, V$ Prefixes
- USER_TABLES Data Dictionary View
- USER_TAB_COLUMNS Data Dictionary View
- USER_CONSTRAINTS VIEW
- USER_CONS_COLUMNS Data Dictionary Views
- USER_VIEWS Data Dictionary View
- USER_TAB_COMMENTS & USER_COL_COMMENTS Data Dictionary Views
- Section 20: Oracle Sequences
- Section 21: Oracle Synonyms
- Collection of programs that enable the users to access, manipulate, and retrieve data to the users.
- There are four types of DBMS
-
Hierarchical DBMS
- Parent-child relationship for storing data
- Windows XP
- Rare and not often used today
-
Network DBMS
- Many-to-many relationships
- Not frequently used
-
Relational DBMS
- Most used
- MySQL
- Oracle
- MsSQL
- Pre-defined types
- RDBMS
- Most used
-
Object-relational DBMS
- Useful as well
- PostgreSQL
-
- Security
- Very secure database
- Performance
- Oracle has an optimizer, tuning options, and hardware to handle very large sets of data
- Scalability
- Powerful Coding
- Oracle SQL
- PL/SQL
- Support
- You must know how to deal with this database
- It's not free
- Every column can only have one type of data
- Rows can have many types of data
- Tables that have their own data, but have relationships with other tables via an ID stored in both tables.
- They use entity-logic
- The smallest unit containing meaningful set of data is called an entity.
- Rows, columns, etc.
- A 'thing' or 'object' in the real world that is distinguishable from all other
objects.
- i.e. A person in a university is an entity.
- Also known as Multitenant Architecture.
- In new versions of Oracle, there is one overall Container Database that
has multiple pluggable databases.
- Unlike the pluggable databases which are full databases, it does not have an
object.
- CDB stores only metadata such as configuration files, etc.
- There must be at least one inside the container database.
- Unlike the pluggable databases which are full databases, it does not have an
object.
- Previously, each database needed its own server, regardless of size. With a
CDB, it's possible to have many DB's on a single server.
- Having one server per DB was a lot of work for the DB.
A schema is a collection of logical structures of data or objects.
- A database user has only one schema with the same name as its username.
- Table (A base unit of the database to store data, formatted with columns and rows).
- View (A virtual table that provides access to a subset of columns or some
restricted rows from one or more tables).
- Stores SQL queries
- Table's SQL script to return data, saved to a virtual table.
- SQL queries work on views the same as they do tables.
- Constraint (The rules for restricting invalid data entry into tables).
- E.g. a Check Constraint will prevent certain entries from being added into the table.
- Index (Used for improving the speed of data retrieval from the tables).
- Knows physical address of data in blocks and goes to the data directly.
- Work automaticallly.
- Sequences (Database objects which generate unique integers).
- Synonym An alternative name (alias) for the database objects.
- References to the original object.
- Materialized View (Has a real table filled by an SQL query unlike the
views. The real table is truncated and refilled with a specified time
frequency.)
- Imagine you have a view with a very complex stored SQL query, it will take a long time. The benefit of using a materialized view is that the data is stored for faster data retrieval.
- Functions and procedures (Functions return some value, but procedures return nothing).
- PL/SQL (P rocedural L anguage extension to SQL)
- SQL + Procedural Programming
- Allows variables, control structures, loops, triggers, I/O operations, etc.
- Triggers (Compiled PL/SQL program unites stored in the database and execute with a specific event).
- Packages Schema objects that are compiled and stored in the database.
- Consist of SQL - PL/SQL codes, variables, cursors, etc. to perform one or more than one operation by using functions and procedures.
- Database Links (The connections between two physical database servers).
- NonSchema Objects (Other types of objects stored in the database are
called Nonschema Objects.These objects are not in a schema.)
- There are a lot of nonschema objects, such as:
- Directories
- Roles
- Tablespaces
- users
- etc.
- There are a lot of nonschema objects, such as:
- Since each user must have a schema, we can consider schemas as users. But technically, schemas are the collections of objects for each user in Oracle Database.
- Abbreviation of H uman R esources. A test schema for practicing.
- Pre-filled with a lot of data to work with.
- Tables
- Views
- Triggers
- Constraints
- Etc.
- Entity Relationship Diagram
- The three lines at the end of each line represent one-to-many relationships
- For example: There can be many locations whose
country_id
is set to the same country.
- For example: There can be many locations whose
Structured Query Language
- Language used to interact with the database.
- Ansi SQL is the standard used across all DBMS.
- A merican N ational S tandards I nstitute
- BI, Data Science, Database Administration, Web Development, etc.
- Use VirtualBox
- Recommended
- Uses a VM (Virtual Machine)
- Install directly to your PC
- Oracle Live SQL
Run the Unlock Script in CMD:
sqlplus
/ as sysdba;
alter
session set container=orclpdb;
alter
pluggable database open;
alter
pluggable database orclpdb save state;
alter
user hr identified by hr account unlock;
/
- Connect as the sys or system user.
- Run the SQL script found in SQL Script by hitting Run Script (F5) in SQL Developer.
- SQL Plus a tool that allows you to connect to the database
- There is a tnsnames.ora file inside your_database_folder/network/admin
- Create another user ORCLPDB and copy the config from ORCL
- Change the
SERVICE_NAME
to match the newly created one - Change hr to use TNS and this new type.
- Click the Plus button and create a new connection.
- Write a name (Use hr to keep it simple)
- Fill in the username and password.
- Passwords are case-sensitive
- Default hr per the code above
- Tick the save password option
- Select Service Name.
- Write the pluggable database name that was created
- Default is orclpdb.
- Change connection type to TNS
- We're interested in the CDB (Container DataBase), so select it.
- If it's not there, go to Services and start the Oracle services (If they aren't already running).
- Click your connection and click SQL Worksheet above (Green button)
- Alternative: Right-click on the connection you want, and hit connect.
- Create the other databases using the files in Install Script
- Must be in the root of the same drive as the database folder
Normal user with dba privilege.
Highest privilege user in the oracle DB.
- DML (Data Manipulation Language)
SELECT
INSERT
UPDATE
DELETE
MERGE
- DDL (Data Definition Language)
CREATE
ALTER
DROP
RENAME
TRUNCATE
- DCL (Data Control Language)
GRANT
REVOKE
- TCL (Transaction Control Language)
COMMIT
ROLLBACK
SAVEPOINT
DML (Data Manipulation Language) |
DDL (Data Definition Language) |
DCL (Data Control Language) |
TCL (Transaction Control Language) |
---|---|---|---|
SELECT |
CREATE |
GRANT |
COMMIT |
INSERT |
ALTER |
REVOKE |
ROLLBACK |
UPDATE |
DROP |
SAVEPOINT |
|
DELETE |
RENAME |
||
MERGE |
TRUNCATE |
- Right-click to the left of the code, and click toggle line numbers to make them appear.
- In the Oracle DB, there's a table called dual. It's a dummy table with a
single row, used for
SELECT
ing something when you are not interested in the data, but instead the results of some function.
- SQL statements are not case-sensitive.
- User variables should be lower-case, and SQL commands should be upper.
- SQL Statements can be separated into multiple lines
- Keywords cannot be abbreviated or split
- IN SQL Developer, the delimiter is
;
or/
. - To use SQLPlus instead:
- Connect using
sqlplus <user>/<pass>@<PDB name>
- Connect using
VARCHAR2(size)
(Variable-length character data)CHAR(size)
(Fixed-length character data)NUMBER(p, s)
(Variable-length numeric data)- precision and scale
DATE
(Date and time values)LONG
(Variable-length character data [up to 2 GB])- Not recommended anymore.
- Use
BLOB
orCLOB
RAW
andLONG RAW
(Raw binary data)- Not recommended anymore.
- Use
BLOB
orCLOB
BLOB
(Maximum size is (4GB - 1) * (DB_BLOCK_SIZE initialization parameter (8TB to 128 TB)))LOB
stands for L arge OB jects- Mainly used for large blocks of unstructured data
- Images, video, sound, etc
CLOB
(Maximum size is (4GB - 1) * (DB_BLOCK_SIZE))LOB
stands for L arge OB jects
BFILE
(Binary data stored in an external file (up to 4GB))- External LOBs
- Read only
- Stores a pointer to a file. Limited by the OS.
ROWID
(A base 64 number system representing the unique address of a row in its table.)
Marker that indicates that the data does not exist in the database. Null means Unknown or non-existent.
- Not the same as an empty string, 0, or space
NULL
doesn't take up space in the physical disk, while these doNULL
values are not counted as rows while these are
Describes the structure of a table
DESC[RIBE] table_name;
- Column names
- Nullable or not
- Data types of columns
SQL Developer has its own version:
- Double-click any table in the script
- Hit Shift + F4
Improved version of the DESCRIBE
command.
INFO
[RMATION] table_name;
INFO
[RMATION]+ table_name; -- Provides even more information about the columns
- The column with the asterisk next to it is the Primary Key.
Always start with ORA followed by a number code
- If the error is too basic or common, the cause and action fields will be empty.
- Type the exact error into google to solve it, if the explanation given is bad.
Used to retrieve data from the database.
SELECT *
FROM < table >;
- Selecting fewer columns means better and faster performance
Renames a column heading.
SELECT first_name AS name, last_name AS surname, email
FROM employees;
-- It's also possible to not use AS, and just use double quotes.
SELECT first_name "name", last_name AS surname, email
FROM employees;
- Useful for calculations (Used quite often)
- Should be used with double quotes if column contains special characters, space characters, or handling case-sensitivity.
Used to increase readability and usability. Writes special characters without the need to escape them.
SELECT q '[Text]' my_text
FROM dual;
Text
will be the value in the rowmy_text
will be the name of the column- Any character can be used as a delimiter, although brackets are expected.
- To escape a single quote character, you must use two single quotes, unless using the quote operator.
SELECT q '[It's a good day today mate]' AS "Quote Operator" FROM dual;
Used to eliminate duplicate rows
SELECT DISTINCT < column >
FROM < table >;
SELECT DISTINCT < column >, < column >
FROM < table >;
SELECT UNIQUE <column>
FROM < table >; -- Not standard and not always recognized
- Row-based operator, not column. Only one
DISTINCT
is needed in a query. - If multiple columns are used with
DISTINCT
, then it returns all the unique combinations of those columns.
Combines strings and outputs into a single columns.
SELECT < column > || < column >
FROM < table >;
-- Method 2
SELECT CONCAT(
<column>, <column>
)
FROM < table >;
- Concatenating with
NULL
does not returnNULL
, it returns the other char strings.
Operators | Description |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
- PEMDAS applies
- Can contain column names, numeric numbers, and arithmetic operators.
Arithmetic operations with date values return new dat values:
SELECT sysdate + 3
FROM dual; -- Three days after today.
- Any operation that contains a
NULL
will returnNULL
regardless of if either side had a value.
Limits the rows returned by a query.
SELECT *|{[DISTINCT] column [alias],...}
FROM < table >
[
WHERE logical expression (s)];
-- Example
SELECT *
FROM employees
WHERE job_id = 'IT_PROG';
- Used with the following:
- Comparison Operators
=
,<
,>
,<=
,>=
,<>
,!=
BETWEEN...AND
,IN
,LIKE
, andNULL
- Comparison Operators
<>
is not equal to.- The same as
!=
- The same as
Retrieves data between the specified lower and upper limit
- The lower and upper limit values are included.
SELECT <columns>
FROM < table >
WHERE < column > BETWEEN < value > and < value >;
Used to retrieve the restricted values in a specified list
- Order of specified values is not important
SELECT <columns>
FROM < table >
WHERE < column > IN ([list of possible values])
-- Example
SELECT employee_id
FROM employees
WHERE employee_id IN (100, 105, 102, 200)
- Up to 1,000 values can be used in the list, but it's not recommended due to speed.
- If you're not sure if a value is in a database, don't use it in an
IN
clause. - Without an index, the data will be returned in insertion order.
Used to perform a wildcard search and retrieves rows matching a certain character pattern.
Symbol | Character | Description |
---|---|---|
% | Percentage Sign | Matches any number of characters including 0 or more characters. |
_ | Underscore | Matches exactly one character. |
SELECT <columns>
FROM < table >
WHERE < column > LIKE '%val_to_find%';
- Much slower than equal (
=
) search
SELECT *
FROM < table >
WHERE < column > IS [NOT] NULL;
= NULL
is not the same as theIS NULL
Allow us to use more than one operator in the WHERE
clause.
SELECT *
FROM < table >
WHERE [conditions] AND [conditions];
AND
(True if all conditions are met)OR
(True if any conditions are met)NOT
The order the expressions in a WHERE
clause are performed:
Order | Meaning |
---|---|
1 | Arithmetic Operators |
2 | Concatenation Operator |
3 | Comparison Conditions |
4 | IS [NOT] NULL , LIKE , [NOT] IN |
5 | [NOT] BETWEEN |
6 | Not Equal To |
7 | NOT logical Operator |
8 | AND Logical Operator |
9 | OR Logical Operator |
- Use parenthesis to avoid logical order confusion, or to change the order
specifically.
- Increases code readability
- Use
set linesize <amount>
in sqlplus to make it more readable.
Changes the returning rows' order by any column, alias, or numeric positions of
the columns in the SELECT
list.
SELECT <columns>
FROM < table >
WHERE [conditions]
ORDER BY < column >;
SELECT column1, column2
FROM < table >
WHERE [conditions]
ORDER BY 1; -- Orders by column1
SELECT column1, column2 AS col
FROM < table >
WHERE [conditions]
ORDER BY col; -- Orders by column2
- Can sort by ascending (ASC - Lowest to highest) or descending (DESC - Highest
to lowest).
- Default is ascending
- Can be used with multiple columns.
- Will be sort each column from left to right, without changing the sorting of the previous columns (same entry).
SELECT column1, column2
FROM < table >
WHERE [conditions]
ORDER BY column2 DESC, column1 ASC;
- Queries can be ordered by columns in ascending or descending order individually.
- Aliases and numeric positions for columns can also be sorted by asc or desc.
NULL
values are displayed last in ascending order.- They cannot be sorted, so they are returned after.
The NULLS FIRST
or NULLS LAST
operators are used for changing the order of
the NULL
values.
SELECT column1, column2
FROM < table >
WHERE [conditions]
ORDER BY
column2 [ASC | DESC] NULLS [FIRST | LAST],
column1 [ASC | DESC] NULLS [FIRST | LAST];
ROWID
(Unique identifier that contains the physical address of a row).- Oracle automatically generates a unique
ROWID
at the time of insertion of a row. - Static and does not change so long as the row is not dropped.
- Contains:
- Disk Number
- Cylinder
- Block Number
- Block Offset
- Etc.
- Very fast for queries if you know it.
- Oracle automatically generates a unique
ROWNUM
(Nothing but the consecutive logical sequence number given to the rows fetched from the table).- To limit the returning rows in a table, you can use the
ROWNUM
pseudo column. - Temporary. If you change the query, the
ROWNUM
will refer to another row.
- To limit the returning rows in a table, you can use the
SELECT <columns>
FROM (
SELECT <columns>
FROM < table >
WHERE [conditions]
ORDER BY < column > DESC;
)
WHERE ROWNUM <= 5;
- The
ORDER BY
applies after theLIMIT
(MySQL command), so a sub-query is necessary to get the correct rows.
Used in conjunction with the SELECT
and ORDER BY` clauses to limit the rows and
retrieve a portion of the returning rows.
[OFFSET rows_to_skip ROW[S]]
FETCH [FIRST|NEXT] [row_count | percent PERCENT] ROW[S] [ONLY | WITH TIES];
OFFSET
(Specifies the number of rows to skip before the row limit starts).- If you put 5, then it will skip the first 5 rows and start at row 6.
- If a negative number is given, it will consider it as 0.
- If the number is
NULL
or greater than the amount of rows there are, no row is returned. - If a decimal is given, the fractional part of the number is ignored.
ROW | ROWS
(Both of them can be used based on the returning rows in order to increase the semantic clarity).- Either can be used. It's just for semantics and readability. There's no difference.
FETCH
(Specifies the number of rows or percentage of rows to return).FIRST | NEXT
(You can use either based on the situation, to increase semantic clarity).row_count | percent PERCENT
(Therow_count
specifies the number of rows to return. ThePERCENT
specifies the percentage of the total number of selected rows to return).ONLY | WITH TIES
(ONLY
is used to return exactly the specified number of rows or percentage of rows. TheWITH TIES
returns extra rows with the same value as the last row fetched).- If you specify
WITH TIES
, then you must specify theORDER BY
clause. If you don't specify theORDER BY
clause, then no additional rows will be returned.
- If you specify
-- Example 1
SELECT first_name,
last_name,
salary
FROM employees
ORDER BY salary DESC
OFFSET 1 ROW;
-- Example 2
SELECT first_name,
last_name,
salary
FROM employees
ORDER BY salary DESC
OFFSET 1 ROW FETCH FIRST 10 ROWS ONLY;
-- Example 3 (Returns NULL because the offset is NULL)
SELECT first_name,
last_name,
salary
FROM employees
ORDER BY salary DESC
OFFSET NULL ROW FETCH FIRST 15 ROWS only;
Placeholders in a SQL script where you want to subsitute some values at runtime.
- Not the future of SQL.
-- For whole values
SELECT <columns>
FROM < table >
WHERE < column > = &<variable_name>;
-- For strings or dates
SELECT <columns>
FROM < table >
WHERE < column > = '&<variable_name>';
- The ampersand (&) is used before the name of the variable
- The name cannot contain a space
- Single quotes must enclose the variable name for a string or date.
- Does not save the value
- Columns, aliases, and numerical positions are all valid when giving variable values.
- Multiple variables can be used almost everywhere.
-
- Verification Lines are the lines that show the old and new values in SQLPlus.
Same as the normal variable, although the value is stored for the duration in the variable name for use multiple times.
SELECT <columns>,
&&<variable_name>
FROM < table >
WHERE < column > = &<same_variable_name>;
- To reuse the variable, only one ampersand (&) is required.
- Can be very useful for checking queries with different values for testing.
- Variable must be
UNDEFINE
d for
- Can be used to display the value of a specific user variable or to display the values of all user variables.
DEF
[INE] variable_name = value;
-- Example
DEFINE
col = department_id;
SELECT employee_id,
first_name,
last_name,
&col
FROM employees
ORDER BY &col;
- Can be used in-place of ampersand (&) characters.
- Takes precedence over double-ampersand (&&) variables.
DEF
is the shorthand.
DEF
[INE];
UNDEF
[INE] variable_name;
UNDEF
is the shorthand.
The most reliable and robust method for getting input from the user is to explicitly prompt for values using the ACCEPT and PROMPT commands.
ACCEPT
<var_name> PROMPT '<prompt to display to user>';
ACCEPT
(Takes input from a user and stores it in a user variable).PROMPT
(Used to display a message to the user for supplying a brief explanation of what your script is going to accomplish).
Displays the status of the variable before and after the substitution.
SET
VERIFY ON;
SET
VERIFY OFF;
-- Example
SET
VERIFY ON;
SELECT employee_id,
first_name,
last_name
FROM employees
WHERE employee_id = &emp_id;
- Make sure to run script rather than query (F5 instead of F9) to see the result.
Turns off variable defining. Will use any ampersands (&) as normal ones.
SET
DEFINE ON;
SET
DEFINE OFF;
SET
VERIFY OFF;
SELECT *
FROM departments
WHERE department_name = 'R\&D';
SET
DEFINE OFF;
- Functions must be created before calling them
- Single-Row Functions
- Takes in one input, and returns one output.
- Returns a single value per row
- Can be used alone, or nested
- The type returned and accepted for the parameter is strongly typed.
- Can be used in
SELECT
,ORDER BY
,WHERE
, etc. - Types of single-row functions:
- Character
- Numeric
- Date
- Conversion
- General
- Takes in one input, and returns one output.
- Multiple-Row Functions
- Group Functions
- Takes in multiple rows of input, and returns one output.
Accept and return character or numeric data as input / output
UPPER
(Converts all input characters to uppercase characters).LOWER
(Converts all input characters to lowercase characters).INITCAP
(Converts first letters of each word to uppercase, and the rest of them to lowercase).
Case Conversion Functions | Result |
---|---|
LOWER('Adam SMITH') |
adam smith |
UPPER('Adam SMITH') |
ADAM SMITH |
INITCAP('Adam SMITH') |
Adam Smith |
- If a non-alphabetic character is given, it will not be affected.
SUBSTR
LENGTH
CONCAT
INSTR
TRIM
LPAD | RPAD
Character Manipulation Functions Syntax | Example | Result |
---|---|---|
SUBSTR(source_string, position[, length]) |
SUBSTR('Sql Course', 1, 3) |
Sql |
LENGTH(string) |
LENGTH('Sql Course') |
10 |
CONCAT(string1, string2) |
CONCAT('Sql', 'Course') |
SqlCourse |
INSTR(string, substring[,position, occurrence]) |
INSTR('Sql Course', 'o') |
6 |
TRIM([[LEADING / TRAILING / BOTH] trim_character FROM] string) ('Sql Course') |
TRIM(' Sql Course ') |
Sql Course |
LTRIM(string, [trim_string]) |
LTRIM(' Sql Course ') |
Sql Course _ |
RTRIM(string, [trim_string]) |
RTRIM(' Sql Course ') |
_ Sql Course |
REPLACE(string, str_to_replace[, replacement_string]) |
REPLACE('Sql Course', 's', '*') |
Sql Cour*e |
LPAD(string, target_length, padding_expression) |
LPAD('Sql', 10, '-') |
----------Sql |
RPAD(string, target_length, padding_expression) |
RPAD('Sql', 10, '-') |
Sql---------- |
CONCAT
only accepts two parameters in Oracle DB.INSTR
position
is the index of where it should start searching from- Also accepts negative index. However, it will start searching backwards from there.
occurrence
is which found occurrence of thesubstring
it should return.
TRIM
- Is set to
BOTH
by default. - A space ( ) is the default character to trim. If another is specified,
then
FROM
must be specified after. - Should only have on character
- Is set to
SQL Element | Category | Description | Example |
---|---|---|---|
REGEXP_LIKE |
Condition |
Searches a character column for a pattern. Use this function in the WHERE clause of a query to return rows matching a regular expression. The condition is also valid in a constraint or as a PL/SQL function returning a boolean. The following WHERE clause filters employees with a first name of Steven or Stephen: |
WHERE REGEXP_LIKE(first_name, '^Ste(ph)en$') |
REGEXP_REPLACE |
Function |
Searches for a pattern in a character column and replaces each occurrence of that pattern with the specified string. The following function puts a space after each character in the country_name column: |
REGEXP_REPLACE(country_name, '(.)', '\1 ') |
REGEXP_INSTR |
Function |
Searches a string for a given occurrence of a regular expression pattern and returns an integer indicating the position in the string where the match is found. You specify which occurrence you want to find and the start position. For example, the following performs a boolean test for a valid email address in the email column: |
REGEXP_INSTR(email, '\w+@\w+(\.\w+)+') > 0 |
REGEXP_SUBSTR |
Function |
Returns the substring matching the regular expression pattern that you specify. The following function uses the x flag to match the first string by ignoring spaces in the regular expression: |
REGEXP_SUBSTR('oracle', 'o r a c l e', 1, 1, 'x') |
SELECT REGEXP_REPLACE(first_name, '^([aA])', 'BB') replaced_output,
first_name
FROM employees
ORDER BY replaced_output
OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;
Accept numeric values as the input, and return numeric values as the output.
ROUND
(Takes in a number and rounds it to the specified number of decimal places)TRUNC
(Truncates values to the specified number of decimal places)- Truncates to a whole number by default
CEIL
(Return the smallest integer number greater than or equal to a specified number)FLOOR
(Returns the highest integer number less than or equal to a specified number)- Often used in place of
ROUND
- Often used in place of
MOD
(Returns the remainder of division)
Oracle Numeric Function | Example | Result |
---|---|---|
ROUND(number[, decimal]) |
ROUND(12.136, 2) |
12.14 |
TRUNC(number[, decimal]) |
TRUNC(12.136, 2) |
12.13 |
CEIL(number) |
CEIL(2.67) |
3 |
FLOOR(number) |
FLOOR(2.67) |
2 |
MOD(m, n) |
MOD(8, 5) |
3 |
- Using negatives with
ROUND
will go left instead of right.
DATE
is the main datatype used in Oracle for storing date values.
- Seven-byte number that contains:
- Century
- Year
- Month
- Day
- Hour
- Minute
- Second
- A few representations:
DD-MON-RR
DD-MM-YY
DD/MM/YYYY
- etc.
- To change the default in SQL Developer:
Tools Preferences Database NLS
- Format models for Oracle Dates
YY
(Shows the last two digits of a year)- Takes the first two digits of the current year directly
RR
(Different time format element that allos us to show 20th-century dates in the 21st century using only 2 digits)- Is smart in that it will change the year based off if it thinks you mean past, present, or future.
- The last two digits never change for both, only the first two digits change.
DATE
(The standard type that stores date values in Oracle)TIMESTAMP
(This datatype stores year, month, day, hour, minute, second, ans fractional seconds)- An extension of
DATE
.
- An extension of
TIMESTAMP WITH TIME ZONE
(This data type is the same asTIMESTAMP
, but it stores the timezone along with it)- Shows the database timezone
TIMESTAMP WITH LOCAL TIME ZONE
(This data type is similar toTIMESTAMP WITH TIME ZONE
, but the stored timezone is the database's timezone)- This timezone is converted to the local time of where the user performed the query.
If the function name includes CURRENT
, it's referring to the user. If the
function name includes SYS
, it's referring to the database.
SYSDATE
(Returns the current date and time of the OS where the Oracle database is installed)CURRENT_DATE
(Returns the current date and time of the place where the user's session is logged in from)SESSIONTIMEZONE
(Returns the time zone of the user's session)SYSTIMESTAMP
(Returns the date and time of the database)CURRENT_TIMESTAMP
(Returns current date and time from user's session)
We can add/subtract a number from a date, and the result will also be a date.
-- Adding 2 Days
SELECT SYSDATE,
SYSDATE + 2 -- Adds 2 days
FROM dual;
-- Adding 1 Hour
SELECT SYSDATE,
SYSDATE + 1 / 24
FROM dual;
-- Adding 1 minute
SELECT SYSDATE,
SYSDATE + 1 / (24 * 60)
FROM dual;
-- Example
SELECT employee_id,
hire_date,
sysdate,
TRUNC((sysdate - hire_date) / 365) worked_in_years
FROM employees
ORDER BY worked_in_years DESC;
- Subtracting 2 dates from eachother returns the number of days between those two dates.
- If you're on the last date when using
ADD_MONTHS
and add a month, it will set the day to be the last day in that month. - Oracle understands date values and ignores the delimiters between them (so long as it's not a letter).
ROUND
is usually used withMONTH
as the format.- It will round up if the day is greater than 15, else it will round down.
There are two types:
- Implicit Conversions
- The server automatically converts some data type to the required one.
- Not recommended due to problems and performance loss.
- Explicit Conversions
- Done using the conversion functions explicitly
TO_CHAR()
(Converts the number or date to theVARCHAR2
data type in the specified format model)TO_NUMBER()
TO_DATE()
TO_CHAR
(date | number, [format_model], [nls_parameter])
date | number
(Value to be converted toVARCHAR2
type. Can be a date or number)format_model
(Input value is converted to the VARCHAR2 data type in the specified format model)nls_parameter
(Specified the language for the names and abbreviations of the days and months)- E.g., Monday <-> Mon, January <-> Jan, etc.
- N ational L anguage S upport
- Default system language is used it this isn't specified
-- Example 1
SELECT first_name,
last_name,
TO_CHAR(hire_date, 'YYYY')
FROM employees
WHERE TO_CHAR(employee_id) = '100';
-- Example 2
SELECT first_name,
hire_date,
TO_CHAR(hire_date, 'YEAR-RR') formatted_date
FROM employees;
- The
format_model
is case-sensitive, returning either upper, lower, or initcap. TH
,SP
,SPTH
, andTHSP
adds the letters onto the numbers- E.g.
DDTHSP
DDTH
- E.g.
Number format Models | Meaning |
---|---|
9 | Specified the number of digits |
0 | Specified the leading or trailing zeros |
$ | Adds dollar sign |
L | Displays local currency symbol |
. | Displays a decimal point |
, | Displays comma as indicator |
If there is no digit, 9
will leave that digit blank, and 0
will fill it in
with a 0.
Converts text to a number.
TO_NUMBER
(char [, 'format_model']);
-- Example
SELECT TO_NUMBER('$5,332.33', '$99,999.00') AS formatted_number
FROM employees;
- The format model must fit the text, or it will return an error.
Converts the characters to a DATE
data type in the specified format model.
TO_DATE
(char [, 'format_model']);
-- Example
SELECT first_name,
last_name,
TO_CHAR(hire_date, 'Month Ddspth, YYYY') "Hire Date"
FROM employees
WHERE hire_date > TO_DATE('12JUN2005', 'DDMMYYYY');
NVL
NVL2
NULLIF
COALESCE
Replace a null value with a meaningful alternative
NVL
(Expression1, Expression2);
-- Example
SELECT job_id,
first_name,
last_name,
salary + salary * NVL(commission_pct, 0) as commission_pct
FROM employees
ORDER BY commission_pct
FETCH FIRST 10 ROWS
WITH TIES;
- If
Expression1
is null, then returnExpression2
. Else, returnExpression1
. - Types must be the same for both expressions.
Extends the functionality of NVL
. Allows us to replace a value when either
a null or non-null value is encountered.
NVL2
(expression1, expression2, expression3);
-- Example
SELECT job_id,
first_name,
last_name,
NVL2(commission_pct, 'has', 'has not') as commission_pct
FROM employees
ORDER BY commission_pct NULLS FIRST;
- If
expression1
isNULL
, then returnexpression2
. Else, returnexpression3
. expression1
does not have to be the same type as the other expressions.
NULLIF(expression1, expression2);
-- Example
SELECT first_name,
last_name,
LENGTH(first_name) AS len1,
LENGTH(last_name) AS len2,
NULLIF(LENGTH(first_name), LENGTH(last_name)) AS result
FROM employees
WHERE NULLIF(LENGTH(first_name), LENGTH(last_name)) IS NULL;
- Compares
expression1
andexpression2
. If they're equal, returnNULL
. else, returnexpression1
.
Improved version of the NVL
function. Accepts a list of arguments and returns
the first one that evaluates to a non-null value.
COALESCE(expression1, expression2, ..., expressionN);
-- Example
SELECT state_province,
city,
COALESCE(state_province, city)
FROM locations;
- Accepts two or more parameters
- If all specified expressions are
NULL
, returnsNULL
.- This is avoided by putting a static value as the last parameter.
- All arguments must be the same type.
CASE
DECODE
- Simple Case Expression
- Expression is stated at the beginning, and the possible results are checked in the condition parameters.
- Searched Case Expression
- The expressions are used within each condition without mentioning it at
the start of the
CASE
expression - Good for making different comparisons
- The expressions are used within each condition without mentioning it at
the start of the
- Both return
NULL
if none are true, and noELSE
block is in place.
CASE expression
WHEN comparison_expression1 THEN result_1
[WHEN comparison_expression2 THEN result_2
...
WHEN comparison_expression3 THEN result_n
ELSE result]
END;
expression
andcomparison_expression1
need to be the same data type, butresult_1
can be a different one.- All results must be the same data type.
- Commonly used one.
CASE
WHEN expression_1 = comparison_expression1 THEN result_1
WHEN expression_2 = comparison_expression2 THEN result_2
ELSE result
END;
- Different types can be used for comparison.
-- Simple Case Expression
SELECT first_name,
last_name,
job_id,
salary,
hire_date,
CASE job_id
WHEN 'ST_MAN' THEN 1.20 * salary
WHEN 'SH_MAN' THEN 1.30 * salary
WHEN 'SA_MAN' THEN 1.40 * salary
ELSE salary
END AS updated_salary
FROM employees
WHERE job_id
IN ('ST_MAN', 'SH_MAN', 'SA_MAN');
-- Searched Case Expression
SELECT first_name,
last_name,
job_id,
salary,
CASE
WHEN job_id = 'ST_CLERK' THEN salary * 1.2
WHEN job_id = 'ST_REP' THEN salary * 1.3
WHEN job_id = 'IT_PROG' THEN salary * 1.4
WHEN last_name = 'King' THEN salary * 1.4
ELSE 0
END AS updated_salary
FROM employees;
-- Subquery
SELECT first_name,
last_name,
job_id,
salary
FROM employees
WHERE (CASE
WHEN job_id = 'IT_PROG' AND salary > 5000 THEN 1
WHEN job_id = 'SA_MAN' AND salary > 10000 THEN 1
ELSE 0
END) = 1;
Specific to Oracle and is an alternative to a CASE
expression. Provides an
if-then-else logic.
CASE
is an expression whereasDECODE
is a function.
DECODE
(col | expression, search1, result1, [, search2, result2] ... [, default]);
-- Example
SELECT first_name,
last_name,
job_id,
salary,
hire_date,
DECODE(job_id, -- column to compare
'ST_MAN', salary * 1.20,
'SH_MAN', salary * 1.30,
'SA_MAN', salary * 1.40,
salary -- default value
) AS updated_salary
FROM employees
WHERE job_id
IN ('ST_MAN', 'SH_MAN', 'SA_MAN');
- The
default
value at the end is what to return as a default value. - result expressions must be the same data type.
- Search expressions must be the same data type.
- Group functions are known as:
- Multiple-Row Functions
- Aggregate Functions
SELECT group_function([DISTINCT | ALL] column_name), ...
FROM < table > [
WHERE condition];
- Operator on multiple rows and return one result for each group
- Uses all the returned rows of
column_name
- Uses all the returned rows of
- Usually used after the
SELECT
keyword. - Multiple group functions can be used in a
SELECT
statement - Group functions ignore
NULL
values, but you can useNVL
,NVL2
,COALESCE
,DECODE
, orCASE
expressions to handleNULL
values ALL
is the default keyword.- All group functions return
NULL
by default. - If a group function is used in a query, then all columns must be in a group function.
AVG
(Returns the average value)COUNT
(Returns the number of rows returned by a query)MAX
(Returns the maximum value of the expression or a column)MIN
(Returns the minimum value of the expression or a column)SUM
(Returns the sum of the expression or column values)LISTAGG
(Transforms and orders data from the multiple rows into a single list of values separated by a specified delimiter)
Returns the number of rows returned by a query
COUNT([DISTINCT | ALL] expression)
- When using an asterisk with
COUNT(*)
, allNULL
values are included.- When a column is given instead, all
NULL
values are ignored.
- When a column is given instead, all
SELECT COUNT(*),
COUNT(manager_id),
COUNT(ALL manager_id),
COUNT(DISTINCT manager_id)
FROM employees;
Used for getting the sum of the column or expression you provide it with.
SUM([ALL | DISTINCT] expression);
SELECT SUM(salary),
SUM(DISTINCT salary)
FROM employees;
- Used exclusively with numeric data.
Used to aggregate strings from data in columns in a table.
- Similar to
CONCAT
, but allows grouping- Concat values from separate rows into a single value
- Transforms data from multiple rows into a single list of values separated by a specified delimiter.
LISTAGG
(column_name [, delimiter]) WITHIN GROUP (ORDER BY sort_expression);
-- Example1
SELECT LISTAGG(first_name, ', ')
WITHIN GROUP (ORDER BY first_name) AS employees
FROM employees
WHERE job_id = 'ST_CLERK';
-- Example2
SELECT LISTAGG(DISTINCT salary, ', ')
WITHIN GROUP (ORDER BY salary DESC) AS employees
FROM employees
WHERE job_id = 'ST_CLERK';
-- Example 3
WITHIN GROUP
must be with the(ORDER BY)
clause, but this entire section is optional if you don't need the results ordered.
Order | Clause | Function |
---|---|---|
1 | from | Chooise and join tables to get base data |
2 | where | Filters the base data |
3 | group by | Aggregates the base data |
4 | having | Filters the aggregated data |
5 | select | Returns the final data |
6 | order by | Sorts the final data |
SELECT expression1,
expression2, ..., expression_n,
aggregate_function(aggregate_expression)
FROM < table >
[
WHERE condition]
GROUP BY expression 1, expression 2, ..., expression_n
[
ORDER BY order_expression];
- The columns that are not encapsulated in the
aggregate_function
must be written in theGROUP BY
clause.- We don't need to use all the columns in the
GROUP BY
clause though.
- We don't need to use all the columns in the
- Column aliases cannot be used with the
GROUP_BY
clause. - The
ORDER BY
clause cannot have any other individual columns than theGROUP BY
clause has.
- Splits the rows into smaller groups and applies the group functions to each individually.
SELECT job_id,
department_id,
ROUND(AVG(salary), 2),
COUNT(*)
FROM employees
GROUP BY job_id,
department_id
ORDER BY AVG(salary);
HAVING
filters grouped data, while the WHERE
clause filters rows.
SELECT < column >,
group_function
from < table >
[
WHERE condition]
[
GROUP BY group_by_expression]
[
HAVING group_condition]
[
ORDER BY column];
-- Example
SELECT job_id,
AVG(salary)
FROM employees
GROUP BY job_id
HAVING AVG(salary) > 10000;
HAVING
can actually be used before theGROUP BY
clause, but it's not recommended due to readability.
SELECT MAX(AVG(salary))
FROM employees
GROUP BY department_id;
- Group Functions can be nested to a depth of 2.
- To use a nested multi-row function, you need to have a
GROUP BY
clause.
- Normalization (The process of decreasing data redundancy by using keys and storing only specific information in a table)
- Create Payouts Table
- An ambiguous reference is when a join is performed on two tables that have the same column names in them.
- Table aliases are used for handling column ambiguity when joining two or more
tables.
- Increase code readability and query performance
- If all table names are changed, the aliases will not need to be
- We cannot give aliases to columns that we use with the
USING
clause orNATURAL JOIN
SELECT first_name,
last_name,
department_name,
d.manager_id
FROM employees e
JOIN departments d
USING (departments_id);
A join is a concept that allows us to retrieve data from two or more tables in a single query.
SELECT columns
FROM table1 JOIN_TYPE table2
ON table1.column_name = table2.column_name;
- Natural Join
- Inner Join
- Outer Join
- Left Outer Join
- Right Outer Join
- Full Outer Join
- Equijoin
- Non-Equijoin
- Self Join
- Cross Join (Cartesian Product)
Implicitly joins two tables based on common columns that have the same name and same data type.
SELECT *
FROM table1
NATURAL JOIN table2;
- The rows are matched with each other from two tables that have equal values in the common columns.
- If common columns have the same name but different types of data, it throws an error.
WHERE
can be used to restrict data- Joined columns come first in the output, and are only written once.
When joining two tables, if there are more than one common columns that have the
same names, we can use the USING
clause to specify which column needs to be
selected as the join column in the join operation.
SELECT <columns>
FROM table1
JOIN table2
USING (column_in_both_tables [, column_in_both_tables]);
- The
USING
clause is used for matching a specific column or columns when joining two tables. - Joining with the
USING
clause is considered as Equijoin.- When the columns must have equal values
Returns all rows from both participating tables that satisfy the join condition
or the expression of the ON/USING
clause.
SELECT columns
FROM table1 [INNER] JOIN table2
ON (join_condition) / USING (column_name)
-- Example1
SELECT e.first_name,
e.last_name,
d.manager_id,
d.department_id
FROM employees e
INNER JOIN departments d
ON (e.department_id = d.department_id AND e.manager_id = d.manager_id);
-- Example2
SELECT e.first_name,
e.last_name,
manager_id,
department_id
FROM employees e
JOIN departments d
USING (department_id, manager_id);
- With the
ON
clause, we can write one or more join conditions even if they have different names. Only rows that satisfy these join conditions are included in the result set. - The
USING
clause requires the columns to be the same name, where theON
clause can have different column names.
SELECT e.first_name,
e.last_name,
d.department_name,
l.city,
l.postal_code,
l.street_address,
country_id
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
JOIN locations l
ON d.location_id = l.location_id
NATURAL JOIN countries
ORDER BY e.first_name, e.last_name
- The join order matters, because each
JOIN
result is stored in memory. The subsequentJOIN
is thenJOIN
ed with the one in memory.- Only the columns from the selected table are stored.
- If the needed column for a join is not yet joined, then the query will fail.
NATURAL JOIN
can be problematic since it doesn't know what columns to join in advance. Don't use it.
- Only the columns from the selected table are stored.
SELECT e.first_name,
e.last_name,
d.department_name,
l.city,
l.postal_code,
l.street_address,
country_id
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
JOIN locations l
ON d.location_id = l.location_id
JOIN countries
USING (country_id) [AND |
WHERE] d.department_id = 100
ORDER BY e.first_name, e.last_name
AND
orWHERE
can be used for restricting inJOIN
clauses.WHERE
can only be used once
Joining a table with itself is called a Self-Join
- Used for comparing rows in the same table or querying hierarchical data
SELECT worker.first_name,
worker.last_name,
worker.employee_id,
worker.manager_id,
manager.employee_id,
manager.first_name,
manager.last_name
FROM employees worker
JOIN employees manager
ON worker.manager_id = manager.employee_id;
If two tables do not match with columns, we can join these tables using the
BETWEEN
operator, or the comparison operators (<, >, <=, >=, <>).
SELECT e.employee_id,
e.first_name,
e.last_name,
e.job_id,
e.salary,
j.min_salary,
j.max_salary,
j.job_id
FROM employees e
JOIN jobs j
ON e.salary > j.max_salary
AND j.job_id = 'SA_REP';
SELECT e1.employee_id,
e1.first_name,
e1.last_name
FROM employees e1
JOIN employees e2
ON e1.employee_id != employee_id
AND e1.first_name = e2.first_name;
Returns the matching rows from the joined tables, plus unmatched rows from one or both tables.
- Very commonly used in real work, as the
JOIN
table is considered extra information, and often they want to see the actual table in any case.- An entire row is left out if even one piece of data is
NULL
- An entire row is left out if even one piece of data is
- There are three types of outer joins:
LEFT OUTER JOIN
RIGHT OUTER JOIN
FULL OUTER JOIN
Returns the matching rows from the joined tables, plus unmatched rows from the
left table. For the unmatched rows, the values are shown as NULL
for the other
table.
- The
OUTER
is optional.
Returns the matching rows from the joined tables, plus unmatched rows from the
right table. For the unmatched rows, the values are shown as NULL
for the other
table.
- The
OUTER
is optional.
Retrieves all rows from both tables. If a match is found, it displays the
row. If not, it displays NULL
for the other tables row.
SELECT e.first_name,
e.last_name,
d.department_name
FROM employees e
FULL OUTER JOIN departments d
ON (e.department_id = d.department_id);
- The combination of the
LEFT
andRIGHT
joins. - The
OUTER
is optional
Cross joins are used to return every combination of rows from two tables.
- Cross joins happen if you don't specify a
JOIN
between two tables, usually by accident.- Often happens if you use Oracle's old syntax.
- Can become exceedingly large when dealing with large tables.
- Generally used for performance testing or in DBA responsibilities.
SELECT e.first_name,
e.last_name,
e.department_id,
d.department_id,
d.department_name,
j.job_title
FROM employees e
CROSS JOIN departments d
CROSS JOIN jobs j;
SELECT *
FROM employees,
departments;
- Oracle's old syntax
SELECT e.first_name,
e.last_name,
d.department_name
FROM employees e,
departments d
WHERE e.department_id = d.department_id
AND d.department_name = 'Finance';
- In the older syntax,
WHERE
can also use all theJOIN
clauses. - The older syntax is error-prone
-- LEFT OUTER JOIN
SELECT e.first_name,
e.last_name,
d.department_name
FROM employees e,
departments d
WHERE e.department_id = d.department_id(+);
-- RIGHT OUTER JOIN
SELECT e.first_name,
e.last_name,
d.department_name
FROM employees e,
departments d
WHERE e.department_id(+) = d.department_id;
- A (+) is added to whichever table is optional.
- In this scenario, it's a
LEFT
join.
- In this scenario, it's a
SELECT e.first_name,
e.last_name,
d.department_name
FROM employees e,
departments d
WHERE e.department_id(+) = d.department_id;
UNION
SELECT e.first_name,
e.last_name,
d.department_name
FROM employees e,
departments d
WHERE e.department_id = d.department_id(+);
- Syntax Differences
- Equijoin and Non-Equijoin describe join conditions
- How tables are joined and how rows are matched
INNER JOIN
andOUTER JOIN
specify what to do with rows that do not satisfy the join condition.
- Use the ANSI syntax
- Don't use the
NATURAL JOIN
s - Use table aliases for a sustainable query
- Decide what you need
- Do you need only the matched rows or not?
- If you need the unmatched rows too, use an
OUTER JOIN
. - Do you need the matched rows and the unmatched rows from one table, or both tables?
- Use the Equijoins if you want to get only the rows which equally match with the join conditions.
- Use the Non-Equijoin if you want to get the rows which don't match equally.
- Use the Self Join if you want to join different rows of the same table
- Use the Cross Join if you need to generate massive amounts of data.
There are three types of the Entity-relationship (data) models
- One-To-Many - Many-To-One
- One-To-One
- Many-To-Many
Most used relationship. When one object from one table relates to many objects from another table.
- A department can have many employees, but an employee cannot have many departments.
- A One-to-Many does not need to have many each time. i.e., One customer does not need to have many orders. The important part is that it can have many.
If each row in the first table is joined with one row from the second table, there is a one-to-one relationship.
- Not used often.
- I.e., Students and Classes table. A student can have many classes, and a class can have many students.
Sits between a Many-To-Many table to join the tables.
- The convention is to name it the combination of the tables it's joining.
- A Students and Classes table would be Students_Classes.
There are 3 types of subqueries:
- Single-Row Subqueries
- Multiple-Row Subqueries
- Multiple-Column Subqueries
Return single rows and are used with single-row operators (<, >, =, <>, >=, <=)
SELECT *
FROM employees
WHERE department_id = (SELECT department_id
FROM employees
WHERE employee_id = 145);
- Group functions can be used within single row queries
- If a single-row subquery returns multiple-rows, it generates an error.
- If a subquery returns nothing or a
NULL
value, the main query will return nothing.
Return more than one row from the inner queries
IN
- Most commonly used
- Checks whether a value matches any values in a subquery
ANY
- Checks whether a value matches at least one in a subquery
ALL
- Checks whether a value matches all in a subquery
- Does not work with single-row operators
SELECT first_name,
last_name,
department_id,
salary
FROM employees
WHERE salary IN (SELECT MIN(salary)
FROM employees
GROUP BY department_id)
ORDER BY salary;
- Used with single-row operators
SELECT first_name,
last_name,
department_id,
salary
FROM employees
WHERE salary > ANY (SELECT salary
FROM employees
WHERE job_id = 'SA_MAN')
ORDER BY salary;
In multiple-row subqueries it's used to return values which provide the condition with all elements of the inner query.
- Used with single-row operators
- < means less than the maximum
- > means more than the maximum
- The = is not used as it means nothing if there are more than one records.
SELECT first_name,
last_name,
department_id,
salary
FROM employees
WHERE salary < ALL (SELECT salary
FROM employees
WHERE job_id = 'SA_MAN')
ORDER BY salary;
Return more than one column to the outer query
- Useful when you need more than one inner query in one outer query
- Usually used with
IN
andNOT IN
operators.
- Non-pairwise Comparison Subquery
- Pairwise Comparison Subquery
Like multiple-row subqueries with the IN
operator, that we check multiple
column values with separate subqueries.
SELECT employee_id,
first_name,
last_name,
salary
FROM employees
WHERE department_id IN
(SELECT department_id
FROM employees
WHERE employee_id IN (103, 105, 110))
AND salary IN
(SELECT salary
FROM employees
WHERE employee_id IN (103, 105, 110));
- Each column is compared with a separate subquery
SELECT employee_id,
first_name,
last_name,
salary
FROM employees
WHERE (department_id, salary) IN
(SELECT department_id,
MAX(salary)
FROM employees
GROUP BY department_id);
IN
ignores null values, so anyone without a department_id would be skipped without doing a pairwise-comparison.- If a pairwise-comparison only returns one row, it's still a single-row subquery.
- INLINE Views do not have to have one table, they can be joined.
SELECT e.employee_id,
e.first_name,
e.last_name,
b.department_name,
b.city,
b.state_province
FROM employees e
JOIN (SELECT department_id,
department_name,
state_province,
city
FROM departments
JOIN locations
USING (location_id)
ORDER BY department_id) b
USING (department_id)
;
If a subquery returns only one column for one row, it's a Scalar Subquery.
SELECT employee_id,
first_name,
last_name,
FROM employees
WHERE department_id =
(SELECT department_id
FROM employees
WHERE UPPER(first_name) = 'LUIS');
SELECT employee_id,
first_name,
last_name,
(CASE
WHEN location_id =
(SELECT location_id
FROM locations
WHERE postal_code = '99236') THEN 'San Francisco'
ELSE 'other'
END) city
FROM employees
NATURAL JOIN departments;
- If a scalar subquery returns
NULL
or 0 rows, the main query will return nothing. - If a scalar subquery returns more than 1 row, the main query will return an error.
- Scalar subqueries can be used in:
SELECT
statementsDECODE
function andCASE
expressionsWHERE
clausesSET
clauses ofUPDATE
statementsVALUES
clauses ofINSERT
statementsORDER BY
clauses
- Scalar subqueries are cached and reused if called more than once. Great for performance.
- Called Selecting a Select.
- If more than one row is returned from the subquery, use
IN
instead of=
.
When a subquery references to the columns from the parent query, it is called a correlated subquery.
-- Example 1
SELECT employee_id,
first_name,
last_name,
department_id,
salary
FROM employees a
WHERE (salary, department_id) IN
(SELECT MAX(salary),
department_id
FROM employees b
WHERE b.department_id = a.department_id
GROUP BY department_id);
-- Example 2
SELECT employee_id,
first_name,
last_name,
a.department_id,
salary
FROM employees a
JOIN
(SELECT AVG(salary) avg_sal,
department_id
FROM employees
GROUP BY department_id) b
ON (a.department_id = b.department_id)
WHERE a.salary < b.avg_sal;
- Correlated subqueries allow us to read every row in a table and compare values
for each row against the related data.
- In regular subqueries, they are executed first and the result of the subqueries are passed bqack to the parent query.
- In correlated subqueries, the subquery is executed again and again for every row in the parent query.
- Correlated subqueries can use single-row and multi-row operators.
- Aka a repeating subquery or synchronized subquery.
- These queries are slow, and using a
JOIN
often performs better.
Uses to check the existence of rows in the subquery and match the records between the subquery and main query.
SELECT employee_id,
first_name,
last_name,
department_id
FROM employees a
WHERE EXISTS
(SELECT NULL
FROM employees
WHERE manager_id = a.employee_id);
- Generally used with the correlated subqueries.
- Terminates the processing of the subquery once the subquery returns the first row.
- The subquery does not need to return a specific type of value. It can be a
constant, a
NULL
, or a column value.- The subquery can also return more than one row.
- Returning
NULL
is better for performance when usingEXISTS
, but does not work withIN
.
A semijoin between two tables returns rows that match an EXISTS
or IN
subquery without duplicating the rows of the main query even when there are
multiple matches from the subquery.
- An
EXISTS
or Subquery is a semijoin.
Negation format of the EXISTS
operator.
SELECT department_id,
department_name
FROM departments d
WHERE NOT EXISTS
(SELECT department_id
FROM employees
WHERE department_id = d.department_id);
- Using
NOT IN
can give unexpected behavior, so useNOT EXISTS
instead.
SET operators return the results of two or more queries and return as one result.
SELECT column1, column2, ..., column_n
FROM table1
SET_OPERATOR
SELECT column1, column2, ..., column_n
FROM table2
SET_OPERATOR
SELECT column1, column2, ..., column_n
FROM table_n;
UNION
(Returns all rows of both queries by eliminating duplicate rows)UNION ALL
(Returns all rows of both queries including duplicates)INTERSECT
(Returns common rows of both queries)MINUS
(Returns unique rows of first query)- Shows results that only exist in the first query.
- Queries using the
SET
operators are called Compound Queries. - All
SET
operators have eqaul precedence, except forINTERSECT
which is higher.- Executed from top to bottom.
- Use parenthesis to change execution order.
- The numbers of columns or expressions in queries must match.
- The data types must match as well.
- The
ORDER BY
clause can only be used once at the end of the last query. - Duplicate rows are eliminated automatically in all
SET
operators except for theUNION ALL
. - Column headings come from the first query.
JOINS combine columns, and SET operators combine rows.
- If you have Table A and Table B and use a
JOIN
, then you get all the columns from both tables. - If you have Table A and Table B and use a SET operator, then you get all the rows from both tables under the columns from Table A.
Returns all rows of both queries by eliminating duplicate rows
Code for table: Code
- The
SELECT
order of the columns needs to be the same for both queries.
Returns all rows of both queries including duplicates
Returns common rows of both queries
Returns distinct rows from the first query that are not returned by the second query.
- All duplicates are eliminated, not just ones that exist in both tables.
NULL
values can be used to combine queries that do not have the same number of
columns.
SELECT job_id,
department_id,
first_name,
last_name
FROM employees
UNION ALL
SELECT job_id,
department_id,
NULL,
NULL
FROM job_history;
Used only once at the end of the compound query.
SELECT first_name,
last_name,
salary s,
department_id
FROM employees
UNION ALL
SELECT first_name,
last_name,
salary s,
department_id
FROM employees
WHERE department_id = 30
UNION
SELECT first_name,
last_name,
salary s,
department_id
FROM retired_employees
ORDER BY s;
- It recognizes the column aliases only in the first query when there's only
two queries.
- If there's more than 2 queries, the alias must be re-written for all queries except the last one.
- DDL commands create, modify, and maintain the database objects in the
database.
- They are always auto-committed.
CREATE
(Creates database objects in the database)ALTER
(Modifies the structure of the database and its objects)- Can modify almost anything
DROP
(Deletes objects from the database)TRUNCATE
(Removes all data from a table, including all space allocated for the removed rows)- Cannot be rolled back
COMMENT
(Adds explanatory comments to the table and its columns)RENAME
(Renames an existing object)
- Must start with a letter
- Can only contain A-Z, a-z, 0-9, _, $, #
- Can be up to 128 characters in length
- Tablespace Names and Pluggable Database Names can only be up to 30.
- Cannot have the same name as another existing object in the same schema
- Cannot have more than one column with the same name either.
- Quoted identifiers allow mixed case, but this is not recommended.
- Column names are capitalized by default
- Cannot be a reserved word.
- Table names should be in plural form.
- If a table has more than one word, they should be separated by an underscore (snake case).
- Column names should include the alias of the related table underscore the
column name.
- i.g.,
adr_street
,usr_first_name
- i.g.,
- Column names should be singular
- The primary key columns names should end with "_ID"
- The logical aliases of both tables should be used while naming a foreign key column.
- To create a table, you must have the CREATE TABLE privilege.
- Up to 1,000 columns can be created per table.
CREATE TABLE schema_name.table_name
(
column_name_1 datatype [ DEFAULT default_value] [NULL | NOT NULL],
column_name_2 datatype [ DEFAULT default_value] [NULL | NOT NULL],
column_name_3 datatype [ DEFAULT default_value] [NULL | NOT NULL], .
.
.
);
- The
schema_name
is optional. If not specified, the table will be created under the current schema. - If
NULL
is specified, it means that it can have a null value, not that it will.NULL
is the default if not specified.
DEFAULT default_value
sets the default value for the column.
A table can be created using queries and populated with the rows returned by the specified query.
- Great for creating test tables without affecting the main one.
CREATE TABLE table_name[
(
column1,
column2
.
.
.
)]
AS select_query;
-- Example
CREATE TABLE employees_copy
AS
SELECT *
FROM employees;
-- Copying a table's structure without the data
CREATE TABLE employees_copy
AS (SELECT *
FROM employees
WHERE 1 = 2);
- The column names are optional if you want to have the same column names as the original table.
- While creating a table from a
SELECT
query, the only constraints that are inherited are theNOT NULL
constraints.
Column names can be defined differently from the SELECT
list while creating a
table:
CREATE TABLE employees_copy(name, surname, annual_salary)
AS
SELECT first_name, last_name, 12 * salary
FROM employees;
- The number of specified columns must match the number of columns in the
SELECT
list.
Changes the structure of an existing table. A few possible commands:
- Add one or more new columns to a table.
- Modify the datat type of one or more existing columns.
- Drop one or more columns from a table.
- Rename a column or a table.
- Much more...
ALTER TABLE < table_name >
ADD (column_name_1 datatype [DEFAULT default_value] [NULL | NOT NULL],
column_name_2 datatype [DEFAULT default_value] [NULL | NOT NULL],
column_name_3 datatype [DEFAULT default_value] [NULL | NOT NULL],
...);
-- Example
ALTER TABLE employees_copy
ADD (fax_number VARCHAR2(11),
date_of_birth DATE,
password VARCHAR2(10) DEFAULT '@123abC');
ALTER TABLE table_name
MODIFY (column_name_1 datatype [ DEFAULT default_value] [NULL | NOT NULL],
column_name_2 datatype [ DEFAULT default_value] [NULL | NOT NULL],
column_name_3 datatype [ DEFAULT default_value] [NULL | NOT NULL], ...);
- The most common use for
MODIFY
is to increase the size of aVARCHAR2
column to allow for more space. - A column will keep the same
DEFAULT
unless modified. The new data will be put in to new entries only.- Set it to
NULL
to delete the existing one if desired.
- Set it to
ALTER TABLE table_name
DROP
COLUMN column_name;
ALTER TABLE table_name
DROP
(column_name1[, column_name2, ...]);
The SET UNUSED
clause is used to mark one or more columns as unused.
- When there's billions of values in a column, it may be faster to set a column as unused.
- As soon as columns are marked as unused, those columns are dropped logically by
becoming invisible and inaccessible.
- The column will still be on the disk physically, and can be dropped physically during off-peak hours.
ALTER TABLE table_name
SET UNUSED COLUMN column_name;
ALTER TABLE table_name
SET UNUSED (column_name1[, column_name2,...]);
ALTER TABLE table_name
SET UNUSED (column_name1[, column_name2,...]) ONLINE;
- The
ONLINE
keyword at the end of theSET UNUSED
clause can be used to indicate that DML operations are allowed on the table while marking columns as unused.
ALTER TABLE table_name
DROP
UNUSED COLUMNS;
SELECT *
FROM user_unused_col_tabs;
user_unused_col_tabs
shows allUNUSED
columns.
- A read-only table can still be dropped.
Some use-cases:
- We need to do maintenance on some tables. During these times, we may want to prevent any DML operations and certain DDL statements that affect the data on those tables against any accidental changes.
ALTER TABLE table_name READ ONLY;
READ ONLY
is added to the end of the table to make it read-only.
ALTER TABLE table_name READ WRITE;
READ WRITE
restores access to the table for writing operations.
Removes an existing table with all its data from the database and moves it to the recycling bin.
DROP TABLE table_name [PURGE];
PURGE
removes the table and all its dependent objects permanently, skipping the recycling bin and making them unable to be recovered.- To restore a table from the recycling bin:
-
FLASHBACK TABLE table_name TO BEFORE DROP;
- You need to be a DBA, System Admin, or table creator to use `FLASHBACK`.
-
- After dropping a table, all the objects related to that table will also be deleted or become invalid.
- The recycle bin has a limit, and tables outside that limit will be deleted.
The DELETE
statement deletes all data row by row whereas the TRUNCATE
statement deletes all rows from a table more quickly.
DELETE
FROM table_name; -- Deletes all data row by row (slow)
TRUNCATE TABLE [schema_name.] table_name; -- Deletes all rows at once (faster)
TRUNCATE
does not delete the table.TRUNCATE
statement is one of the DDL statements so it will auto-commit changes immediately after removing data.- Does not allow rollback.
- Does not generate any undo information or log data, so it cannot be easily restored.
- DDL commands auto-commit after they're done.
Adds an explanation to a table or column.
-- Commenting a column
COMMENT
ON COLUMN table_name.column_name IS 'comment';
-- Commenting a table
COMMENT
ON TABLE table_name IS 'comment';
- We cannot drop a comment, so instead we create a new comment with an empty string.
- To query comments:
user_tab_comments
anduser_col_comments
Used to change the name of an existing column or table
-- Rename column
ALTER TABLE table_name RENAME COLUMN column_name TO new_column_name;
-- Rename table
-- Syntax 1
RENAME
table_name TO new_table_name;
-- Syntax 2
ALTER TABLE table_name RENAME TO new_table_name
- The DML statements are:
INSERT
(Add new rows into a table)UPDATE
(Update existing rows in a table)DELETE
(Can remove data from a table)MERGE
(Can perform all 3 of the above at the same time, based on specified conditions)
- Other users will not see your DML statements until you commit them.
A collection of DML statements
- Databases use transactions that must be completed in full. If one DML statement fails, then they all fail.
- Used for data integrity, security, & consistency
Adds one or more new rows into a table.
INSERT INTO table(column1, column2, ..., column_n)
VALUES (value1, value2, ..., value_n)
- Not all columns have to be specified, only the ones you want to fill when adding a row.
- Specifying the column names is optional for
table
, although it's recommended to as the order can be mixed up and incorrect data will be inserted.
INSERT INTO jobs_copy
VALUES ('DATA_ENG2', 'Data Engineer2', NULL, NULL);
NULL
can be used as a placeholder.- Using
NULL
will prevent theDEFAULT
value form being used.
INSERT INTO jobs_copy
VALUES ('DATA_ARCH4', UPPER('DAta Architecture4'), 8000, NULL);
- Mulit-Row functions cannot be used
INSERT INTO target_table(col1, col2, col3, ...)
SELECT (col1, col2, col3, . . .)
FROM source_table;
- The data types and column amount must match.
source_table
is where the data comes from.- It's good to run
SELECT
standalone first to make sure that it will return the correct data before it's inserted. - The column list is optional for both:
-
INSERT INTO employees_copy SELECT * FROM employees;
-
The INSERT ALL
statement is used to insert multiple rows into a table or
multiple tables.
INSERT
ALL
INTO table_name1 VALUES (val1, val2, val3, ...)
INTO table_name2(col1, col2, col3) VALUES (val4, val5, val6, ...)
INTO table_name3(col1, col2, col3, ...) VALUES (val7, val8, val9, ...)
...
Subquery;
-- Example
INSERT
ALL
INTO employees_history VALUES (
employee_id,
first_name,
last_name,
hire_date)
INTO salary_history VALUES(
employee_id,
EXTRACT(year FROM sysdate),
EXTRACT(month FROM sysdate),
salary,
commission_pct)
SELECT *
FROM employees
WHERE hire_date > TO_DATE('15-MAR-08');
- Increases performance and saves time.
- Each row returned by the subquery is inserted into each of the target tables
using the Unconditional
INSERT ALL
statement. - If you need to insert hard-coded values, it's better to subquery from
dual
. - The insert order is not guaranteed, and is not top to bottom.
- Unconditional Insert Statements
- Conditional Insert Statements
- Conditional Insert ALL Statements
- Conditional Insert FIRST Statements
INSERT
ALL
INTO employees_history VALUES(
employee_id,
first_name,
last_name,
hire_date)
INTO salary_history VALUES(
employee_id,
EXTRACT(year FROM sysdate),
EXTRACT(month FROM sysdate),
salary,
commission_pct)
SELECT *
FROM employees
WHERE hire_date > '15-MAR-08';
INSERT
ALL
WHEN Condition1 THEN
INTO Insert_satetement_1
INTO Insert_satetement_2
...
WHEN Condition2 THEN
INTO Insert_Statement_3
...
ELSE
INTO Insert_statement_n
Subquery;
- All
WHEN
conditions are evaluated regardless of the results of any otherWHEN
clause.
INSERT
FIRST
WHEN Condition1 THEN
INTO Insert_satetement_1
INTO Insert_satetement_2
...
WHEN Condition2 THEN
INTO Insert_Statement_3
...
ELSE
INTO Insert_statement_n
Subquery;
- Uses
IF-THEN-ELSE
logic.- When a condition is found that is satisfied, the subsequent statements are skipped.
Used for converting non-relational data to a relational format and inserting it into a relational table.
- An unconditional
INSERT ALL
statement can also be used for pivoting data.
- Can not be used on views or materialized views.
- Cannot be used to insert data into remote tables.
- The number of columns in all the INSERT INTO clauses must not exceed 999.
- A Table collection expression cannot be used in a multitable insert statement.
- The subquery of the multitable insert statement cannot use a sequence.
UDPATE
table
SET column = value [, column2 = value, ...]
[WHERE condition(s)];
-- Example
UPDATE employees_copy
SET salary = 50000,
department_id = NULL
WHERE job_id = 'IT_PROG';
A subquery must be used to update multiple columns at once.
UPDATE employees_copy
SET (salary, commission_pct) = (SELECT MAX(salary),
MAX(commission_pct)
FROM employees)
WHERE job_id = 'IT_PROG';
Used to delete one or more rows from a table.
DELETE
[FROM] TABLE
[WHERE condition];
Used to INSERT
new records, UPDATE
or DELETE
existing ones depending on
the specified conditions at the same time.
- Optimized for merging sets of data.
- Faster than the individual DML statements being used independently.
MERGE INTO taget_table target_alias
USING (source_table|view|subquery) source_alias
ON (join_condition)
WHEN MATCHED THEN
UPDATE SET
column_name1 = value1,
column_name2 = value2,
...
[WHERE <
update condition>]
[
DELETE
WHERE <
delete condition >]
WHEN NOT MATCHED THEN
iNSERT
(
columns
)
VALUES (values)
[
WHERE <
insert
condition
>
];
-- Example
MERGE INTO employees_copy c
USING (SELECT *
FROM employees) e
ON (c.employee_id = e.employee_id)
WHEN MATCHED THEN
UPDATE SET c.first_name = e.first_name,
c.last_name = e.last_name,
c.department_id = e.department_id,
c.job_id = e.job_id,
c.salary = e.salary
DELETE
WHERE department_id IS NULL WHEN NOT MATCHED THEN
INSERT
VALUES (
e.employee_id,
e.first_name,
e.last_name,
e.department_id,
e.job_id,
e.salary
);
A transaciton is a unit of work that you want to treat as a whole. It either has to happen in full or not at all.
- Used to ensure data integrity, data consistency and data security.
- When we execute a DML operation, the affected rows are locked and no one else can update or delete these rows during this lock.
- There are 3 types of TCL Statements
COMMIT
ROLLBACK
SAVEPOINT
Undoes any changes to the database and restores data to its previous state.
- Goes all the way back to the last commit (All changes made in the current transaction).
- After a commit or rollback operation, all the locked rows are released and everyone can change these rows.
- After a DDL or DCL statement, the commit will be automatically executed.
ROLLBACK;
Permanently saves the changes into the database and ends the transaction.
COMMIT;
During a DML operation, the rows are locked until a COMMIT
or ROLLBACK
occurs.
- The session will be left hanging and the ScriptRunner Task will not finish
if another user is making changes to that row.
- It will be locked until the user commits or rolls back the changes.
- Row locks are specific to individual rows.
For longer transactions, save-points are useful as they divide longer transactions into smaller parts nad mark certain points of a transaction as checkpoints.
SAVEPOINT name;
-- Rolling back to a savepoint
ROLLBACK TO [SAVEPOINT] savepoint_name;
- Saves the current state of the transaction, and we can roll back to that state.
- We can create as many save-points as we want.
- After rollback to an earlier savepoint, subsequent ones will be deleted and only the ones before it will still exist.
- Using a regular
ROLLBACK
without a save-point, orCOMMIT
, will delete all save-points. - Save-point names must be unique within a transaction.
- When using the same name, the new one will override the old one.
- Adding
SAVEPOINT
increases readability, but is optional.
DELETE
FROM employees_copy
WHERE job_id = 'IT_PROG';
SAVEPOINT A;
UPDATE employees_copy
SET salary = 1.2 * salary;
SAVEPOINT B;
INSERT INTO jobs_copy
VALUES ('PY_DEV', 'Python Developer', 12000, 20000);
SAVEPOINT C;
DELETE
FROM employees_copy
WHERE job_id = 'SA_REP';
SAVEPOINT D;
ROLLBACK TO B;
FOR UPDATE
is a locking mechanism that locks all rows returned by a query.
SELECT *
FROM employees
WHERE job_id = 'IT_PROG'
FOR UPDATE [OF column(s)] [NOWAIT | WAIT sec | SKIP LOCKED];
- It is not able to lock rows that are already locked by another session, it will wait.
- Used to deal with concurrent updates to data.
NOWAIT
tells Oracle not to wait if the rows have already been locked by another user.- If the rows are already locked by another user, Oracle will directly return an error.
SKIP LOCKED
keyword tells Oracle to skip the locked rows and operator on the available ones.- With joins, the rows from all joined tables are locked by default.
- The
OF
clause is used to indicate which tables will be locked:- In Oracle, you cannot lock a specific column in a row. The entire row is locked.
- Constraint names must be unique for the entire schema.
- Constraints restirct data entry (insert, update, delete) and prevent invalid
entries.
- They ensure data consistency and data integrity in the database.
- There are 5 constraint types:
NOT NULL
UNIQUE
PRIMARY KEY
FOREIGN KEY
CHECK
- Constraints can be at the column-level or table-level
- The functionality is the same, it's just where they're created.
- Ones created table-level are applied to multiple columns.
- By default, auto-generated constraint names start with 'SYS_C'.
- Constraint names must be unique.
CREATE TABLE managers
(
employee_id NUMBER [ CONSTRAINT constraint_name] CONSTRAINT_TYPE,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
department_id NUMBER, [
CONSTRAINT
constraint_name]
CONSTRAINT_TYPE
(
column_name1,
.
.
.
) -- Table-level
);
- There can be multiple table-level and column-level constraints
- Table-level constraints can have multiple columns in them.
Prevents the insertion of NULL
values in a column.
CREATE TABLE managers
(
employee_id NUMBER NOT NULL,
first_name VARCHAR2(50),
last_name VARCHAR2(50) CONSTRAINT lname_not_null NOT NULL,
department_id NUMBER NOT NULL
);
- Can only be created at the column-level
Ensures the uniqueness of a column or a set of columns which means no duplicate values will be inserted.
CREATE TABLE managers
(
employee_id NUMBER NOT NULL,
first_name VARCHAR2(50) UNIQUE,
last_name VARCHAR2(50) CONSTRAINT lname_uk UNIQUE,
department_id NUMBER NOT NULL,
phone_number VARCHAR2(11) UNIQUE NOT NULL,
CONSTRAINT department_uk UNIQUE (department_id),
CONSTRAINT composite_uk(employee_id, first_name, last_name) -- Composite Unique Key
);
- A
UNIQUE
column or a set of columns where the combination must be unique can have multiple null values, unless you also defineNOT NULL
constraints for those columns. UNIQUE
constraints based on multiple columns are called Composite Unique Keys.- A composite unique key can contain a maximum of 32 columns.
- Composite unique keys can only be created at the table-level.
- Oracle server creates a unique index implicitly on unique key creation.
- The easiest way to figure out the meaning of a system-named constraint in
Oracle is:
- Click the table
- Hit Shift + F4
- Go to constraints
- Click the related constraint name and look at the columns it's affecting.
CREATE TABLE managers
(
manger_id NUMBER
CONSTRAINT mgr_mid_uk UNIQUE,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
department_id NUMBER NOT NULL,
phone_number VARCHAR2(11) CONSTRAINT pnum_uk UNIQUE CONSTRAINT pnum_nn NOT NULL
);
A column or a combination of columns in a table that uniquely identifies each row in a table.
- A combination of
NOT NULL
andUNIQUE
constraints.- The
NOT NULL
constraint is automatically created on the related column(s) when creating a primary key.
- The
- There can only be one primary key on the table.
- Primary key is the unique ID of each row in a table.
- The oracle server creates a
UNIQUE
index when creating a primary key. - There are 2 types of primary keys:
- Simple Primary Key (Single Column)
- Composite Primary Key (Multiple Columns)
-- Column-level constraint
CREATE TABLE managers
(
manager_id NUMBER
CONSTRAINT pk_managers PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50)
);
-- Table-level constraint
CREATE TABLE managers
(
manager_id NUMBER,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
CONSTRAINT pk_managers PRIMARY KEY (manager_id),
);
A column or combination of columns used to enforce a relationship between a parent table and a child table.
-
The relationship is established between the parent table's primary/unique key and a column or set of columns in the child table.
-
The Foreign Key constraint is also known as the Referential Integrity constraint.
-
A referenced record must exist in the parent table before you can insert a related record into the child table.
-
- There are 2 types of Foreign keys:
- Simple Foreign Key (Single Column)
- Composite Foreign Key (Multiple Columns)
CREATE TABLE managers
(
manager_id NUMBER
CONSTRAINT pk_managers PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
department_id NUMBER
CONSTRAINT mgr_dept_id_fk REFERENCES departments (department_id),
CONSTRAINT mgr_emp_fk FOREIGN KEY (manager_id) REFERENCES employees (employee_id)
);
FOREIGN KEY
isn't used on column-level restraints, as it's obvious.- A column or group of columns can be both the
PRIMARY KEY
and theFOREIGN KEY
at the same time.- In this example, every manager must be in the employees table, but not every employee must be in the managers table.
- Child records can be set to
NULL
even if the parent table doesn't have it.- Unless the child record is a
PRIMARY KEY
or hasNOT NULL
on it.
- Unless the child record is a
CREATE TABLE managers
(
manager_id NUMBER
CONSTRAINT pk_managers PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
department_id NUMBER
CONSTRAINT mgr_dept_id_fk REFERENCES departments (department_id),
phone_number VARCHAR2(11) UNIQUE NOT NULL,
email VARCHAR(100),
UNIQUE (email),
CONSTRAINT mgr_emp_fk FOREIGN KEY (manager_id) REFERENCES employees_copy (employee_id),
CONSTRAINT mgr_names_fk FOREIGN KEY (first_name, last_name) REFERENCES employees_copy (first_name, last_name)
);
CREATE TABLE employees_copy
(
employee_id NUMBER(6) CONSTRAINT emp_eid_pk PRIMARY KEY,
first_name VARCHAR2(20),
last_name VARCHAR2(20),
department_id NUMBER(4),
CONSTRAINT emp_cpy_names_uk UNIQUE (first_name, last_name)
);
- The referenced column or group of columns must have a
UNIQUE
orPRIMARY
key on it.
CREATE TABLE managers
(
manager_id NUMBER
CONSTRAINT pk_managers PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
department_id NUMBER
CONSTRAINT mgr_dept_id_fk
REFERENCES departments (department_id),
phone_number VARCHAR2(11) UNIQUE NOT NULL,
email VARCHAR(100),
UNIQUE (email),
CONSTRAINT mgr_emp_fk FOREIGN KEY (manager_id)
REFERENCES employees_copy (employee_id) [ ON DELETE CASCADE | ON DELETE SET NULL],
);
-- Example
CREATE TABLE managers
(
manager_id NUMBER
CONSTRAINT pk_managers UNIQUE,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
department_id NUMBER
CONSTRAINT mgr_dept_id_fk
REFERENCES departments (department_id),
phone_number VARCHAR2(11) UNIQUE NOT NULL,
email VARCHAR(100),
UNIQUE (email),
CONSTRAINT mgr_emp_fk FOREIGN KEY (manager_id)
REFERENCES employees_copy (employee_id)
ON DELETE SET NULL
);
- The
ON DELETE CASCASDE
clause deletes dependent rows in the child table when a related row in the parent table is deleted. - The
ON DELETE SET NULL
clause updates dependent rows in the child table toNULL
when a related row in the parent table is deleted. - Both clauses can only be used table-level.
Ensures a column or a group of columns meets a specific condition.
- We cannot create
CHECK
constraints referencing another table. - A
CHECK
constraint can be created at the column-level or table-level.
CREATE TABLE managers
(
manager_id NUMBER
CONSTRAINT pk_managers PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
department_id NUMBER CHECK (check_condition),
salary NUMBER,
email VARCHAR(100),
CONSTRAINT mgr_salary_check CHECK (salary > 0 AND salary < 100000)
);
We can add, drop, enable, or disable constraints using ALTER TABLE
.
ALTER TABLE table_name
ADD [CONSTRAINT constraint_name] CONSTRAINT_TYPE (column_name, ...);
- To add a
NOT NULL
Constraint, we use theALTER TABLE MODIFY
clause.- The table must be empty or all the values of the
NOT NULL
column must have a value.
- The table must be empty or all the values of the
- We cannot modify a constraint's structure. To do that we need to drop and recreate the constraint.
- Existing rows shouldn't violate the constraint
We use the ALTER TABLE
statement to remove a constraint.
ALTER TABLE table_name
DROP
CONSTRAINT constraint_name;
While dropping a PRIMARY KEY
constraint, we can use the CASCADE
option to
drop all the associated FOREIGN KEY
constraints.
ALTER TABLE employees_copy
DROP CONSTRAINT emp_cpy_emp_id_pk CASCADE;
-- Simpler Syntax
ALTER TABLE employees_copy
DROP
PRIMARY KEY CASCADE;
-- Online
ALTER TABLE employees_copy
DROP
PRIMARY KEY ONLINE
- We can use the
ONLINE
keyword to allow DML operations while dropping the constraints. ONLINE
andCASCADE
cannot be used together.
If we use the CASCADE CONSTRAINTS
clause while dropping a column, all the
constraints referring to that column's PRIMARY
and UNIQUE
keys are dropped.
ALTER TABLE departments_copy
DROP COLUMN department_id CASCADE CONSTRAINTS;
- If there's a multi-column constraint, we need to use the
CASCADE CONSTRAINTS
clause to drop the column, otherwise we will get an error.
We use the ALTER TABLE ... RENAME CONSTRAINT
statement to rename one.
ALTER TABLE table_name
RENAME CONSTRAINT old_name TO new_name;
A disabled constraint does not enforce its restriction on the DML operation until it is re-enabled.
ALTER TABLE table_name
DISABLE CONSTRAINT old_name;
- We cannot directly disable a constraint if there is one or more foreign keys referencing this constraint.
- We can use the
CASCADE
option to disable a constraint and all the dependent constraints. - When we disable a unique or a primary key constraint, the Oracle Server will
remove the unique indexes.
- We can use the
KEEP INDEX
option to prevent this.
- We can use the
ALTER TABLE table_name
ADD CONSTRAINT constraint_name CONSTRAINT_TYPE DISABLE;
- It's also possible to create tables with disabled constraints.
ALTER TABLE table_name
ENABLE CONSTRAINT old_name;
- There is no
CASCADE
option to enable constraints, and they must all be explicitly enabled. - A unique index is automatically created by the Oracle Server when a unique or primary key constraint is enabled.
- To enable a constraint, all the data in the column or table must satisfy the constraint rules.
VALIDATE
orNOVALIDATE
can also be used withENABLE
andDISABLE
for configuring existing or future data validation.VALIDATE
ensures that the existing data must conform to the constraint conditions.NOVALIDATE
is used to suspend the checking of existing rows for constraint violations.
ENABLE VALIDATE
- Default for the
ENABLE
clause. - All existing and future rows will be validated.
- Default for the
ENABLE NOVALIDATE
- Existing rows for not validated, but future ones will be.
DISABLE VALIDATE
- The constraint is disabled, but it remains valid. No DML operations are alowed on the table because the future changes will not be validated.
DISABLE NOVALIDATE
- Default for the
DISABLE
clause. - No checks are performed on existing or future data.
- Basically makes the table read-only.
- Default for the
ALTER TABLE employees_temp
[ENABLE | DISABLE] [NO] VALIDATE CONSTRAINT constraint_name;
Constraints can have 2 deferring states:
- DEFERRABLE
- Allows us the option of postponing enforcement of constraints to the end
of a transaction. A deferrable constraint can be created in one of two
modes:
- INITIALLY IMMEDIATE (DEFAULT): Specifies that the constraint are checked for conformance at the end of each query execution.
- INITIALLY DEFERRED: Postpones constraint enforcement until the end of a transaction (commit).
- Allows us the option of postponing enforcement of constraints to the end
of a transaction. A deferrable constraint can be created in one of two
modes:
- NOT DEFERRABLE (DEFAULT)
- Indicates the enforcement of the constraint must always be done immediately as each statement is executed.
NOT DEFERRABLE
constraints will not be changed to DEFERRED
.
- Don't make constraints
DEFERRABLE
unless you really need to.
ALTER TABLE table_name
ADD CONSTRAINT constraint_name PRIMARY KEY (column_name) [NOT] DEFERRABLE []
SET CONSTRAINT constraint_name IMMEDIATE | DEFERRED;
SET CONSTRAINTS constraint_name1, constraint_name2, ..., IMMEDIATE | DEFERRED;
SET CONSTRAINTS ALL IMMEDIATE | DEFERRED;
- These all only apply to the current transaction.
ALTER SESSION SET CONSTRAINTS ALL = IMMEDIATE | DEFERRED;
- A view is a schema object formed of a stored SQL query based on tables or other views.
- A view is stored in the database as a
SELECT
statement. - No data is stored in the views
- The tables taht views are based on are called base tables.
- Views are used for:
- Restricting data access
- Simplifying data retrieval
- Presenting different views of the same data
- Provide logical data independence
- Simple Views
- Views that retrieve data from one table, containing no functions and no grouping of data.
- Complex Views
- Views that retrieve data from more than one table, or contain functions or grouping of data.
Feature | Simple Views | Complex Views |
---|---|---|
Number of Tables | One | One or more |
Contain functions | No | Yes |
Contain groups of data (GROUP BY) | No | Yes |
Contain DISTINCT or ROWNUM | No | Yes |
DML operations through a view | Yes | Not Always |
CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW view_name
[(alias[, alias]...)] AS subquery
[WITH CHECK OPTION [CONSTRAINT constraint_name]]
[WITH READ ONLY [CONSTRAINT constraint_name]];
OR REPLACE
modifies the view without the need to re-grant its privileges.FORCE
creates the view even if the base table does not exist.NOFORCE
creates the view only if the base table exists. (Default option)WITH CHECK OPTION
Prevents any kind of DML operations that the view cannot select.- An implicit constraint is created, so the
constraint_name
is optional to name it.
- An implicit constraint is created, so the
WITH READ ONLY
prevents any DML operation on the view.
CREATE NOFORCE VIEW empvw40 (
e_id,
name,
sirname,
email) AS
SELECT
employee_id,
first_name,
last_name,
email
FROM employees
WHERE department_id=40;
Retrieve data from one or more tables, and can contain much more.
CREATE NOFORCE VIEW emp_cx_vw (dname, min_sal, max_sal) AS
SELECT DISTINCT UPPER(department_name), MIN(salary), MAX(salary)
FROM employees e
JOIN departments d
USING(department_id)
GROUP BY department_name;
We can drop and re-create a view to modify it without losing any data.
- This is not the best way to do it. Dropping a view removes all the privileges on that view.
- The
REPLACE
option of theCREATE VIEW
statement modifies the view without the need to re-grant its privileges.
Used to ensure that the user cannot perform any DML operations that the view cannot select.
CREATE OR REPLACE VIEW empvw80 AS
SELECT
employee_id,
first_name,
last_name,
email,
hire_date,
job_id
FROM employees_copy
WHERE department_id = 80
WITH CHECK OPTION CONSTRAINT emp_dept_80_chk;
- If a constraint is violated, or the DML is performed violating the WHERE clause,
it will be denied.
- In this example, nothing can be inserted that doesn't have the
department_id
as 80. Also applies to updates.
- In this example, nothing can be inserted that doesn't have the
- To see all constraints:
SELECT * FROM user_constraints;
- Cannot be used with
WITH READ ONLY
clause
CREATE OR REPLACE VIEW empvw80 AS
SELECT
employee_id,
first_name,
last_name,
email,
hire_date,
job_id
FROM employees_copy
WHERE department_id = 80
WITH READ ONLY CONSTRAINT emp_80_rok;
- Cannot be used with
WITH CHECK OPTION
clause
DROP VIEW view_name;
- Does not cause data loss on the base tables
A set of read-only tables that provides administrative metadata about the database and database objects.
- Created and maintained by the Oracle Server
- Used by the Oracle DB itself or users including developers, DBA's and application designers.
- Read-Only
- Definitions of all schema objects in the database (tables, views, functions, indexes, etc.)
- Names of all users
- Default values for columns
- Constraint information
- Privileges of users
We can find the complete list of all data dictionary views in the view named
DICTIONARY
- All data dictionary view names are written in uppercase.
-- Searching user tables
SELECT * FROM dictionary WHERE table_name = 'USER_TABLES';
-- Searching comments to find the right table for security
SELECT * FROM dictionary WHERE UPPER(COMMENTS) LIKE '%SECURITY%';
-- Searching comments to find all tables related to constraints
SELECT * FROM dictionary WHERE UPPER(COMMENTS) LIKE '%CONSTRAINT%';
SELECT * FROM DICT -- Alias for DICTIONARY
USER
: Includes all the objects in the user's schemaALL
: Includes all the objects in user's schema and the objects that the user can access in all schemas.DBA
: Includes all the objects of all users. Only DBAs and users who have the required privileges can access these data dictionary views.V$
: Includes views that have information about database performance. Only DBAs and users who have the privileges can access these data dictionary views.
Contains the following info:
Column Name | Description |
---|---|
OBJECT_NAME |
Name of the object |
OBJECT_TYPE |
Type of the object (Table, view, etc.) |
CREATED |
Time of creation of the object |
LAST_DDL_TIME |
Last modification time of the object (Cahanging the structure) |
STATUS |
Status of the object (Valid, invalid, N/A) |
GENERATED |
Whether this object is system-generated or not (Y/N) |
SELECT * FROM user_objects;
SELECT * FROM user_catalog;
CAT
View (USER_CATALOG
): Cat is a synonym for theUSER_CATALOG
view which returns just the table_name and the table_type columns which list tables, views, synonyms and sequences of the user.- Also shows tables in the recycle bin
Used to see all objects that we own and all the objects that the user can access in all schemas.
SELECT * FROM all_objects;
Used to see all objects of all users including system objects.
SELECT * FROM dba_objects;
Shows all the tables that we own.
SELECT * FROM user_tables;
SELECT * FROM tabs; -- Synonym for user_tables view;
There are OBJECTS
, TABLES
, and INDEXES
for USER
, ALL
, and DBA
.
Used to see all the columns of all tables and views that we own. Has info like:
- Table Name
- Column Name
- Data Type
- Data Length
- ...
SELECT * FROM user_tab_columns;
SELECT * FROM cols; - Synonym for user_tab_columns;
-- Example
SELECT
column_name,
data_type,
data_length,
nullable,
data_default,
num_nulls,
avg_col_len,
num_disctinct
FROM user_tab_columns
WHERE table_name = 'DEPARTMENTS';
- Often used to query a specific table's columns and column properties using the user_tab_columns view.
Used to display all the information about the constraints on our tables.
Column Name | Description |
---|---|
OWNER |
Owner of the table |
CONSTRAINT_NAME |
Name of the constraint |
CONSTRAINT_TYPE |
Type of the constraint |
TABLE_NAME |
Name of the table associated with the constraint |
STATUS |
Status of the constraint (ENABLED / DISABLED) |
INDEX_NAME |
The index used by the constraint |
SEARCH_CONDITION |
Rule for the condition (Example: NOT NULL ) |
R_CONSTRAINT_NAME |
Name of the unique constraint in the referenced table |
DELETE_RULE |
Delete rule fora referential constraint (CASCADE , SET NULL , NO ACTION |
Constraint types for CONSTRAINT_TYPE
:
- C Check Constraint
- P Primary Key
- U Unique Key
- R Referential Integrity (Foreign Key)
- V With Check Option (Used For Views)
- O With Read-Only (Used For Views)
SELECT
owner,
table_name,
constraint_name,
constraint_type,
search_condition,
r_constraint_name,
delete_rule,
status,
index_name
FROM user_constraints;
Stores information about all the column - constraint pairs of our tables and views.
- Has critical information such as owner, constraint_name, table_name, column_name, and position.
SELECT * FROM user_cons_columns;
SELECT b.constraint_type, a.*, b.r_constraint_name
FROM user_cons_columns a
JOIN user_constraints b
ON (a.table_name = b.table_name AND a.constraint_name = b. constraint_name);
Shows the details about views that the user owns.
SELECT * FROM user_views;
USER_TAB_COMMENTS
(Used to see all the comments of our tables and views)USER_COL_COMMENTS
(Used to see all the comments of columns of tables and views.)- Tables or columns with no comments are returned with
NULL
in the comment column. - These views can also be used to find a table or column by searching some keywords from their comments.
SELECT *
FROM user_tab_comments
WHERE UPPER(comments) LIKE '%EMPLOYEE%';
- A sequence is a user-created object that automatically generates unique integer numbers.
- Generally used for populating primary key column values.
IDENTITY
column- Similar to
AUTO_INCREMENT
in MySQL
- Similar to
- A sequence is a shareable object that can be shared by multiple users
- Sequence numbers are stored independent of tables so a sequence can be used by multiple users and for multiple tables.
- Sequence numbers cannot be rolled back.
- Can be used anywhere to generate unique numbers.
- Sequence access efficiency can be improved by caching sequences in memory
PURGE RECYCLEBIN;
will delete everything in the recycle bin.
CREATE SEQUENCE [schema_name.]sequence_name
[ { START WITH start_num }
{ INCREMENT BY increment_num }
{ MAXVALUE max_num | NOMAXVALUE }
{ MINVALUE min_num | NOMINVALUE }
{ CYCLE | NOCYCLE }
{ CACHE cache_num | NOCACHE }
{ ORDER | NOORDER }
];
START WITH
is 1 by default.INCREMENT BY
is 1 by default.- A negative nubmer can also be specified.
- When
MAXVALUE
is reached, it will start over. (Default) CYCLE
After reaching its max or min value, the sequence continues to generate numbers starting with the min or max value.NOCYCLE
Stops generating numbers after reaching the max value. (Default)- Should be used when used with a
PRIMARY
orUNIQUE
key.
- Should be used when used with a
CACHE
Specified how many values are pre-allocated in memory by the Oracle server. (Default)- 20 sequence values are cached by default.
NOCACHE
No value is kept in memory.ORDER
guarantees that sequence numbers are generated in order of request.NOORDER
If you do not need to ensure that Oracle generates sequence numbers in order of request,NOORDER
can be used. (Default)
ALTER SEQUENCE
is used to modify a sequence.
ALTER SEQUENCE [schema_name.]sequence_name
[
{ INCREMENT BY increment_num }
{ MAXVALUE max_num | NOMAXVALUE }
{ MINVALUE min_num | NOMINVALUE }
{ CYCLE | NOCYCLE }
{ CACHE cache_num | NOCACHE }
{ ORDER | NOORDER }
];
- Only future sequence numbers are affected.
- We must be the owner of the sequence or have the
ALTER ANY SEQUENCE
privilege to modify a sequence. - We cannot use the
START WITH
option while modifying a sequence.- We must drop and re-create the sequence to start the sequence from a different number.
- While modifying the sequences, some validations are performed (e.g.,
MAXVALUE
cannot be smaller than theCURRENT
value.)
DROP SEQUENCE sequence_name;
- We must be the owner of the sequence or have the
DROP ANY SEQUENCE
privilege to modify a sequence.
NETVAL
(used to get the next value of a sequence)CURRENTVAL
(used to get the current value of a sequence)
SELECT sequence_name.NEXTVAL FROM dual;
SELECT sequence_name.CURRVAL FROM dual;
- If you try to retrieve the current value without initializing it for your
session, you will get an error.
- Initialize it with
nextval
.
- Initialize it with
- Do not get the next value unless you need it.
To catch a sequence up to a table, you can run:
SELECT sequence_name.NEXTVAL from <table>;
- The sequence will be run once per row in
table
.
- In the
SELECT
list of a query (not in a subquery or a view). - In the
SELECT
list of a subquery in anINSERT
statement. - In the
VALUES
part of aINSERT
statement.
- With the
DSTINCT
keyword - In the
GROUP BY
clause - In the
HAVING
clause - In the
ORDER BY
clause
- We can use
CURRVAL
orNEXTVAL
as a default value as long as the sequence exists.
CREATE TABLE temp(
column1 NUMBER DEFAULT employee_seq.NEXTVAL NOT NULL,
column2 VARCHAR2(50)
)
Sequences can be cached in memory to improve performance.
- Cache size can be defined when the sequence is initially created or altered.
- Default: 20
- The specified number of sequence values is cached into memory on the first call.
- After the last cached sequence value in memory is used, the next set of sequence values is cached.
- Cached sequence values will be lost on any systemf ailure, even if you haven't used them all.
Shows the properties of all the sequences that the current user owns.
DESCRIBE user_sequences;
SELECT * FROM user_sequences;
SEQUENCE_NAME
: Name of the dsequenceMINVALUE
: Minimum value of the sequenceMAXVALUE
: Maximum value of the sequenceINCREMENT_BY
: Specified interval between sequence numbersCYCLE_FLAG
: Whether the sequence starts with the minimum value after reaching the maximum value (Y=CYCLE/N=NOCYCLE)ORDER_FLAG
: Whether sequence numbers are generated in order (Y=ORDER / N=NOORDER)CACHE_SIZE
: Number of sequence values stored in memoryLAST_NUMBER
: Last sequence number written to disk or the maximum value in the cache (if sequence caching is active).SCALE
: Indicates whether this is a scalable sequence or not.EXTEND_FLAG
: Indicates whether this scalable sequence's values can be more than the max value or less than the min value.SHARDED_FLAG
: Indicates whether this is a sharded sequence or not.SESSION_FLAG
: Indicates whether the sequence is session-specific or not.KEEP_VALUE
: Indicates whether the sequence values are kept after a failure or not.
The IDENTITY
column automatically generates and inserts sequential values into
the related column.
GENERATED [ALWAYS | BY DEFAULT [ON NULL]] AS IDENTITY [(identity options)]
GENERATED ALWAYS
: Always generates a value on each insert. (Default)- Cannot insert into this column when this option is set.
GENERATED BY DEEFAULT
: Generates a value only if no value is provided.- Cannot insert
NULL
into this column when this option is set.
- Cannot insert
GENERATED BY DEEFAULT ON NULL
: Generates a value only if aNULL
value or nothing is specified.identity options
: Sequence options for creating theIDENTITY
column sequence.- Same set of properties as a sequence.
START WITH LIMIT VALUE
sets the existing maximum/minimum value +INCREMENT BY
value as theSTART WITH
value.- The
USER_TAB_IDENTITY_COLS
view can be used to query all the identity columns. - The
SYS.IDNSEQ$
view stores the link between the table and the sequence.
CREATE TABLE temp (
ID NUMBER GENERATED AS IDENTITY,
text VARCHAR2(100)
);
The DROP IDENTITY
clause removes the identity property but keeps the column.
ALTER TABLE table_name
MODIFY column_name
DROP IDENTITY;
- A table can only have one identity column
- Identity columns must be numeric data types
- Identity column is not inheirted when using a CTAS statement.
- Identity column cannot have another
DEFAULT
value. - Identity columns implicitly have
NOT NULL
andNOT DEFERRABLE
constraints. - The
CREATE SEQUENCE
privilege is needed to create an identity column.
- A synonym is a database object created to give an alternative name to another database object.
- We can think of synonyms as an alias
- Advantages of Synonyms:
- Useful for hiding the identity and location of the related object
- Eliminate the need of typing the owner of an object
- Useful for simplifying (abbreviating) object names
- Useful for backward compatibility
- Helpful in moving the objects between schemas without breaking the existing code.
- No need for additional privileges for the synonyms.
- Require no storage in the database other than its definition in the data dictionary views.
CREATE [OR REPLACE] [PUBLIC] SYNONYM [schema_name.]synonym_name
FOR [schema_name.]object_name[@db_link];
- To use a synonym created for another user's objects ,the usern eeds to have the related object privileges.
- Synonyms created without the
PUBLIC
option are considered private synonyms. - To create a private synonym in your schema, the
CREATE SYNONYM
privilege is needed. - To create a private synonym in another user's schema, the
CREATE ANY SYNONYM
privilege is required. - We can create synonyms for our objects or other schema objects in our schema or in another schema.
- DBAs or the users having the
CREATE PUBLIC SYNONYM
privilege can createPUBLIC
synonyms. db_link
is used to reach another database.- A private synonym should be unique amongst the objects in its schema, and a public synonym should be unique amongst public synonyms.
- Private synonyms have a higher precedence than public synonyms.
- A synonym is used as an alias for the underlying object.
- We can create synonyms for nonexistent objects and those for which we don't have access privileges at creation time.
- A private synonym name cannot be created with the same name as the underlying object, but a public one can.
DROP [PUBLIC] SYNONYM [schema_name.]synonym_name[@db_link];
DESC user_synonyms;
SYNONYM_NAME
: Name of the synonym
TABLE_OWNER
: Owner of the object referenced by the synonym
TABLE_NAME
: Name of the object referenced by the synonym
DB_LINK
: Database link referencing remote system
ORIGIN_CON_ID
: ID of the containing database
- 0 For non-container database
- 0 For non-container database
- 1 For the Root database