7

テストを行うために一時テーブルでオーバーレイする必要があるテスターというテーブルがあります。これまでのところ、次を使用して管理してきました。

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 |        |

ご覧のとおり、2 つのレコードがあります。1 つは元のテーブル用で、もう 1 つは一時テーブル用です。2 番目のレコードは一時テーブルです。これは、別のセッションで作業しているときに消えてしまうのでわかりますが、一時テーブルとして識別できる唯一の方法は、インデックスまたは主キーがないことです。これは単なるテスト テーブルです。私が使用している実際のテーブルには、インデックスや主キーがないものもあります。

質問 (tl;dr 版):同じ名前の「実際の」テーブルが既に存在する場合、一時テーブルが存在するかどうかをテストするにはどうすればよいですか? (または、少なくともテーブルが一時的なものであることを識別しますか?)

免責事項: Java タグを追加したのは、クエリを実行するために使用しているためです (SQL はアプリケーションのほんの一部です)。Java は質問に直接関係していませんが、Java コンテキストから使用できる回答が必要です。

4

4 に答える 4

8

一時テーブルが存在するかどうかを確認するユーザー定義関数。

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

詳しくはこちら

于 2012-06-27T11:11:30.597 に答える
0

like必要な情報を含む列があるのに、なぜ「あいまい検索」をしたいのかわかりません。たぶん、私が気付いていない下位互換性の問題がいくつかあります。

これは上記と同じコードですが、table_type = 'LOCAL TEMPORARY代わりにlike 'pg_temp_%'

SELECT EXISTS (
   SELECT 1
   FROM information_schema.tables 
   WHERE table_type = 'LOCAL TEMPORARY'
   AND table_name = 'table_name'
)
于 2021-09-17T12:14:35.860 に答える