PostgreSQL全局临时表(pgtt)——兼容oracle

0、概述

PostgreSQL中的临时表是会话级别的,即在会话结束后会自动被删除,或者可以设置为事务级别的,即在事务结束后自动被删除。也就是说不支持oracle的全局临时表的功能,除此之外,Oracle全局临时表是可以指定SCHEMA的,而PostgreSQL的临时表不能指定SCHEMA,会自动在temp临时SCHEMA中创建。
Pgtt是PostgreSQL的一个插件,可以用来兼容创建、管理和使用Oracle风格的全局临时表。

1、安装

**下载地址:**https://github.com/darold/pgtt

要安装pgtt扩展插件,必须使用pg9.5以上的版本。下载完之后直接解压安装即可:

make
make install

2、使用

在需要使用全局临时表的所有数据库中,使用以下命令创建扩展:

bill@bill=>create extension pgtt;
CREATE EXTENSION

我们可以手动开启/关闭该扩展,例如:

bill@bill=>SET pgtt.enabled TO off;
SET
bill@bill=>SET pgtt.enabled TO on;
SET

当我们需要使用该扩展时,首先需要使用超级用户去加载:

bill@bill=>LOAD 'pgtt';
LOAD

pgtt中相关的对象都在pgtt_schema的schema下面,该schema始终位于search_path的末尾:

bill@bill=>show search_path ;
       search_path       
-------------------------
 bill,public,pgtt_schema
(1 row)

当我们安装完pgtt扩展后,会自动将pgtt_schema加载到search_path中。

创建全局临时表:
使用pgtt创建全局临时表的语法如下:

CREATE GLOBAL TEMPORARY TABLE test_gtt_table (
	id integer,
	lbl text
) ON COMMIT { PRESERVE | DELETE } ROWS;

但是需要注意:GLOBAL关键字已过时,但可以安全使用,唯一的是它将生成警告:

WARNING:  GLOBAL is deprecated in temporary table creation

因此我们推荐将GLOBAL关键字进行注释使用:

扫描二维码关注公众号,回复: 12653266 查看本文章
CREATE /*GLOBAL*/ TEMPORARY TABLE test_gtt_table (
	LIKE other_table LIKE
	INCLUDING DEFAULTS
	INCLUDING CONSTRAINTS
	INCLUDING INDEXES
) ON COMMIT { PRESERVE | DELETE } ROWS;
 

例子:
建表:

bill@bill=>CREATE /*GLOBAL*/ TEMPORARY TABLE test_tt (id int, lbl text) ON COMMIT PRESERVE ROWS;
CREATE TABLE

插入数据:

bill@bill=>INSERT INTO test_tt VALUES (1, 'one'), (2, 'two'), (3, 'three');
INSERT 0 3

查看:

bill@bill=>select * from test_tt ;
 id |  lbl  
----+-------
  1 | one
  2 | two
  3 | three
(3 rows)

我们也可以在全局临时表上创建索引:

bill@bill=>create index idx_test on test_tt (id);
CREATE INDEX

删除表:
这里需要注意,我们不能删除正在使用的全局临时表。

bill@bill=>drop table test_tt ;
ERROR:  can not drop a GTT that is in use.

要先确保被删除的表没有在被使用才能删除:

bill@bill=>SET pgtt.enabled TO off;
SET
bill@bill=>drop table test_tt ;    
DROP TABLE

另外需要注意的是,我们也不能在全局临时表上使用外键和分区,尽管这些在PostgreSQL的临时表上是被允许的,但是为了兼容oracle的全局临时表,pgtt中并不允许这么使用:

CREATE GLOBAL TEMPORARY TABLE t1 (c1 integer, FOREIGN KEY (c1) REFERENCES source (id));
ERROR:  attempt to create referential integrity constraint on global temporary table

3、总结

尽管PostgreSQL已经支持会话级和事务级的临时表,但是不支持类似oracle的全局临时表,虽然我们可以在使用的时候通过其它方式去代替,但是对于从oracle迁移到PostgreSQL的系统来说,能够直接使用和oracle风格一致的全局临时表还是很方便的。

参考链接:
https://github.com/darold/pgtt
https://www.postgresql.org/docs/12/sql-createtable.html

猜你喜欢

转载自blog.csdn.net/weixin_39540651/article/details/107491290
今日推荐