如何创建一个user defined function in PostgreSQL,其作用类似于下面定义的C函数pair
?
另外,我应该使用哪种类型的功能?为什么?
(A)query language (SQL) function
(B)procedural language function
(C)internal function
(D)C-language function
(E)None of the above
SQL和&amp ;;中实现的奖励积分PL / pgSQL语言。
#include <stdio.h>
#include <math.h>
int pair(int x, int y)
{
int z;
if (x < y) {
z = x * (y-1);
y = y - x - 2;
} else {
z = (x-1) * y;
y = x - y - 2;
}
return z + pow(y, 2) / 4;
}
// TESTING
void test(int x, int y, int z)
{
printf("%s", pair(x, y) == z ? "." : "F");
}
int main(void)
{
test(1, 2, 1);
test(1, 3, 2);
test(1, 4, 3);
test(1, 5, 5);
test(1, 6, 7);
test(1, 7, 10);
test(1, 8, 13);
test(1, 9, 17);
test(2, 3, 4);
test(2, 4, 6);
test(2, 5, 8);
test(2, 6, 11);
test(2, 7, 14);
test(2, 8, 18);
test(2, 9, 22);
printf("\n");
return 0;
}
答案 0 :(得分:2)
SQL更简单。如果x < y它将返回数组的第一个元素,否则返回第二个元素
create or replace function pair(x int, y int)
returns double precision as $$
select (array[
x * (y - 1) + power(y - x - 2, 2) / 4,
(x - 1) * y + power(x - y - 2, 2) / 4
])[(not x < y)::int + 1]
;
$$ language sql;
select
pair(1, 2) = 1,
pair(1, 3) = 2,
pair(1, 4) = 3,
pair(1, 5) = 5,
pair(1, 6) = 7,
pair(1, 7) = 10,
pair(1, 8) = 13,
pair(1, 9) = 17,
pair(2, 3) = 4,
pair(2, 4) = 6,
pair(2, 5) = 8,
pair(2, 6) = 11,
pair(2, 7) = 14,
pair(2, 8) = 18,
pair(2, 9) = 22
;
一个转换为整数的布尔值产生1或0.由于Postgresql数组索引从1开始,然后将1添加到转换结果中。
答案 1 :(得分:2)
使用SQL CASE
statement:
CASE WHEN x < y THEN
x * (y - 1) + ((y - x - 2)^2)::int / 4
ELSE
(x - 1) * y + ((x - y - 2)^2)::int / 4
END
运算符^
以及函数power()
返回double precision
。所以我转向int
以符合你的问题。
包装成普通SQL function(带有运算符^
):
CREATE OR REPLACE FUNCTION pair1(x int, y int)
RETURNS int AS
$func$
SELECT CASE WHEN x < y THEN
x * (y - 1) + ((y - x - 2)^2)::int / 4
ELSE
(x - 1) * y + ((x - y - 2)^2)::int / 4
END
$func$ LANGUAGE sql IMMUTABLE;
在Postgres 9.1或更早版本中,你有第三个参考输入列,位置参数为$1
,$2
。
与PL/pgSQL function(功能power()
)相同:
CREATE OR REPLACE FUNCTION pair2(x int, y int)
RETURNS int AS
$func$
BEGIN
RETURN CASE WHEN x < y THEN
x * (y - 1) + power(y - x - 2, 2)::int / 4
ELSE
(x - 1) * y + power(x - y - 2, 2)::int / 4
END;
END
$func$ LANGUAGE plpgsql IMMUTABLE;
我依赖,但通常我会使用简单的 SQL函数。别忘了宣布IMMUTABLE
。这允许在更大的查询中进行各种性能优化并在功能索引中使用它。更详细的示例:
Does PostgreSQL support "accent insensitive" collations?