BEGIN INSERT INTO users(email) VALUES(p_email);EXCEPTION WHEN unique_violation THEN RAISE NOTICE 'duplicate email %', p_email; WHEN OTHERS THEN RAISE;END;
Condition
Catches
unique_violation
23505
foreign_key_violation
23503
not_null_violation
23502
division_by_zero
22012
OTHERS
All non-system errors
2. Using RAISE Statement
RAISE NOTICE 'value = %', x;RAISE WARNING 'low stock for sku %', sku;RAISE EXCEPTION 'invalid input: %', val USING ERRCODE = '22023', HINT = 'must be positive';
Note: Controlled by plpgsql.check_asserts (default on). Use for invariants, not user-input validation.
4. Using RETURN Statement
RETURN x + 1; -- scalarRETURN NEXT row_var; -- accumulate setRETURN QUERY SELECT * FROM customers WHERE active;RETURN; -- end of SETOF function
5. Using Function Overloading
CREATE FUNCTION add(int, int) RETURNS int AS $ SELECT $1+$2 $ LANGUAGE sql;CREATE FUNCTION add(numeric, numeric) RETURNS numeric AS $ SELECT $1+$2 $ LANGUAGE sql;
6. Using DEFAULT Parameter Values
CREATE FUNCTION greet(name text DEFAULT 'world')RETURNS text LANGUAGE sql AS $ SELECT 'Hello, ' || name $;SELECT greet(); -- 'Hello, world'
7. Using Named Parameters
SELECT greet(name => 'Alice');-- positional + named mix allowed left-to-right
8. Using STRICT Keyword
Modifier
Effect
STRICT
Return NULL if any arg is NULL (skip body)
CALLED ON NULL INPUT
Always invoke (default)
9. Using IMMUTABLE, STABLE, VOLATILE
Volatility
Meaning
IMMUTABLE
Same args → same result, no side effects (can index expression)
STABLE
Within statement, deterministic (e.g. current_user)
VOLATILE
Default; may change anytime (e.g. random())
10. Using SECURITY DEFINER vs SECURITY INVOKER
CREATE FUNCTION secret_op() RETURNS voidLANGUAGE plpgsql SECURITY DEFINERSET search_path = pg_catalog, public AS $ BEGIN ... END $;
Warning: SECURITY DEFINER runs with the owner's privileges. ALWAYS set search_path explicitly to prevent schema-spoofing attacks.
11. Using PARALLEL SAFE, PARALLEL UNSAFE, PARALLEL RESTRICTED
Mode
Meaning
UNSAFE (default)
Cannot run in parallel workers
RESTRICTED
Only on leader process
SAFE
Anywhere — required for parallel scans
12. Listing Functions
\df\df+ schema.*SELECT proname, pg_get_function_identity_arguments(oid) FROM pg_proc WHERE pronamespace = 'public'::regnamespace;