シーケンスが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;
IF NOT EXISTS
がPostgres 9.5のCREATE SEQUENCE
に追加されました。それが今の簡単な解決策です:
CREATE SEQUENCE IF NOT EXISTS myschema.myseq;
しかし、とにかく古い回答の詳細を検討してください...
そして、あなたはserial
列について知っていますよね?
シーケンスの名前は、シーケンスだけでなく、いくつかのタイプのオブジェクトの名前と競合します。 マニュアル:
シーケンス名は、同じスキーマ内の他のシーケンス、テーブル、インデックス、ビュー、または外部テーブルの名前とは異なる必要があります。
大胆な強調鉱山。
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$;
マニュアルによると、pg_class
のオブジェクトタイプ(relkind
) :
r =通常のテーブル
i =インデックス
S =シーケンス
v =表示
m =マテリアライズドビュー
c =複合型
t = TOASTテーブル
f =外部テーブル
関連:
私は別のルートに行きました:例外をキャッチしてください:
DO
$$
BEGIN
CREATE SEQUENCE myseq;
EXCEPTION WHEN duplicate_table THEN
-- do nothing, it's already there
END
$$ LANGUAGE plpgsql;
これの1つの素晴らしい利点は、現在のスキーマが何であるかを気にする必要がないことです。
潜在的に存在するシーケンスを保持する必要がない場合は、それをドロップしてから再作成することができます。
DROP SEQUENCE IF EXISTS id_seq;
CREATE SEQUENCE id_seq;
PostgresにはCREATE SEQUENCE IF NOT EXISTS
と、シーケンスを削除しただけでシーケンスを使用したテーブルにデフォルト値がある場合、エラーが発生する可能性があります。
エラー:他のオブジェクトがシーケンスに依存しているため、シーケンス(sequence_name)を削除できませんSQL状態:2BP01
私にとって、これは助けることができます:
ALTER TABLE <tablename> ALTER COLUMN id DROP DEFAULT;
DROP SEQUENCE IF EXISTS <sequence_name>;
CREATE sequence <sequence_name>;
データベースアプリケーションのすべてのテーブルをいつでもクリーンアップする機能があります。動的に構築されますが、本質は、各テーブルからすべてのデータを削除し、シーケンスをリセットすることです。これは、テーブルの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;
お役に立てれば、
ろく
私はpostgres 8.4を使用していますが、9.2を使用しているようです。情報が保存される場所に違いが生じる可能性があります。
シーケンスに関する情報はinformation_schema.sequences
から取得できます( 参照 )
次のようなものを試してください(試していない):
...
IF not EXISTS (SELECT * FROM information_schema.sequences
WHERE sequence_schema = 'firma1' AND sequence_name = 'myseq') THEN
...