PostgreSQL plpgsql 获取当前程序 oid

Posted

技术标签:

【中文标题】PostgreSQL plpgsql 获取当前程序 oid【英文标题】:PostgreSQL plpgsql get current procedures oid 【发布时间】:2015-08-14 09:01:32 【问题描述】:

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

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

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

【问题讨论】:

我不确定,但是……为什么?你想用这个解决什么问题? 最后,我想获取创建函数的模式的名称。我需要这个来在运行时操作search_path 我认为这不可能。请参阅来自 Postgres 主要贡献者之一的this answer。此后,他添加了support for callstack dumps,它将为您提供函数名称,但不幸的是,它似乎没有任何模式限定。 感谢您提供此信息! 【参考方案1】:

我猜你看起来很像

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

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

【讨论】:

这对我没有帮助。函数foo 是在不同的模式中创建的(都在search_path 中)。所以我们的选择会返回不止一个 oid。 哦,那么只返回硬编码的模式名称?.. 不同模式中的每个 foo 都不同 这里没有选项。【参考方案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”,则当public 不在@987654327 中时,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;

【讨论】:

“我确定你做得不好”——嗯...@Pavel 我使用了你提供的代码(谢谢!)所以要捕获我的程序的名称跑步。我在记录成功/失败信息和/或将类似信息上游传递给调用者时提供过程名称。有没有更好的方法来做到这一点?还是我做事也很糟糕? @Wellspring - 很难说 - 通常在更多模式中具有相同名称的函数是不好的。这不是典型的,然后你需要做一些非常具体的代码。另一方面,这段代码并不是很疯狂——所以还不算太糟糕。它只是不典型。来源 一些奇怪的问题可能来自其他数据库的端口,那里有一点不同的功能。但这就是生活。

以上是关于PostgreSQL plpgsql 获取当前程序 oid的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL:在 plpgsql 函数中回滚事务?

PostgreSQL - 继续 unique_violation (plpgsql)

在 postgresql 中使用 plpgsql 有啥好处

Postgresql - 从 plpgsql 函数返回记录 []

Postgresql plpgsql 多行循环

如何在 PostgreSQL 9.2 中分析 plpgsql 函数