Maison >base de données >tutoriel mysql >Comment puis-je créer des rôles PostgreSQL de manière conditionnelle pour éviter les erreurs ?

Comment puis-je créer des rôles PostgreSQL de manière conditionnelle pour éviter les erreurs ?

DDD
DDDoriginal
2024-12-17 19:37:10556parcourir

How Can I Create PostgreSQL Roles Conditionally to Avoid Errors?

Création de rôles PostgreSQL avec exécution conditionnelle

Introduction au problème

Dans PostgreSQL 9.1, la création d'un rôle à l'aide de CREATE ROLE échoue si le rôle existe déjà. Cette limitation pose un défi lors de la création de scripts de base de données et de gestion des rôles. Une solution souhaitée consiste à exécuter l'instruction CREATE ROLE de manière conditionnelle, uniquement si le rôle n'existe pas.

Développement de script conditionnel

Une approche consiste à utiliser le bloc DO de PL/pgSQL et la condition 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$;

Ce script vérifie dynamiquement l'existence du rôle à l'aide de SELECT et exécute CREATE ROLE uniquement si le rôle ne le fait pas. existent.

Aucun scénario de condition de concurrence

Cette solution n'introduit pas de condition de concurrence. La condition IF EXISTS garantit que le rôle est créé uniquement s'il n'existe pas au moment de la vérification. Toute transaction simultanée créant le rôle entre le contrôle et la création ne posera pas de problème car le rôle existera déjà au moment de l'exécution de CREATE ROLE.

Script optimisé (sans gestion des exceptions)

Pour optimiser davantage le script, un bloc imbriqué peut être utilisé pour éviter le coût d'un gestionnaire d'exceptions :

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$;

Ce script effectue la vérification efficacement et gère tout condition de concurrence potentielle avec une surcharge minimale. Le bloc imbriqué garantit que le rôle est créé uniquement s'il n'existe pas ou si une transaction concurrente vient de le créer, auquel cas une notification est émise.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn