PostgresSQL 提供三种类型的函数:
过程语言函数(用诸如 PLTCL 或 PLSQL 这样的语言写的函数)
编程语言函数(用类似 C 这样编译的编程语言写的函数)
跟在 AS 后面的 SQL 函数体应该是一个用空白字符分隔和用引号括起来的查询列表。要注意在查询里面的引号必须用前面带两个反斜杠的方法转意。
SQL 函数的参数在查询里可以用 $n 语法引用:$1 指第一个参数,$2 指第二个参数,以此类推。如果参数是复合类型,那么可以用点表示法(例如。"$1.emp")访问参数里的字段或者激活函数。
create function TP1 (int4, float8) returns int4 as 'update BANK set balance = BANK.balance - $2 where BANK.acctountno = $1 select(x = 1)' language 'sql';一个用户可以象下面这样用这个函数给帐户 17 扣款 $100.00:
select (x = TP1( 17,100.0));下面的更有意思的例子接受一个类型为 EMP 的参数,并且检索多个结果:
select function hobbies (EMP) returns set of HOBBIES(译注:开头的 select 应为 create) as 'select (HOBBIES.all) from HOBBIES where $1.name = HOBBIES.person' language 'sql';
CREATE FUNCTION one() RETURNS int4 AS 'SELECT 1 as RESULT' LANGUAGE 'sql'; SELECT one() AS answer; +-------+ |answer | +-------+ |1 | +-------+注意我们给函数定义了目标列(名称为 RESULT),但是激活函数的查询语句的目标列覆盖了函数的目标列. 因此,结果的标记是 answer 而不是 one 的.
定义以基本类型为参数的 SQL 函数几乎一样简单,注意我们在函数内如何用$1和$2使用参数:
CREATE FUNCTION add_em(int4, int4) RETURNS int4 AS 'SELECT $1 + $2;' LANGUAGE 'sql'; SELECT add_em(1, 2) AS answer; +-------+ |answer | +-------+ |3 | +-------+
CREATE FUNCTION double_salary(EMP) RETURNS int4 AS 'SELECT $1.salary * 2 AS salary;' LANGUAGE 'sql'; SELECT name, double_salary(EMP) AS dream FROM EMP WHERE EMP.cubicle ~= '(2,1)'::point; +-----+-------+ |name | dream | +-----+-------+ |Sam | 2400 | +-----+-------+注意这里 $1.salary 语法的使用.在开始说明返回复合类型的函数之前,我们必须先介绍用于映射字段的函数表示法.我们可以用一个简单的方法解释这些:我们可以互换地使用 attribute(class) 和 class.attribute 两种表达方式:
-- -- 这是与下面语句一样的: -- SELECT EMP.name AS youngster FROM EMP WHERE EMP.age < 30 -- SELECT name(EMP) AS youngster FROM EMP WHERE age(EMP) < 30; +----------+ |youngster | +----------+ |Sam | +----------+不过,我们呆会儿就会看到不总是这种情况.这种函数表示法在我们希望使用的函数返回单条记录时是很重要的.此时我们在函数里面一个字段一个字段地组装整条记录.下面是返回单条 EMP 记录的函数例子:
CREATE FUNCTION new_emp() RETURNS EMP AS 'SELECT \'None\'::text AS name, 1000 AS salary, 25 AS age, \'(2,2)\'::point AS cubicle' LANGUAGE 'sql';在这个例子中我们把每个字段赋予了一个常量,当然我们可以用任何计算或表达式来代替这些常量.定义这样的函数可能需要一点点技巧.下面是一些比较重要的注意事项:
你必须很仔细的进行类型转换 (使用 ::).否则你将看到下面的错误信息:
WARN::function declared to return type EMP does not retrieve (EMP.*)当我们调用了一个返回整条记录的函数时,我们不能检索整条记录.我们要么是从该记录中映射出一个字段,要么是把整条记录传递给另外一个函数.
SELECT name(new_emp()) AS nobody; +-------+ |nobody | +-------+ |None | +-------+通常我们必须把函数的返回值映射到字段里,使用这种函数语法是因为分析器在分析函数调用时,无法正确分析与函数相联的'点'的语法.
SELECT new_emp().name AS nobody; WARN:parser: syntax error at or near "."在 SQL 查询语言里的任何命令的集合都可以打包在一起,定义为函数.这些命令可以包含更新动作(例如,INSERT,UPDATE,和 DELETE),就象可以使用 SELECT 查询一样.不过,最后的命令必须是一条返回类型与所声明的函数返回类型的一致的 SELECT 语句。
CREATE FUNCTION clean_EMP () RETURNS int4 AS 'DELETE FROM EMP WHERE EMP.salary <= 0; SELECT 1 AS ignore_this' LANGUAGE 'sql'; SELECT clean_EMP(); +--+ |x | +--+ |1 | +--+