PostgreSQL:将函数作为值存储在列中
函数是否可以作为匿名函数直接存储在列中作为其值 假设我希望这个函数存储在列中。 示例(伪代码): 表my_表:pk(int),my_函数(func) func(x){返回x*100} 然后将其用作:PostgreSQL:将函数作为值存储在列中,postgresql,dynamic-sql,Postgresql,Dynamic Sql,函数是否可以作为匿名函数直接存储在列中作为其值 假设我希望这个函数存储在列中。 示例(伪代码): 表my_表:pk(int),my_函数(func) func(x){返回x*100} 然后将其用作: select t.my_function(some_input) AS output from my_table as t where t.pk = 1999 每个pk的函数可能不同。您的标题要求的不是您的示例 必须先创建函数,然后才能调用它。(标题) 必须对表达式进行计算。
select
t.my_function(some_input) AS output
from
my_table as t
where t.pk = 1999
每个pk的函数可能不同。您的标题要求的不是您的示例
-- DROP SCHEMA x CASCADE;
CREATE SCHEMA x;
CREATE OR REPLACE FUNCTION x.f1(int)
RETURNS int AS
$$SELECT $1 * 100;$$
LANGUAGE sql IMMUTABLE;
CREATE OR REPLACE FUNCTION x.f2(text)
RETURNS text AS
$$SELECT $1 || '_foo';$$
LANGUAGE sql IMMUTABLE;
CREATE TABLE x.my_expr (expr text PRIMARY KEY, def text, rettype text);
INSERT INTO x.my_expr VALUES
('x', $$x.f1(3)$$, 'int')
,('y', $$x.f2('bar')$$, 'text')
;
CREATE OR REPLACE FUNCTION x.f_eval(text, _type anyelement, OUT _result anyelement)
AS
$x$
BEGIN
EXECUTE
'SELECT ' || (SELECT def FROM x.my_expr WHERE expr = $1)
INTO _result;
END;
$x$
LANGUAGE plpgsql;
电话:
2.动态创建和使用函数
可以动态创建函数,然后使用它们。但是,使用普通SQL无法做到这一点。您必须使用另一个或至少一个PostgreSQL 9.0中引入的
它可以这样工作:
-- DROP SCHEMA x CASCADE;
CREATE SCHEMA x;
CREATE TABLE x.my_func (func text PRIMARY KEY, def text);
INSERT INTO x.my_func VALUES('f'
, $$CREATE OR REPLACE FUNCTION f(int)
RETURNS int AS
'SELECT $1 * 100;'
LANGUAGE sql IMMUTABLE$$);
CREATE OR REPLACE FUNCTION x.f_create_func(text)
RETURNS void AS $x$
BEGIN
EXECUTE (SELECT def FROM x.my_func WHERE func = $1);
END;
$x$
LANGUAGE plpgsql;
电话:
之后可能需要删除该函数
在大多数情况下,您应该只创建函数,然后用它来完成。如果多个版本或权限有问题,请使用单独的架构
有关我在此处使用的功能的更多信息,请参见。您可能是指
my_function()
或一些实际的\u架构。my_function()
而不是t。my_function()
,因为t
是表别名。只要我们没有尝试那种疯狂,那么只要函数输出一个非设置的、非记录的值(即它不输出一行或一个表),那么是的,应该可以。不,听起来像是没有。my_function()正是他想要的。基本上,DB相当于函数指针或clousure。是的,我的意思是类似闭包的东西。谢谢你Erwin提供了这个例子。我怀疑我所问的可能不起作用,所以这个或类似的问题是计划B。您如何在x.f_eval
中分配返回数据类型?我看到您将\u键入anyelement
作为第二个参数;但是,我不知道它是如何在函数定义中使用的。忽略上面的注释。。。详情见
-- DROP SCHEMA x CASCADE;
CREATE SCHEMA x;
CREATE TABLE x.my_func (func text PRIMARY KEY, def text);
INSERT INTO x.my_func VALUES('f'
, $$CREATE OR REPLACE FUNCTION f(int)
RETURNS int AS
'SELECT $1 * 100;'
LANGUAGE sql IMMUTABLE$$);
CREATE OR REPLACE FUNCTION x.f_create_func(text)
RETURNS void AS $x$
BEGIN
EXECUTE (SELECT def FROM x.my_func WHERE func = $1);
END;
$x$
LANGUAGE plpgsql;
select x.f_create_func('f');
SELECT f(3);