PostgreSQL 9.1 では、CREATE ROLE my_user LOGIN のような単純なスクリプトを使用して存在しない ROLE を作成しますユーザーがすでに存在する場合、PASSWORD 'my_password' は失敗する可能性があります。このエラーを回避するには、より洗練されたアプローチが必要です。
効果的な解決策の 1 つは、PL/pgSQL のような手続き型言語で DO ステートメントを使用することです。
DO $do$ BEGIN IF EXISTS ( SELECT FROM pg_catalog.pg_roles WHERE rolname = 'my_user') THEN RAISE NOTICE 'Role "my_user" already exists. Skipping.'; ELSE CREATE ROLE my_user LOGIN PASSWORD 'my_password'; END IF; END $do$;
このスクリプトは、EXISTS ステートメントを使用してロールがすでに存在するかどうかを確認します。存在する場合、通知が発行され、作成はスキップされます。それ以外の場合、ロールは作成されます。
競合の多いワークロードの場合、ネストされたブロック内に CREATE ROLE ステートメントをネストすることで、さらに最適化できます。
DO $do$ BEGIN IF EXISTS ( SELECT FROM pg_catalog.pg_roles WHERE rolname = 'my_user') THEN RAISE NOTICE 'Role "my_user" already exists. Skipping.'; ELSE BEGIN -- nested block CREATE ROLE my_user LOGIN PASSWORD 'my_password'; EXCEPTION WHEN duplicate_object THEN RAISE NOTICE 'Role "my_user" was just created by a concurrent transaction. Skipping.'; END; END IF; END $do$;
このネストされたブロックにより、可能性の低い競合状態が発生した場合にのみロールが作成されることが保証されます。これにより、例外の発生とキャッチに関連するパフォーマンスのオーバーヘッドが大幅に削減されます。
以上がPostgreSQL ロールがまだ存在しない場合に安全に作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。