favBeersselect intoselect into❖ Week 04 Monday  | 
cs3311@cse❖ Week 04 Monday (cont)  | 
❖ PostgreSQL Stored Procedures  | 
PostgreSQL syntax for defining stored functions:
create or replace function funcName(arg1, arg2, ....) returns retType as $$ String containing function definition $$ language funcDefLanguage;
Notes:
$$$$''❖ Withdrawal Function in PLpgSQL  | 
create or replace function
    withdraw(_acctNum text, _amount integer) returns text
as $$
declare bal integer;
begin
    select balance into bal
    from   Accounts
    where  acctNo = _acctNum);
    if (bal < _amount) then
        return 'Insufficient Funds';
    else
        update Accounts
        set    balance = balance - _amount
        where  acctNo = _acctNum;
        bal := bal - _amount;
        return 'New Balance: ' || bal;
    end if
end;
❖ SQL functions  | 
The body of a PostgreSQL function can be an SQL query
create or replace function maxPriceAt(text) returns numeric(4,2) as $$ select max(price)::numeric(4,2) from Sells where bar = $1; $$ language sql;
which can be used as, e.g.
select * from maxPriceAt('Royal Hotel');
select maxPriceAt('Coogee Bay Hotel');
select name, maxPriceAt(name) from  Bars;
But still provides no procedural programming capability
❖ SQL functions (cont)  | 
Value returned by an SQL function ...
selectcreate or replace function maxPriceAt(_bar text) returns numeric(4,2) as $$ select max(price)::numeric(4,2) from Sells where bar = _bar; $$ language sql;
❖ Exercise: SQL function  | 
Write an SQL function to find the most expensive beer that a drinker likes
create or replace function priciest(_drinker text) returns text as $$ ... $$ language sql;
❖ PLpgSQL  | 
PLpgSQL is PostgreSQL's stored procedure language
Allows you to write functions that combine
Loosely based on Oracle's PL/SQL (translating between PL/SQL and PLpgSQL is easy)
❖ Example PLpgSQL function (i)  | 
An iterative factorial function in PLpgSQL
create or replace function ifac(n integer) returns integer as $$ declare i integer; --uninitialised variable fac integer := 1; -- initialised variable begin for i in 2..n loop fac := fac * i; end loop; return fac; end; $$ language plpgsql;
❖ Example PLpgSQL function (ii)  | 
A recursive factorial function in PLpgSQL
create or replace function
   rfac(n integer) returns integer
as $$
begin
   if (n < 2) then
      return 1;
   else
      return n * rfac(n-1);
   end if;
end;
$$ language plpgsql;
❖ PLpgSQL functions returning Sets  | 
PLpgSQL functions can return sets of values, e.g.
create or replace function iota(_max integer) return setof integer as $$ ... $$
If they return a set of tuples, they effectively return a table, e.g.
create or replace function favBeers(_drinker text) return setof Beers as $$ ... $$
Each tuple/value is included in the result set by  return nextValue
❖ Exercise: Function Overloading  | 
A function is identified by its name and parameter types (its signature).
Can have several functions with same name, but different parameters.
Consider a function seq
seq(n)seq(n,m)seq(n,m,incr)seq()❖ PLpgSQL function returning Sets of Tuples  | 
As noted above, functions can return sets of tuples.
Return sets can be defined:
function F(...) returns table(x integer, y integer)
create type Pair as (x integer, y integer); function F(...) returns setof Pair
create table Beers (id integer, name text, ...); function F(...) returns setof Beers
❖ PLpgSQL function returning Sets of Tuples (cont)  | 
Individual tuples are added to result set via RETURN NEXT
How this is acheived differs between the methods.
F(...) returns table(x integer, y integer)xyRETURN NEXT;F(...) returns set of PairpPairp.xp.yRETURN NEXT p;❖ PLpgSQL functions using queries  | 
PLpgSQL functions can invoke queries and iterate through their results
Example:
create function
    beersLike(partName text) returns setof Beers
as $$
declare
    tuple Beers;
begin
    for tuple in
        select * from Beers where name ~* partName
    loop
       return next tuple;
    end loop;
end;
$$ language plpgsql;
❖ PLpgSQL functions using queries (cont)  | 
Deferred typing of query variables:
declare
   tuple record;
begin
   for tuple in Query
   loop
      Process tuple
   end loop;
   ...
end;
The tuple
I.e. the type of a record
❖ Exercise: The  favBeers | 
Implement a the favourite beers function
create or replace function favBeers(_drinker text) returns setof Beers as $$ ... $$ language plpgsql;
Assume that every beer a drinker drinks is one of their favourites
❖ Functions vs Views  | 
Functions returning setof
Views are used like tables.
What's the difference?
❖ Exercise: Function vs View  | 
Consider a view that gives Drinkers, but without their phone:
create or replace view d1(drinker,surburb) as ...
Then implement the same thing as a function
Then add parameter to restrict to names matching pattern
❖  select into | 
Can capture individual attributes in a select statement
select att1, att2, ... attn into var1, var2, ... varn from ...
Notes:
attiattivaricreate table R (...); declare tup R; select * into tup from R where Condition;
❖ Exercise:  select into | 
Consider a table  R(a integer, b text, c float)
Implement different ways to collect individual attributes into variables
Variables are  x integer, y text, z float
Produced: 2 Oct 2023