2015-08-14 4 views
2

Возможно ли получить текущий OID внутри функции? Как:PostgreSQL plpgsql получить текущие процедуры oid

CREATE FUNCTION foo() 
RETURNS numeric 
LANGUAGE plpgsql 
AS ' 
    BEGIN 
    return THIS_FUNCTIONS_OID; 
    END 
'; 

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

+0

Не уверен, что у меня на голове, но ... * why *? Какую проблему вы пытаетесь решить с этим? –

+0

В конце концов, я хочу получить имя схемы, в которой была создана функция. Мне нужно это, чтобы манипулировать 'search_path' во время выполнения. – maroonyw

+1

Я не думаю, что это возможно. См. [Этот ответ] (http://stackoverflow.com/a/12620168/1104979) от одного из главных участников Postgres. С тех пор он добавил [поддержку дескрипторов callstack] (http://www.postgresql.org/message-id/[email protected]om), которая даст вам имя функции, но, к сожалению, она не кажется схема - квалифицировать что угодно. –

ответ

0

Я предполагаю, что вы ищете, как

л

return select oid from pg_proc where proname='$0';

Я сомневаюсь, что вы можете получить его в качестве переменной. Вы можете получить имя от current_query(), но оно будет очень ненадежным ... Если вы не определяете имя функции как первый аргумент каждый раз, когда вы его вызываете :), то вы можете использовать $ 1, но он не очень надежный ...

+0

Это мне не помогает. Функция 'foo' была создана в разных схемах (все в' search_path'). Таким образом, наш выбор вернет больше, чем один. – maroonyw

+0

oh тогда просто верните имя жестко запрограммированной схемы? .. по-разному для каждого foo в другой схеме –

+0

Здесь нет выбора. – maroonyw

1

Я не знаю, что вы делаете, но я уверен, что вы не делаете это хорошо :). Обычно эти странные требования связаны со странным дизайном и приводят к тому, что код трудно поддерживать.

Но вы можете легко получить oid текущей функции с помощью PostgreSQL 9.4 и выше. (Эта информация легко доступна в функциях C PL, но она скрыта в PLpgSQL.) Гораздо проще, если ваши функции из других схем, чем public:

CREATE OR REPLACE FUNCTION omega.inner_func() 
RETURNS oid AS $$ 
DECLARE 
    stack text; fcesig text; 
BEGIN 
    GET DIAGNOSTICS stack = PG_CONTEXT; 
    fcesig := substring(stack from 'function (.*?) line'); 
    RETURN fcesig::regprocedure::oid; 
END; 
$$ LANGUAGE plpgsql; 

Для функций из public схемы это немного больше сложно - существует несогласованность и без явного добавления префикса «публичный» приведение к regprocedure не должно работать, если public не находится в search_path. Для общего решения требуются еще несколько линий:

CREATE OR REPLACE FUNCTION omega.inner_func() 
RETURNS oid AS $$ 
DECLARE 
    stack text; fcesig text; retoid oid; 
BEGIN 
    GET DIAGNOSTICS stack = PG_CONTEXT; 
    fcesig := substring(stack from 'function (.*?) line'); 
    retoid := to_regprocedure(fcesig::cstring); 
    IF retoid IS NOT NULL THEN RETURN retoid; END IF; 
    RETURN to_regprocedure(('public.' || fcesig)::cstring); 
END; 
$$ LANGUAGE plpgsql; 
Смежные вопросы