web-dev-qa-db-fra.com

MySQL: Vérifiez si l'utilisateur existe et supprimez-le

Il n’existe pas de méthode standard pour vérifier s’il existe un utilisateur MySQL et le supprimer. Y at-il des solutions de contournement pour cela?

Edit: J'ai besoin d'une méthode simple pour exécuter ceci sans générer d'erreur
par exemple.

DROP USER test@localhost; :    
79
Cherian

Depuis MySQL 5.7, vous pouvez faire un DROP USER IF EXISTS test

Plus d'infos: http://dev.mysql.com/doc/refman/5.7/en/drop-user.html

39
JavierCane

Cela a fonctionné pour moi:

GRANT USAGE ON *.* TO 'username'@'localhost';
DROP USER 'username'@'localhost';

Cela crée l'utilisateur s'il n'existe pas déjà (et lui accorde un privilège inoffensif), puis le supprime d'une manière ou d'une autre. Solution trouvée ici: http://bugs.mysql.com/bug.php?id=19166

Mises à jour: @ Hao recommande ajouter IDENTIFIED BY; @andreb (dans les commentaires) suggère de désactiver NO_AUTO_CREATE_USER.

88
phyzome

A la réponse de phyzome (la plus votée), il me semble que si vous mettez "identifié par" à la fin de la déclaration de subvention, l'utilisateur sera créé automatiquement. Mais si vous ne le faites pas, l'utilisateur n'est pas créé. Le code suivant fonctionne pour moi,

GRANT USAGE ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password';
DROP USER 'username'@'localhost';

J'espère que cela t'aides.

13
Hao

J'ai trouvé la réponse à cette question sur l'un des forums MySQL. Nous devrons utiliser une procédure pour supprimer l’utilisateur.

L'utilisateur est ici "test" et "databaseName" le nom de la base de données.


SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI';
USE databaseName; 
 PASSER LA PROCEDURE SI EXISTE databaseName.drop_user_if_exists; 
 DELIMITER $$ 
 CRÉER UNE PROCÉDURE databaseName.drop_user_if_exists () 
 COMMENCER 
 DÉCLARER foo BIGINT DEFAULT 0; 
 CHOISIR LE COMPTE (*) 
 DANS foo 
 FROM mysql .user 
 WHERE User = 'test' et Host = 'localhost'; 
 SI foo> 0 ALORS 
 DROP USER 'test' @ 'localhost'; 
 END IF; 
 END; $$ 
 DELIMITER; 
 CALL databaseName.drop_user_if_exists (); 
 DROP DE LA PROCÉDURE SI EXISTE databaseName.drop_users_if_exists; 
 SET SQL_MODE = @ OLD_SQL_MODE;


CREATE USER 'test' @ 'localhost' IDENTIFIÉ PAR 'a'; Accordez tous les privilèges sur databaseName. * TO 'test' @ 'localhost' AVEC OPTION GRANT </ code>
13
Cherian
DROP USER IF EXISTS 'user'@'localhost' ;

cela fonctionne pour moi sans générer d'erreurs dans Maria DB, cela devrait fonctionner pour vous aussi

4
Sathish Neel

Mise à jour: À partir de MySQL 5.7, vous pouvez utiliser l'instruction DROP USER IF EXISTS. Réf.: https://dev.mysql.com/doc/refman/5.7/en/drop-user.html

Syntaxe: DROP USER [IF EXISTS] user [, user] ...

Exemple: DROP USER IF EXISTS 'jeffrey'@'localhost';

Pour votre information (et pour les anciennes versions de MySQL), c'est une meilleure solution ... !!!

Ce qui suit SP vous aidera à supprimer l’utilisateur 'tempuser'@'%' En exécutant CALL DropUserIfExistsAdvanced('tempuser', '%');

Si vous souhaitez supprimer tous les utilisateurs nommés 'tempuser' (Disons 'tempuser'@'%', 'tempuser'@'localhost' Et 'tempuser'@'192.168.1.101'), Exécutez SP comme CALL DropUserIfExistsAdvanced('tempuser', NULL); Ceci supprimera tous les utilisateurs nommés tempuser !!! sérieusement ...

