Функция в качестве параметра для другой функции в Postgres - PullRequest
5 голосов
/ 01 декабря 2011

Могу ли я создать пользовательскую функцию в Postgres через API функций языка C или с помощью pl/pgsql, который принимает функцию обратного вызова в качестве параметра?

Насколько я вижу, нет способа сделать это через API языка C, поскольку он принимает только типы данных sql, и для function нет типа данных. Но, может быть, я что-то упустил?

Ответы [ 3 ]

4 голосов
/ 01 декабря 2011

Поскольку каждая функция / процедура должна иметь запись в pg_proc, вы можете использовать первичный ключ для идентификации процедуры.Это также устранит проблемы с процедурами, имеющими одно и то же имя, но с разным количеством параметров или разными типами параметров.

Сокращения для этого - типы regproc и regprocedure со связанными приведениями для упрощения обработки.Найдите для них руководство .

Идентификация функции и ее передача не проблема:

select 'pg_database_size(oid)'::regprocedure; -- create "reference"
     regprocedure      
-----------------------
 pg_database_size(oid)

Используйте regprocedure в качестве типа параметра.

Проблема, которую я еще не выяснил, состоит в том, как на самом деле назвать такую ​​вещь удобным способом.

1 голос
/ 01 декабря 2011

Я думаю, что вы не можете, но, поскольку нет анонимных функций, передается имя функции.

0 голосов
/ 16 августа 2018

Старый вопрос и уже есть принятый ответ. Но это не ясно объясняет, как это сделать. Поэтому я подумал добавить более четкий ответ.

Предположим, что вы передали имя функции обратного вызова своей основной функции в качестве значения varchar.

CREATE OR REPLACE FUNCTION public.get_function_fields(fn_name character varying)
    ...
    ...

Теперь, если вы хотите вызвать эту fn_name функцию внутри запроса, вам нужно использовать команду EXECUTE и правильно привести имя вашей функции, используя regproc, как показано ниже.

EXECUTE 'create temp table if not exists temp_call as select * from ' || fn_name::regproc || '() limit 1';

Важной частью является следующее: ...|| fn_name::regproc || '()... Как видите, вы должны добавить круглые скобки и привести имя функции с помощью ::regproc.

Надеюсь, это кому-нибудь поможет!

...