PostgreSQL plpgsql获取当前过程oid

PostgreSQL plpgsql获取当前过程oid,postgresql,plpgsql,Postgresql,Plpgsql,是否可以在函数中获取当前OID?比如: CREATE FUNCTION foo() RETURNS numeric LANGUAGE plpgsql AS ' BEGIN return THIS_FUNCTIONS_OID; END '; 我需要这个,因为我在不同的模式中创建了函数foo,所以函数名在这里没有帮助。我想你看起来很像 从pg_proc返回select oid,其中proname='$0' 我怀疑你能把它当作变量。您可以从当前的_查询中获取名称,但它将非常不可靠

是否可以在函数中获取当前OID?比如:

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

我需要这个,因为我在不同的模式中创建了函数foo,所以函数名在这里没有帮助。

我想你看起来很像

从pg_proc返回select oid,其中proname='$0'


我怀疑你能把它当作变量。您可以从当前的_查询中获取名称,但它将非常不可靠。。。除非每次调用时都将函数名定义为第一个参数:,否则可以使用$1,但它也不太可靠…

我不知道您在做什么,但我肯定您做得不好:。通常,这些奇怪的需求与奇怪的设计相关,导致代码难以维护

但使用PostgreSQL 9.4及更高版本,您可以轻松获得当前函数的oid。此信息在C PL函数中很容易访问,但它隐藏在PLpgSQL中。如果函数来自公共模式以外的其他模式,则更容易:

对于来自公共模式的函数,这有点困难-存在不一致性,如果不显式地添加前缀public,则当public不在搜索路径中时,cast to regprocedure不应工作。一般解决方案还需要几行:

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;

我不太清楚,但是。。。为什么?你想用这个来解决什么问题?最后,我想得到创建函数的模式的名称。我需要这个来在运行时操纵搜索路径。我认为这是不可能的。请参阅一位主要的博士后投稿人。他后来添加了,这将为您提供函数名,但不幸的是,它似乎没有对任何模式进行限定。感谢这些信息!这对我没有帮助。函数foo是在搜索路径中的不同模式中创建的。因此,我们的select将返回多个oid。哦,然后只返回硬编码的架构名称?。。在不同的方案中,每个foo都不同。这里没有选择。我肯定你做得不好-嗯@Pavel我使用了你提供的代码谢谢!所以要捕获我正在运行的过程的名称。我在记录成功/失败信息和/或向调用者上游传递类似信息时提供过程名称。有更好的方法吗?还是我做的也很糟糕?@Wellspring——很难说——在更多的模式中使用同名函数通常是不好的。这不是典型的,然后你需要做一些非常具体的代码。从另一方面来说,这段代码并不是很疯狂——所以也不是太糟糕。这并不典型。Source一些奇怪的问题可能来自其他数据库的端口,这些数据库的功能略有不同。但这就是生活。
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;