我在CREATE TABLE语句中有以下行:
field1_id bigint DEFAULT nextval('table1_field1_id_seq'::regclass) NOT NULL,
regclass在上面表示什么?是否绝对需要添加::regclass
?
N.B:我看过Postgresql文档link,该文档讲述regclass
,但无法理解。
答案 0 :(得分:51)
不,在调用接受regclass
参数的nextval
这样的函数时,您不需要转换为regclass
,因为从text
到regclass
有一个隐含的强制转换regclass
。在其他一些情境中,可能需要明确转换为::regclass
。
<强>解释强>
::integer
是演员,如regclass
。
oid
是一种“魔术”数据类型;它实际上是regclass
或“对象标识符”的别名。请参阅文档中的Object identifier types。转换为regclass
是一种快捷方式,可以说“这是关系的名称,请将其转换为该关系的oid”。转化为search_path
的人都知道pg_class
,而不是直接查询关系oid
的{{1}},因此转换为regclass并不完全等同于pg_class
。
表是关系。序列和视图也是如此。因此,您也可以通过强制转换来获取视图或序列的oid。
为text
和regclass
定义了隐式强制转换,因此如果省略显式强制转换并且您正在调用接受regclass
的函数,则会自动完成强制转换。所以你不需要它,例如,nextval
来电。
还有其他地方可以。例如,您无法直接将text
与oid
进行比较;所以你可以这样做:
regress=> select * from pg_class where oid = 'table1'::regclass;
但不是这样:
regress=> select * from pg_class where oid = 'table1';
ERROR: invalid input syntax for type oid: "table1"
LINE 1: select * from pg_class where oid = 'table1';
为了好玩,我试着写一个执行铸造到regclass
的等效操作的查询。不要使用它,它主要是为了好玩,并试图演示实际发生的事情。除非你真的对Pg的胆量如何工作感兴趣,否则你可以在这里停止阅读。
据我了解,'sequence_name'::regclass::oid
大致相当于以下查询:
WITH sp(sp_ord, sp_schema) AS (
SELECT
generate_series(1, array_length(current_schemas('t'),1)),
unnest(current_schemas('t'))
)
SELECT c.oid
FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid)
INNER JOIN sp ON (n.nspname = sp.sp_schema)
WHERE c.relname = 'sequence_name'
ORDER BY sp.sp_ord
LIMIT 1;
除了它更短,速度更快。有关current_schemas(...)
等的定义,请参阅System information functions
换句话说:
pg_class
中搜索具有匹配名称的关系,并将每个名称与其名称空间(架构)相关联search_path
答案 1 :(得分:0)
根据我对文档的理解,oid被细分为类型。 regclass
是表示关系的数据库对象(因此它们属于元数据表pg_class)。
它表示序列与DEFAULT
表达式之间的依赖关系(例如,如果在INSERT查询中未提供显式值,则表示生成默认值的过程),因此如果发出{{1}在序列上,查询将不会通过,除非它是级联的(通过编写DROP SEQUENCE ...
)。