SQL Basics
PL/SQL Concepts
Ref
Definition
- Procedural Language for SQL is a procedural extesion for SQL.
- Most commonly used features include:
- Program units
- Block
- Function
- Procedure
- Package
- Trigger
- Data types
- Numeric
- Character
- Date
- Exceptions
- Specifi columns
- Conditional statements
- Array handling
- Associative arrays(index-by tables)
- Nested tables
- Varrays(variable-size arrays)
- Cursors
- Looping
- Dynamic SQL
- Program units
Trigger
Stored Procedure and Function
Refs
Stored Procedure vs Function
Functions follow the computer-science definition in that they MUST return a value and cannot alter the data they receive as parameters (the arguments). Functions are not allowed to change anything, must have at least one parameter, and they must return a value. Stored procs do not have to have a parameter, can change database objects, and do not have to return a value.
Stored Procedure
Syntax
1 | -- create a procedure: |
- Parameter types:
- IN: Passed into the procedure, must assign a value, immutable.
- OUT: Not required to assign a value, mutable.
- IN OUT: Passed into the procedure, must assign a value, mutable.
Test Data
- Initalize test data for the examples:
1 | create table customers ( |
Cursor
A cursor is a pointer that points to the result of a query.
There are two types of cursors:
- Implicit cursor
- Automatically created by Oracle whenever an SQL statement is executed.
- Whenever a DML(INSERT, UPDATE and DELETE) statement is executed, an implicit cursor is associated with this statement.
- For INSERT statement, the cursor holds the data to be inserted; For UPDATE and DELETE statement, the cursor identifies the rows that would be affected.
- Explicit cursor
- Created on a SELECT statement which returns more than one row.
- Implicit cursor
Cursor attributes
Attribute Description %FOUND Returns TRUE if an INSERT, UPDATE, or DELETE statement affected one or more rows or a SELECT INTO statement returned one or more rows. Otherwise, it returns FALSE. %NOTFOUND The logical opposite of %FOUND. It returns TRUE if an INSERT, UPDATE, or DELETE statement affected no rows, or a SELECT INTO statement returned no rows. Otherwise, it returns FALSE. %ISOPEN Always returns FALSE for implicit cursors, because Oracle closes the SQL cursor automatically after executing its associated SQL statement. %ROWCOUNT Returns the number of rows affected by an INSERT, UPDATE, or DELETE statement, or returned by a SELECT INTO statement.
Examples
If you run the examples in PL/SQL Developer, remember to run the code of the procedure creation in a program windows instead of a sql window. Sql window does not throw errors!
- Implicit cursor:
1 | DECLARE |
- Explicit cursor:
1 | DECLARE |
- Simplest procedure:
1 | CREATE OR REPLACE PROCEDURE greetings |
- Procedure with parameters:
1 | DECLARE |
1 | DECLARE |
- Exception handling:
1 | DECLARE |
CTE
Ref
Definition
- Common Table Expression, a query defined within another query.
- It’s like a subquery, but can be assigned a name and reused many times.
- It’s also like a ‘one-shot’ view.
- Also called a SQL WITH clause as it uses the WITH keyword.
Example
Initialization data
- Initialize data:
1 | CREATE TABLE employee ( |
This creates the following data:
EMP_ID | FIRST_NAME | LAST_NAME | DEPT_ID | MANAGER_ID | OFFICE_ID |
---|---|---|---|---|---|
1 | Sally | Jones | 3 | 2 | 5 |
2 | Mark | Smith | 2 | 4 | 3 |
3 | John | Andrews | 1 | 4 | 3 |
4 | Michelle | Johnson | 2 | 5 | |
5 | Brian | Grand | 2 | 2 | 3 |
Simple Example: Get employee name with department employe count
1 | WITH d_count AS |
Recursive CTE Example
1 | WITH cteEmp(emp_id, |
- This produces the following result:
EMP_ID | FIRST_NAME | MANAGER_ID | EMPLEVEL |
---|---|---|---|
4 | Michelle | 1 | |
2 | Mark | 4 | 2 |
3 | John | 4 | 2 |
1 | Sally | 2 | 3 |
5 | Brian | 2 | 3 |
The above result is generated in the following process:
- Get data from the initial query
where manager_id IS NULL
, which returns one row;
Notice that a recursive CTE must have beUNION
query connecting a initial qery and a recursive query. - The recursive query
FROM employee e, cteEmp r WHERE e.manager_id = r.emp_id
associates the original table with data from the initial query, returning more data; - Repeats step 2, until no more data is yielded.
Window function
Materialized View
Ref
Concept
- A materialized view, or snapshot as they were previously known, is a table segment whose contents are periodically refreshed based on a query, either against a local or remote table.
Syntax
1 | -- Normal |
Build options:
- IMMEDIATE: The materialized view is populated immediately.
- DEFERRED: The materialized view is populated on the first request refresh.
Refresh types:
- FAST: A fast refresh is attempted. If materialized view logs are not present against the source tables in advance, the creation fails.
- COMPLETE: The table segment supporting the materialized view is truncated and repopulated completely using the associated query.
- FORCE: A fast refresh is attempted. If one is not possible a complete refresh is performed.
- FAST VS COMPLETE: FAST refresh only updates rows while COMPLETE refresh completely removes all data and inserts all data from the query.
Trigger types:
- ON COMMIT: The refresh is triggered by a comitted data change in one of the dependent tables.
- ON DEMAND: The refresh is initiated by a manual request or a scheduled task.
- Refreshing on commi is very intensive on a volative base table.
Prebuilt:
- ON PREBUILT TABLE: use existing table which must have same name as materialized view and same column structure as the query.
- QUERY REWRITE: tells optimizer if materilized view should be considered for qery rewrite operations.
Schedule:
- The
START WITH ... NEXT ...
specifies a schedule.
- The
Refresh on demand
A materialized view can be refreshed either manually or as part of a refresh group or via a schedule.
Refresh manually:
1
2
3
4
5EXEC DMBS_MVIEW.refresh('mvt1');
-- For PL/SQL, use this:
begin
DBMS_MVIEW.REFRESH('mvt1');
end;Create a refresh group:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25BEGIN
DBMS_REFRESH.make(
name => 'SCOTT.MINUTE_REFRESH',
list => '',
next_date => SYSDATE,
interval => '/*1:Mins*/ SYSDATE + 1/(60*24)',
implicit_destroy => FALSE,
lax => FALSE,
job => 0,
rollback_seg => NULL,
push_deferred_rpc => TRUE,
refresh_after_errors => TRUE,
purge_option => NULL,
parallelism => NULL,
heap_size => NULL);
END;
/
BEGIN
DBMS_REFRESH.add(
name => 'SCOTT.MINUTE_REFRESH',
list => 'SCOTT.EMP_MV',
lax => TRUE);
END;
/Create a schedule(must be specified at the creation of the materialized view):
1
2
3
4
5
6create materialized view mvt1
build immediate
refresh force on demand
start with sysdate next sysdate + 1/24/60 -- Refresh every minute
as
select * from mvtt;The materialized view
mvt1
will be refreshed every minute. An Oracle job is also created at the same time.
To find out the job id, use this query:
1 | select m.owner, m.mview_name, r.job |
Examples
- Create a test table
mvtt
:
ind | name |
---|---|
1 | a |
- Create a materialized view:
1 | create materialized view mvt1 |
Now mvt1
has the same data as mvtt
. Insert a new row will not trigger an update in mvtt
because its trigger type is on demand
.
Others
Database link
INSERT MULTIPLE ROWS
- Use
INSERT ALL
to insert multiple rows:
1 | CREATE TABLE employee ( |
SQL Basics