Jed Rembold
April 16, 2025
A view in SQL is essentially a saved query
Existing views can be treated just like tables, selecting from their contents
Syntax similar to creating a new table, just with
VIEW
CREATE VIEW |||view name||| AS (
SELECT |||colnames|||
FROM |||tablename|||
)DROP VIEW |||view_name|||;CREATE OR REPLACE VIEW |||view_name||| ...
NULL valuesWITH LOCAL CHECK OPTION to
the end of a view creation queryLOCAL with
CASCADED if you are referencing several
nested views and want the restrictions to apply based on all the views’
restrictionsSELECT from it after you do!newest that will
only show the “new” boxes from
best_boxesnewred that will
only show new and red boxes using only
newestCHECK OPTION setting for both
views so that you could add
('Jane', 2, 7, 9, 'red', 'new') to
newred but not
('Bart', 6, 10, 12, 'red', 'used') to
newred
The structure of any defined function will generally look like:
CREATE FUNCTION |||function name|||(|||function arguments|||)
RETURNS |||return type||| AS
|||function body string|||
LANGUAGE |||function lang|||;|||function name||| - The desired name
of the function
|||function arguments||| - A comma
separated list of paired arguments and types
|||return type||| - The variable type
of what will be returned (selected)
|||function lang||| - The language
used for the function body
|||function body string||| - a
string containing the query or logic to process
whenever the function is run
LANGUAGE SQLSELECTRETURNS void and then
using INSERT,
UPDATE, DROP,
etc.$$ to quote the body is recommended
so that you do not need to double up any single quotesSuppose we wanted to define a function to return us the difference between two timestamps in hours
CREATE FUNCTION diff_in_hours
(start_ts TIMESTAMP, end_ts TIMESTAMP)
RETURNS FLOAT AS
$$
SELECT date_part('epoch', end_ts - start_ts) / 60
$$
LANGUAGE sql;LANGUAGE plpgsqlBEGIN,
END keywordsYou can define variables
x := 56;Control statements
IF x > 5 THEN
|||...do something...|||
ELSE
|||...do something else...|||
END IF;Returns
RETURN x;Suppose we wanted to define a function to return us the same difference between two timestamps in hours, but now in pgsql
CREATE FUNCTION diff_in_hours_plpgsql
( start_ts TIMESTAMP, end_ts TIMESTAMP )
RETURNS FLOAT AS
$$
BEGIN
IF end_ts > start_ts THEN
RETURN date_part('epoch', end_ts - start_ts) / 60;
ELSE
RETURN NULL;
END IF;
END;
$$
LANGUAGE plpgsql;Python is another supported language in which functions can be written
Requires an extension to be active:
CREATE EXTENSION plpython3u;Having the extension available might depend on how your database was installed
Most common data types with corresponding types are converted, anything else (like timestamps!) are just utilized as strings
I’d generally write the Python in a more Python-suited editor and then copy it in.
box_volume to
compute the volume of a cubic object, and use that function to populate
a new volume column in
best_boxesscale_boxes which
updates the best_boxes table to scale the
value in the named width,
height, or depth
columns by the provided argument. Run it to ensure it is working.NEW and
OLD will refer to the newly changed or
previous table values (respectively)TRIGGER typeUPDATE or
INSERT triggers should return
NEWDELETE triggers should return
OLDCREATE TRIGGER |||trigger name|||
AFTER UPDATE
ON |||table_name|||
FOR EACH ROW
EXECUTE FUNCTION |||func_name|||();
INSERT,
UPDATE, or DELETE
events that affect a particular tableINSTEAD OF
the event occurring, but we won’t cover that hereIn some cases, triggering off of any update or insert is too broad
Can localize to just a single (or few) columns by using
OF colname1:
AFTER UPDATE OF |||column_name₁|||, |||column_name₂|||Can localize to only triggering off certain rows by inserting a
WHEN condition before the
EXECUTE line
NEW and
OLD within this conditionWHEN OLD.|||name||| != NEW.|||name|||
EXECUTE FUNCTION |||myfunc|||();FOR EACH ROW will cause the trigger
function to run once for every row that was a part of the
triggered event
UPDATE that affected 10 rows? The
trigger function will be run 10 times, once on each rowNEW
and OLD variables in your trigger
functionFOR EACH STATEMENT will cause the
trigger function to run once when the triggering event occurs
UPDATE that affects 10 rows? The
trigger function just runs once.OLD or
NEWYou are very worried about the data within
best_boxes from our earlier activity, such
that you want to keep a log of any name changes that might occur. The
table name_changes was already created for
you from the earlier activity.
name from
best_boxes, will add a row to the
name_changes table, where the operation would
be 'update' in this case. The
changed_at column should be set to the
current timestamp. Test it by changing ‘Bob’ to ‘Bobby’.name_changes whenever a new row is added
to best_boxes. In this case, the operation
would be 'insert' and the
og_name would be
NULL.