Postgresql Stored Procedures
Postgresql Stored Procedures
Reusability
Avoid rewriting subqueries and improve readability. If you can't store a query in a library that all the applications can access, you can put that query in a stored procedure. You don't trust non-DBA's to write queries. Use triggers or constraints to prevent bad data from entering. Run several interdependent queries in a transaction in a single stored procedure. Log changes. Notify other systems of new data.
2
Separation of duties
Data integrity
Event handling
Views may be all you need. An object-relational mapper (ORM) can help write queries safely. Difficult to version control stored procedures. Software rollouts may require more db changes. Could slow software development process.
3
Executing get_last_name()
$ psql -E test test=# SELECT get_last_name('John'); NOTICE: Table is "person" get_last_name --------------Smith (1 row) test=# SELECT get_last_name('Bob'); get_last_name --------------unknown table (1 row) test=# SELECT get_last_name('Moe'); NOTICE: Table is "loser" ERROR: relation "loser" does not exist CONTEXT: SQL statement "SELECT last_name FROM loser WHERE first_name = 'Moe'" PL/pgSQL function "get_last_name" line 19 at for over execute statement test=#
Triggers
Triggers can be used to call a stored procedure before or after an INSERT, UPDATE, or DELETE statement on a table. Triggers can be called once per each row affected or once per each INSERT, UPDATE, or DELETE statement. Triggers on many different tables can share the same stored procedure.
7
NEW: The new row for INSERT/UPDATE statements. It is NULL in statement-level triggers. OLD: The old row for UPDATE/DELETE statements. It is NULL in statement-level triggers. TG_NAME: Name of the trigger. TG_WHEN: 'BEFORE' or 'AFTER'. TG_LEVEL: 'ROW' or 'STATEMENT'. TG_OP: 'INSERT', 'UPDATE', or 'DELETE' TG_TABLE_NAME: Name of the table that invoked the trigger. TG_TABLE_SCHEMA: Schema for the table in TG_TABLE_NAME.
8
-----
CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE NEW.sl_avail <> OLD.sl_avail DO INSERT INTO shoelace_log VALUES ( NEW.sl_name, NEW.sl_avail, current_user, current_timestamp ); UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7'; SELECT * FROM shoelace_log; sl_name | sl_avail | log_who | log_when ---------+----------+---------+---------------------------------sl7 | 6 | Al | Tue Oct 20 16:14:45 1998 MET DST (1 row) 12
13
Relations (tables/views) that are used due to rules get checked against the privileges of the rule owner, not the user invoking the rule. One of the things that cannot be implemented by rules are some kinds of constraints, especially foreign keys. A trigger that is fired on INSERT on a view can do the same as a rule: put the data somewhere else and suppress the insert in the view. But it cannot do the same thing on UPDATE or DELETE, because there is no real data in the view relation that could be scanned, and thus the trigger would never get called. A rule may be more efficient than row-level triggers for bulk updates or deletes. A rule may be easier to write than a statement-level triggers, since the rule will rewrite complex queries for you. 14
References
http://mysql.meetup.com/284/ http://www.postgresql.org/docs/8.3/interactive/server-programming.html
SQL stored procedures (trusted) PL/pgSQL (trusted) PL/Tcl (trusted and untrusted) PL/Perl (trusted and untrusted) PL/Python (untrusted) Triggers Rules http://wiki.tada.se/display/pljava/Home http://www.postgresql.org/download/
PL/Java
15