模拟 iif 函数
来自 PostgreSQL wiki
跳转到导航跳转到搜索作者:Emanuel Calvo Franco 和 Hector de los Santos
一些开发者习惯使用某些“Access”(以及其他数据库)函数。其中之一是“iif”函数,它工作起来非常简单,有时可以为查询添加更多智能。
你会惊讶地发现,在 Postgresql 中可以很容易地添加此函数。
在纯 SQL 中
CREATE OR REPLACE FUNCTION iif_sql(boolean, anyelement, anyelement) returns anyelement as
$body$ select case $1 when true then $2 else $3 end $body$
LANGUAGE sql IMMUTABLE;
虽然你可以使用此多态函数一次覆盖所有数据类型,但需要使用强制转换定义或指定类型。一个简单的 iif_sql(8<9,'yes','no') 会失败。为了解决这个问题,你可以添加一个重载方法来覆盖这种情况。
CREATE OR REPLACE FUNCTION iif_sql(boolean, unknown, unknown) returns text as
$body$ select case $1 when true then textin(unknownout($2)) else textin(unknownout($3)) end $body$
LANGUAGE sql IMMUTABLE;
在 PL/Pgsql 中
CREATE OR REPLACE FUNCTION iif_(boolean, double precision, double precision) RETURNS double precision AS
$body$
DECLARE
rtVal double precision;
BEGIN
rtVal := (select case $1 when true then $2 else $3 end);
return rtVal;
END;
$body$
LANGUAGE 'plpgsql' IMMUTABLE CALLED ON NULL INPUT SECURITY INVOKER;
在 PL/Perl 中(警告 - 我们正在用不同的方式解决同一个问题,如果你想像 plpglsql 一样执行,你必须使用 spi_query_exec() 函数)
CREATE OR REPLACE FUNCTION iif_perl(boolean, double precision, double precision) RETURNS double precision AS
$body$
if($_[0] =~ /t/){
return $_[1];
}else{
return $_[2];
}
$body$
LANGUAGE 'plperl' IMMUTABLE RETURNS NULL ON NULL INPUT SECURITY INVOKER;
像一个 C 共享对象
#include <stdio.h>
#include "postgres.h"
#include "executor/executor.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(iif_c);
Datum
iif_c (PG_FUNCTION_ARGS){
bool message = PG_GETARG_BOOL(0);
float8 first = PG_GETARG_FLOAT8(1);
float8 second = PG_GETARG_FLOAT8(2);
if(message == 1){
PG_RETURN_FLOAT8(first);
}else{
PG_RETURN_FLOAT8(second);
}
}
但用这种方式,你必须执行编译和语句“CREATE FUNCTION”。
postgres@pgsql:/usr/local/pgsql84/$ gcc -I include/server/ --shared iif_c.c
...然后
CREATE OR REPLACE FUNCTION iif_c(boolean, double precision, double precision) RETURNS double precision
AS '/usr/local/pgsql84/compiled/a.out', 'iif_c'
LANGUAGE C STRICT;
-- test it? go!
SELECT iif_c(9<8,0,9);
请注意,你必须修改参数的类型以接受其他类型的值! (除了第一个)。
在这些函数中,我们有不同的“总运行时间”。
plpgsql: Total runtime: 0.091 ms plperl: Total runtime: 0.116 ms C: Total runtime: 0.034 ms
真快啊!:D