Maintenant, s'il vous plaît jeter un oeil sur mentionné SP DropUserIfExistsAdvanced:

DELIMITER $$

DROP PROCEDURE IF EXISTS `DropUserIfExistsAdvanced`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `DropUserIfExistsAdvanced`(
    MyUserName VARCHAR(100)
    , MyHostName VARCHAR(100)
)
BEGIN
DECLARE pDone INT DEFAULT 0;
DECLARE mUser VARCHAR(100);
DECLARE mHost VARCHAR(100);
DECLARE recUserCursor CURSOR FOR
    SELECT `User`, `Host` FROM `mysql`.`user` WHERE `User` = MyUserName;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET pDone = 1;

IF (MyHostName IS NOT NULL) THEN
    -- 'username'@'hostname' exists
    IF (EXISTS(SELECT NULL FROM `mysql`.`user` WHERE `User` = MyUserName AND `Host` = MyHostName)) THEN
        SET @SQL = (SELECT mResult FROM (SELECT GROUP_CONCAT("DROP USER ", "'", MyUserName, "'@'", MyHostName, "'") AS mResult) AS Q LIMIT 1);
        PREPARE STMT FROM @SQL;
        EXECUTE STMT;
        DEALLOCATE PREPARE STMT;
    END IF;
ELSE
    -- check whether MyUserName exists (MyUserName@'%' , MyUserName@'localhost' etc)
    OPEN recUserCursor;
    REPEAT
        FETCH recUserCursor INTO mUser, mHost;
        IF NOT pDone THEN
            SET @SQL = (SELECT mResult FROM (SELECT GROUP_CONCAT("DROP USER ", "'", mUser, "'@'", mHost, "'") AS mResult) AS Q LIMIT 1);
            PREPARE STMT FROM @SQL;
            EXECUTE STMT;
            DEALLOCATE PREPARE STMT;
        END IF;
    UNTIL pDone END REPEAT;
END IF;
FLUSH PRIVILEGES;
END$$

DELIMITER ;

Utilisation:

CALL DropUserIfExistsAdvanced('tempuser', '%'); pour supprimer l'utilisateur 'tempuser'@'%'

CALL DropUserIfExistsAdvanced('tempuser', '192.168.1.101'); pour supprimer l'utilisateur 'tempuser'@'192.168.1.101'

CALL DropUserIfExistsAdvanced('tempuser', NULL); pour supprimer tous les utilisateurs nommés 'tempuser' (par exemple, disons 'tempuser'@'%', 'tempuser'@'localhost' et 'tempuser'@'192.168.1.101')

4
rajukoyilandy

Euh ... Pourquoi toutes les complications et astuces?

Plutôt que d'utiliser DROP USER ... Vous pouvez simplement supprimer l'utilisateur de la table mysql.user (qui ne génère pas d'erreur si l'utilisateur n'existe pas), puis supprimer les privilèges nécessaires pour appliquer la modification.

DELETE FROM mysql.user WHERE User = 'SomeUser' AND Host = 'localhost';
FLUSH PRIVILEGES;

-- MISE À JOUR --

J'avais tort. Ce n'est pas sûr de supprimer l'utilisateur comme ça. Vous devez utiliser DROP USER. Puisqu'il est possible de configurer les options de mysql pour ne pas créer d'utilisateurs automatiquement via des subventions (une option que j'utilise), je ne recommanderais toujours pas cette astuce. Voici un extrait d'une procédure stockée qui fonctionne pour moi:

DECLARE userCount INT DEFAULT 0;
SELECT COUNT(*) INTO userCount FROM mysql.user WHERE User = userName AND Host='localhost';
IF userCount > 0 THEN
    SET @S=CONCAT("DROP USER ", userName, "@localhost" );
    PREPARE stmt FROM @S;
    EXECUTE stmt;
    SELECT CONCAT("DROPPED PRE-EXISTING USER: ", userName, "@localhost" ) as info;
