如何检测Postgres临时表是否已存在?

时间:2012-06-27 11:06:28

标签: java sql postgresql

我有一个名为 tester 的表,我需要用临时表覆盖以进行一些测试。到目前为止,我已经使用以下方法进行了管理:

CREATE TEMPORARY TABLE tester AS
  SELECT * FROM tester WHERE name='bananas';

这个临时表将在会话结束时消失,我很好,但是外部应用程序负责连接,并且它倾向于缓存连接以便重用(因此无法保证临时表已被删除)。这意味着如果我再次尝试执行上述查询,它可能会失败,因为临时表仍然存在。

显式删除临时表实际上不是一个选项。我宁愿忍受失败的查询而不是冒险丢弃潜在的“真实”表格。

想要做的只是创建临时表(如果它尚不存在)。 我确实找到了这个查询,在查看表是否存在时,应该使用人们建议的查询:

SELECT * FROM pg_catalog.pg_class WHERE relkind = 'r' AND relname = 'tester';

result when temporary table exists:

 relname | relnamespace | reltype | relowner | relam | relfilenode | reltablespace | relpages | reltuples | reltoastrelid | reltoastidxid | relhasindex | relisshared | relkind | relnatts | relchecks | reltriggers | relukeys | relfkeys | relrefs | relhasoids | relhaspkey | relhasrules | relhassubclass | relfrozenxid | relacl | reloptions
---------+--------------+---------+----------+-------+-------------+---------------+----------+-----------+---------------+---------------+-------------+-------------+---------+----------+-----------+-------------+----------+----------+---------+------------+------------+-------------+----------------+--------------+--------+------------
 tester  |         2200 | 1533065 |  1531747 |     0 |     1533063 |             0 |        0 |         0 |       1533067 |             0 | t           | f           | r       |        3 |         0 |           0 |        0 |        0 |       0 | f          | t          | f           | f              |     17654031 |        |
 tester  |      1533088 | 1533065 |  1531747 |     0 |     1533160 |             0 |        0 |         0 |       1533163 |             0 | f           | f           | r       |        3 |         0 |           0 |        0 |        0 |       0 | f          | f          | f           | f              |     17654066 |        |

如您所见,有两条记录。一个用于原始表,一个用于临时表。第二个记录是临时表 - 我知道这是因为它在不同的会话中工作时消失了 - 但除了缺少索引或主键之外,这是我可以将其识别为临时的唯一方法。这只是一个测试表 - 我正在使用的一些真正的表可能缺少索引和/或主键。

问题(tl; dr edition):如果已经存在一个具有相同名称的“真实”表,我如何测试临时表是否存在?(或至少确定一个表是临时的?)

免责声明:我添加了Java标记,因为我正在使用它来执行查询(SQL只是应用程序的一小部分)。尽管Java与问题没有直接关系,但我还是需要回答我可以在Java环境中使用的问题。

3 个答案:

答案 0 :(得分:5)

用户定义函数,用于检查临时表是否存在。

CREATE or REPLACE FUNCTION public.iftableexists( varchar)
RETURNS pg_catalog.bool AS
$BODY$
DECLARE

 BEGIN

     /* check the table exist in database and is visible*/
 perform n.nspname ,c.relname
FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid
= c.relnamespace
where n.nspname like 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid)
AND Upper(relname) = Upper($1);

     IF FOUND THEN
        RETURN TRUE;
     ELSE
        RETURN FALSE;
     END IF;

 END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE

See here for more details

答案 1 :(得分:2)

  

我只想创建临时表(如果有的话)   还不存在。

CREATE TEMPORARY TABLE IF NOT EXISTS tester AS
  SELECT * FROM tester WHERE name='bananas';

答案 2 :(得分:2)

这对我有用:

SELECT EXISTS (
   SELECT 1
   FROM   information_schema.tables 
   WHERE  table_schema like 'pg_temp_%'
   AND table_name=LOWER('table_name')
)