PostgreSQL plpgsql 获取当前程序oid

问题描述 投票:0回答:3

是否可以在函数内获取当前的OID?喜欢:

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

我需要这个,因为我在不同的模式中创建了函数

foo
,所以函数名称在这里没有帮助。

postgresql plpgsql
3个回答
4
投票

我猜你看起来像

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

我怀疑你能否将其作为变量获取。你可以从

current_query()
得到名字,但它会很不可靠...除非你每次调用它时都将函数名定义为第一个参数:),那么你可以使用$1,但它也不太可靠。 ..


2
投票

我不知道你在做什么,但我确信你做得不好:)。通常,这些奇怪的需求与奇怪的设计有关,并导致代码难以维护。

但是使用 PostgreSQL 9.4 及更高版本可以轻松获取当前函数的

oid
。 (此信息可以在 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
模式中的函数,有点困难 - 存在不一致,并且如果没有显式附加前缀“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;

0
投票

这是一个老问题,但从版本 16 开始,该功能似乎已由上面回答此问题的同一 Pavel 提交给 Postgres:

在 PL/pgSQL 中添加获取当前函数 OID 的功能 (Pavel 斯图勒)

这是通过 GET DIAGNOSTICS 变量 = PG_ROUTINE_OID 来完成的。 https://www.postgresql.org/docs/release/16.0/

这是提交: https://www.postgresql.org/message-id/E1pjkX2-001M2a-UE%40gemulon.postgresql.org

© www.soinside.com 2019 - 2024. All rights reserved.