END IF;
FLUSH PRIVILEGES;
3
BuvinJ

En ce qui concerne la réponse de @ Cherian, les lignes suivantes peuvent être supprimées:

SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI';
...
SET SQL_MODE=@OLD_SQL_MODE;
...

C'était un bug pré-5.1.23. Après cette version, elles ne sont plus nécessaires. Donc, pour la commodité du copier/coller, voici la même chose avec les lignes ci-dessus supprimées. Encore une fois, à des fins d'exemple, "test" est l'utilisateur et "databaseName" est la base de données; et c'était de ce bug .

DROP PROCEDURE IF EXISTS databaseName.drop_user_if_exists ;
DELIMITER $$
CREATE PROCEDURE databaseName.drop_user_if_exists()
BEGIN
  DECLARE foo BIGINT DEFAULT 0 ;
  SELECT COUNT(*)
  INTO foo
    FROM mysql.user
      WHERE User = 'test' and  Host = 'localhost';
   IF foo > 0 THEN
         DROP USER 'test'@'localhost' ;
  END IF;
END ;$$
DELIMITER ;
CALL databaseName.drop_user_if_exists() ;
DROP PROCEDURE IF EXISTS databaseName.drop_users_if_exists ;

CREATE USER 'test'@'localhost' IDENTIFIED BY 'a';
GRANT ALL PRIVILEGES  ON databaseName.* TO 'test'@'localhost'
 WITH GRANT OPTION
2
j4w7
DROP USER 'user'@'localhost';

La commande ci-dessus supprimera l'utilisateur de la base de données. Cependant, il est important de savoir si le même utilisateur utilise déjà la base de données, cette session ne end jusqu'à ce que l'utilisateur ferme cette session. Il est important de noter que l'utilisateur perdu aura ENCORE accès à la base de données et effectuera toutes les opérations. L'APPUI DE L'UTILISATEUR NE DÉPASSE PAS LA SESSION D'UTILISATEUR ACTUELLE

2
Prabhakar

J'ai écrit cette procédure inspirée par la réponse de Cherian. La différence est que dans ma version, le nom d'utilisateur est un argument de la procédure (et non codé en dur). Je fais également un privilège FLUSH beaucoup nécessaire après avoir laissé tomber l'utilisateur.

DROP PROCEDURE IF EXISTS DropUserIfExists;
DELIMITER $$
CREATE PROCEDURE DropUserIfExists(MyUserName VARCHAR(100))
BEGIN
  DECLARE foo BIGINT DEFAULT 0 ;
  SELECT COUNT(*)
  INTO foo
    FROM mysql.user
      WHERE User = MyUserName ;
   IF foo > 0 THEN
         SET @A = (SELECT Result FROM (SELECT GROUP_CONCAT("DROP USER"," ",MyUserName,"@'%'") AS Result) AS Q LIMIT 1);
         PREPARE STMT FROM @A;
         EXECUTE STMT;
         FLUSH PRIVILEGES;
   END IF;
END ;$$
DELIMITER ;

J'ai également posté ce code sur le site Web CodeReview ( https://codereview.stackexchange.com/questions/15716/mysql-drop-user-if-exists )

2
MadSeb

En combinant la réponse de phyzome (qui ne fonctionnait pas tout de suite pour moi) avec le commentaire d'andreb (ce qui explique pourquoi cela ne fonctionnait pas), je me suis retrouvé avec ce code apparemment fonctionnel qui désactive temporairement le mode NO_AUTO_CREATE_USER s'il est actif:

set @mode = @@SESSION.sql_mode;
set session sql_mode = replace(replace(@mode, 'NO_AUTO_CREATE_USER', ''), ',,', ',');
grant usage on *.* to 'myuser'@'%';
set session sql_mode = @mode;
drop user 'myuser'@'%';
0
Svullo