在 PostgreSQL 9.1 中,使用 CREATE ROLE my_user LOGIN 等简单脚本创建不存在的 ROLE如果用户已存在,则 PASSWORD 'my_password' 可能会失败。为了避免这个错误,需要一种更复杂的方法。
一个有效的解决方案是在 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中文网其他相关文章!