내 사용 사례에서는 테이블에 삽입 한 후 정적 인수를 사용하여 동적 (미리 정의 된) 함수를 실행할 수 있어야합니다.
논리적으로 생각하고 있습니다.
지금까지 내가 도착한 것은 다음과 같습니다.
create function f1(num int) returns boolean as $$
-- ...
$$ language plpgsql;
create function f2(name text, age int) returns boolean as $$
-- ...
$$ language plpgsql;
create function f3(first_name text, last_name text) returns boolean as $$
-- ...
$$ language plpgsql;
create table function_invocations(
id integer not null,
name text not null,
args text not null, -- (not sure if this should be an array)
primary key(id)
);
create function verify_function_exists() returns trigger as $$
-- query information_schema to verify there is
-- a function with specified name and that
-- specified args satisfy function's
-- signature.
$$ language plpgsql;
create trigger function_exists_trig
before insert on function_invocations
for each row
execute procedure verify_function_exists();
create table my_data(
id integer not null,
function_invocation_id integer not null,
-- etc.
primary key(id),
foreign key(function_invocation_id) references function_invocations(id)
);
create function exec_dynamic_function() returns trigger as $$
-- retrieve the function name and args from
-- function_definitions and execute the
-- function specified by `name` with the
-- provided `args`.
$$ language plpgsql;
create trigger function_invocations_trig
after update on my_data
for each row
execute procedure exec_dynamic_function();
이것이 작업에 대한 올바른 방법입니까? JS 배경에서 왔기 때문에 잘못된 방식으로 생각할 수 있습니다.
var api = {
my_func: function (age, name) {
console.log('%d %s', age, name);
}
};
var fn = 'my_func';
var args = [50, 'john'];
api[fn].apply(api, args);
내 주요 관심사는 function_invocations
테이블의 행에서 참조하는 함수가 실제로 존재하고 정의 된 인수가 유효한지 확인하는 방법입니다 (또는 적어도 유효하도록 강제 할 수 있음).
PostgreSQL 9.4.1을 사용하고 있습니다.
다음은 CHECK
트리거 대신 간단한 제약 조건 이있는 솔루션입니다 .
CREATE TABLE func (
func_id serial PRIMARY KEY
, func text NOT NULL
, args text NOT NULL
, CHECK ((func || '(' || args || ')')::regprocedure IS NOT NULL)
);
CHECK
제약,보다 빠르고 안정적인 가능한 트리거 솔루션보다 간단합니다. 이 변형은 모든 최신 Postgres 버전에서 작동합니다.
regprocedure
제약 조건이 평가를 완료하기 전에 유효하지 않은 함수에 대한 캐스트가 실패합니다. 이는 해당 오류 메시지에 반영됩니다.
Postgres 9.4+에서는 to_regprocedure()
캐스트 대신 new 를 사용하여 예외를 발생시키지 않습니다. CHECK
대신 제약 조건 에서 예외가 발생 합니다. 자세히 (마지막 장) :
공장:
INSERT INTO func(func, args) VALUES ('substring','text, int');
예외와 함께 실패 :
INSERT INTO func(func, args) VALUES ('nonexistant','text, int');
에 대한 UNIQUE
제약 도 고려할 것 입니다 (func, args)
. 동일한에 대해 유효한 텍스트 표현이 여러 개있을 수 있습니다 args
. 숨겨진 중복을 찾기위한 빠른 확인은 다음과 같습니다.
SELECT func, string_to_array(args, ', ')::regtype[], count(*)
FROM func
GROUP BY 1, 2
HAVING count(*) > 1;
캐스트가 아니기 때문에 고유 인덱스에서이 식을 사용할 수 regtype
없습니다 IMMUTABLE
. 당신은 속임수를 써야 할 것입니다 ...
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다