I have a table called tester which I need to overlay with a temporary table in order to do some testing. So far I have managed that using:
CREATE TEMPORARY TABLE tester AS
SELECT * FROM tester WHERE name='bananas';
This temporary table will disappear at the end of the session which is fine by me, however it is the external application that is responsible for the connection and it has a tendency to cache connections for reuse (thus there is no guarantee that the temporary table has been dropped). This means that if I try to execute the above query again it may fail because the temporary table still exists.
Explicitly dropping the temporary table is not really an option. I'd rather live with the failed query than risk dropping the underlying "real" table by mistake.
What I would like to do is only create the temporary table if it doesn't already exist.
I did find this query which people suggested should be used when checking to see if a table exists:
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 | |
As you can see, there are two records. One for the original table, and one for the temp table. The second record is the temporary table - I know this because it disappears when working in a different session - but other than the lack of an index or a primary key that's the only way I can identify it as being temporary. This is only a test table - some of the real tables I'm working with may lack indexes and/or primary keys.
Question (tl;dr edition): How can I test if a temporary table exists if there is already a "real" table with the same name? (or at least identify that a table is temporary?)
disclaimer: I added the Java tag because that's what I'm using to execute queries (the SQL is only a small part of the application). Even though Java is not directly relevant to the question, I kinda need than answer that I can use from a Java context.
解决方案
User Defined Function to check whether temp table exists.
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