在PostgreSQL 9.1 中,如果角色已存在,則使用CREATE ROLE 角色建立角色會失敗。在編寫資料庫建立和角色管理腳本時,此限制帶來了挑戰。理想的解決方案是僅在角色不存在時有條件地執行 CREATE ROLE 語句。
一種方法是利用PL/pgSQL 的DO 區塊和IF EXISTS 條件:
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$;
此腳本使用SELECT 動態檢查角色是否存在並執行CREATE ROLE僅當角色不存在時。
此解不會引入競爭條件。 IF 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中文網其他相關文章!