35

シーケンスがPostgres(plpgsql)に存在するかどうかを確認するのコードを使用しようとしました。

シーケンスが存在しない場合に作成します。このコードを2回実行すると、例外が発生します。

シーケンス...はすでに存在します。

シーケンスが存在しない場合にのみシーケンスを作成するにはどうすればよいですか?

シーケンスが存在しない場合、メッセージは書き込まれず、エラーも発生しないため、シーケンスが存在する場合は毎回メッセージがログファイルに書き込まれるため、この質問の別の回答でストアドプロシージャを使用できません。

do $$
begin

SET search_path = '';
IF not EXISTS (SELECT * FROM pg_class
             WHERE relkind = 'S'
               AND oid::regclass::text = 'firma1.' || quote_ident('myseq'))
  THEN

SET search_path = firma1,public;

create sequence myseq;

END IF;

SET search_path = firma1,public;

end$$;

select nextval('myseq')::int as nr;
4

6 に答える 6

53

Postgres9.5以降

IF NOT EXISTSCREATE SEQUENCEPostgres9.5でに追加されました。これが今の簡単な解決策です。

CREATE SEQUENCE IF NOT EXISTS myschema.myseq;

しかし、とにかく時代遅れの答えの詳細を考慮してください...そしてあなたはまたは列
について知っていますか?serialIDENTITY

Postgres9.4以前

シーケンスは、名前空間を他のいくつかのテーブルのようなオブジェクトと共有します。マニュアル:

シーケンス名は、同じスキーマ内の他のシーケンス、テーブル、インデックス、ビュー、または外部テーブルの名前とは異なる必要があり ます。

大胆な強調鉱山。したがって、3つのケースがあります。

  1. 名前が存在しません。->シーケンスを作成します。
  2. 同じ名前のシーケンスが存在します。->何もしませんか?出力はありますか?ロギングはありますか?
  3. 同じ名前の他の競合するオブジェクトが存在します。 ->何かしますか?出力はありますか?ロギングはありますか?

どちらの場合も何をするかを指定します。ステートメントは次のDOようになります。

DO
$do$
DECLARE
   _kind "char";
BEGIN
   SELECT relkind
   FROM   pg_class
   WHERE  oid = 'myschema.myseq'::regclass  -- sequence name, optionally schema-qualified
   INTO  _kind;

   IF NOT FOUND THEN       -- name is free
      CREATE SEQUENCE myschema.myseq;
   ELSIF _kind = 'S' THEN  -- sequence exists
      -- do nothing?
   ELSE                    -- object name exists for different kind
      -- do something!
   END IF;
END
$do$;

マニュアルによるオブジェクトタイプ(relkindpg_class

r=通常のテーブル
i=インデックス
S=シーケンス
v=ビュー
m=マテリアライズドビュー
c=複合型
t=TOASTテーブル
f=外部テーブル

関連している:

于 2012-12-06T22:42:12.297 に答える
13

私は別のルートに行きました:例外をキャッチするだけです:

DO
$$
BEGIN
        CREATE SEQUENCE myseq;
EXCEPTION WHEN duplicate_table THEN
        -- do nothing, it's already there
END
$$ LANGUAGE plpgsql;

これの優れた利点の1つは、現在のスキーマが何であるかを心配する必要がないことです。

于 2014-06-05T02:21:57.380 に答える
10

潜在的に存在するシーケンスを保持する必要がない場合は、それを削除してから再作成することができます。

DROP SEQUENCE IF EXISTS id_seq;
CREATE SEQUENCE id_seq;
于 2015-09-15T19:59:40.670 に答える
3

PostgresにはありませんCREATE SEQUENCE IF NOT EXISTS。シーケンスをドロップしただけで、テーブルにシーケンスを使用したデフォルト値がある場合、エラーが発生する可能性があります。

エラー:他のオブジェクトがシーケンス(sequence_name)に依存しているため、シーケンス(sequence_name)を削除できませんSQL状態:2BP01

私にとって、これは役に立ちます:

ALTER TABLE <tablename> ALTER COLUMN id DROP DEFAULT;
DROP SEQUENCE IF EXISTS <sequence_name>;
CREATE sequence <sequence_name>;
于 2016-04-19T03:44:48.533 に答える
0

シーケンスに関する情報は、information_schema.sequences参照)から取得できます。

このようなものを試してください(テストされていません):

...
IF not EXISTS (SELECT * FROM information_schema.sequences
    WHERE sequence_schema = 'firma1' AND sequence_name = 'myseq') THEN
...
于 2012-12-06T21:36:57.690 に答える
0

データベースアプリケーションのすべてのテーブルをいつでもクリーンアップする機能があります。動的にビルドされますが、本質的には、各テーブルからすべてのデータを削除し、シーケンスをリセットします。これは、テーブルの1つのシーケンスをリセットするためのコードです。

perform relname from pg_statio_all_sequences where relname = 'privileges_id_seq';
if found then
  select setval ('privileges_id_seq',1, false) into i_result;
end if;

お役に立てれば、

Loek

私はpostgres8.4を使用していますが、9.2を使用しているようです。情報が保存される場所に違いをもたらす可能性があります。

于 2012-12-07T14:53:45.940 に答える