PostgreSQL 数据类型介绍(五)OID的理解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostgreSQL 数据类型介绍(五)OID的理解相关的知识,希望对你有一定的参考价值。
参考技术A那oid在哪儿?到底为什么会出现这种情况 ?
来看看postgres官网对 oid的介绍:
根据stackoverflow的高票用户的回答:
*OIDs basically give you a built-in, globally unique id for every row, contained in a system column (as opposed to a user-space column). That\'s handy for tables where you don\'t have a primary key, have duplicate rows, etc. For example, if you have a table with two identical rows, and you want to delete the oldest of the two, you could do that using the oid column.
In my experience, the feature is generally unused in most postgres-backed applications (probably in part because they\'re non-standard), and their use is essentially deprecated :
In PostgreSQL 8.1 default_with_oids is off by default; in prior versions of PostgreSQL, it was on by default.
The use of OIDs in user tables is considered deprecated, so most installations should leave this variable disabled. Applications that require OIDs for a particular table should specify WITH OIDS when creating the table. This variable can be enabled for compatibility with old applications that do not follow this behavior.
大意是你要是有个表没有用主键,这时候可以把oid充当为主键使用,当然这是没办法的办法。
总结: oid是给内部表做标识用的,不推荐使用。 建议将 default_with_oids 设置为off。 建表的时候,如果想使用主键,请自行建立。oid本身大小固定的,万一 行数超过了oid 的最大限制数(4 byte int),那就无法插入新行了。
PostgreSQL plpgsql 获取当前程序 oid
【中文标题】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 数据类型介绍(五)OID的理解的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL数据库公开课视频及PGCE认证(第五期)(CUUG)(2020年)