例子

这里是几个例子用以说明书写 PL/pgSQL 函数是多么地容易.对于更复杂的例子,程序员们可以看看用于 PL/pgSQL 回归测试的程序.

书写 PL/pgSQL 的一个很痛苦的细节是单引号的使用.CREATE FUNCTION 的函数原文本必须是一个语言字符串.在一个语言字符串里的单引号要么是两个单引号或者是用反斜杠转意.我们仍然在寻找一种优美的代替物.同时,我们应该象下面例子那样使用双引号.将来任何版本的 Postgres 对此的任何解决方法都将保持向下兼容.

一些简单的 PL/pgSQL 函数

下面的两个 PL/pgSQL 函数与 C 语言里讨论的对应函数是一样的.
CREATE FUNCTION add_one (int4) RETURNS int4 AS '
    BEGIN
        RETURN $1 + 1;
    END;
' LANGUAGE 'plpgsql';
CREATE FUNCTION concat_text (text, text) RETURNS text AS '
    BEGIN
        RETURN $1 || $2;
    END;
' LANGUAGE 'plpgsql';

复合类型的 PL/pgSQL 函数

同样下面的是等效于 C 函数样例的 PL/pgSQL 函数.
CREATE FUNCTION c_overpaid (EMP, int4) RETURNS bool AS '
    DECLARE
        emprec ALIAS FOR $1;
        sallim ALIAS FOR $2;
    BEGIN
        IF emprec.salary ISNULL THEN
            RETURN ''f'';
        END IF;
        RETURN emprec.salary > sallim;
    END;
' LANGUAGE 'plpgsql';

PL/pgSQL 触发器过程

下面的触发器的作用是:任何时候表中插入或更新了行,当前的用户名和时间都记录入行中.并且它保证给出了雇员名称并且薪水是一个正数.
CREATE TABLE emp (
    empname text,
    salary int4,
    last_date datetime,
    last_user name);

CREATE FUNCTION emp_stamp () RETURNS OPAQUE AS '
    BEGIN
        -- 检查是否给出了 empname 和 salary
        IF NEW.empname ISNULL THEN
            RAISE EXCEPTION ''empname cannot be NULL value'';
        END IF;
        IF NEW.salary ISNULL THEN
            RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname;
        END IF;

        -- 我们必须付帐给谁?
        IF NEW.salary < 0 THEN
            RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname;
        END IF;

        -- 记住何时何人的薪水被修改了
        NEW.last_date := ''now'';
        NEW.last_user := getpgusername();
        RETURN NEW;
    END;
' LANGUAGE 'plpgsql';

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_stamp();