No hay una forma estándar de verificar si existe un usuario de MySQL y, en función de eso, elimínelo. ¿Existen soluciones alternativas para esto?
Editar: necesito una forma directa de ejecutar esto sin arrojar un error,
por ejemplo
DROP USER test@localhost; :
Respuestas:
Desde MySQL 5.7 puede hacer un
DROP USER IF EXISTS test
Más información: http://dev.mysql.com/doc/refman/5.7/en/drop-user.html
fuente
Esto funcionó para mí:
GRANT USAGE ON *.* TO 'username'@'localhost'; DROP USER 'username'@'localhost';
Esto crea el usuario si aún no existe (y le otorga un privilegio inofensivo), luego lo elimina de cualquier manera. Solución encontrada aquí: http://bugs.mysql.com/bug.php?id=19166
Actualizaciones: @Hao recomienda agregar
IDENTIFIED BY
; @andreb (en los comentarios) sugiere deshabilitarNO_AUTO_CREATE_USER
.fuente
IDENTIFIED BY
para que esto realmente funcionara.A la respuesta de phyzome (la más votada), me parece que si pones "identificado por" al final de la declaración de concesión, el usuario se creará automáticamente. Pero si no lo hace, el usuario no se crea. El siguiente código funciona para mí,
GRANT USAGE ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password'; DROP USER 'username'@'localhost';
Espero que esto ayude.
fuente
Encontré la respuesta a esto en uno de los foros de MySQL. Necesitaremos usar un procedimiento para eliminar al usuario.
El usuario aquí es "prueba" y "databaseName" el nombre de la base de datos.
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI'; USE
databaseName
; DROP PROCEDURE IF EXISTSdatabaseName
.drop_user_if_exists
; DELIMITER $$ CREATE PROCEDUREdatabaseName
.drop_user_if_exists
() BEGIN DECLARE foo BIGINT DEFAULT 0 ; SELECT COUNT(*) INTO foo FROMmysql
.user
WHEREUser
= 'test' andHost
= 'localhost'; IF foo > 0 THEN DROP USER 'test'@'localhost' ; END IF; END ;$$ DELIMITER ; CALLdatabaseName
.drop_user_if_exists
() ; DROP PROCEDURE IF EXISTSdatabaseName
.drop_users_if_exists
; SET SQL_MODE=@OLD_SQL_MODE ;CREATE USER 'test'@'localhost' IDENTIFIED BY 'a'; GRANT ALL PRIVILEGES ON databaseName.* TO 'test'@'localhost' WITH GRANT OPTION
fuente
DROP USER IF EXISTS 'user'@'localhost' ;
eso funciona para mí sin arrojar ningún error en Maria DB, también debería funcionar para ti
fuente
Actualización: a partir de MySQL 5.7, puede usar
DROP USER IF EXISTS
statement. Ref: https://dev.mysql.com/doc/refman/5.7/en/drop-user.htmlFYI (y para la versión anterior de MySQL), esta es una mejor solución ... !!!
El siguiente SP le ayudará a eliminar el usuario
'tempuser'@'%'
ejecutandoCALL DropUserIfExistsAdvanced('tempuser', '%');
Si desea eliminar a todos los usuarios nombrados
'tempuser'
(digamos'tempuser'@'%'
,'tempuser'@'localhost'
y'tempuser'@'192.168.1.101'
) ejecute SP como ¡¡¡CALL DropUserIfExistsAdvanced('tempuser', NULL);
Esto eliminará todos los usuarios nombradostempuser
!!! seriamente...Ahora, por favor, eche un vistazo al SP mencionado
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 ;
Uso:
CALL DropUserIfExistsAdvanced('tempuser', '%');
para eliminar usuario'tempuser'@'%'
CALL DropUserIfExistsAdvanced('tempuser', '192.168.1.101');
para eliminar usuario'tempuser'@'192.168.1.101'
CALL DropUserIfExistsAdvanced('tempuser', NULL);
para eliminar todos los usuarios nombrados'tempuser'
(por ejemplo, decir'tempuser'@'%'
,'tempuser'@'localhost'
y'tempuser'@'192.168.1.101'
)fuente
Um ... ¿Por qué todas las complicaciones y trucos?
En lugar de usar DROP USER ... Simplemente puede eliminar al usuario de la tabla mysql.user (que no arroja un error si el usuario no existe), y luego eliminar los privilegios para aplicar el cambio.
DELETE FROM mysql.user WHERE User = 'SomeUser' AND Host = 'localhost'; FLUSH PRIVILEGES;
- ACTUALIZAR -
Estaba equivocado. No es seguro eliminar al usuario de esa manera. Necesita usar DROP USER. Dado que es posible tener las opciones de mysql configuradas para no crear usuarios automáticamente a través de subvenciones (una opción que uso), todavía no recomendaría ese truco. Aquí hay un fragmento de un procedimiento almacenado que funciona para mí:
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;
fuente
Con respecto a la respuesta de @ Cherian, se pueden eliminar las siguientes líneas:
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI'; ... SET SQL_MODE=@OLD_SQL_MODE; ...
Este fue un error anterior a 5.1.23. Después de esa versión, estos ya no son necesarios. Entonces, para la conveniencia de copiar / pegar, aquí es lo mismo con las líneas anteriores eliminadas. De nuevo, por ejemplo, "test" es el usuario y "databaseName" es la base de datos; y esto fue por este error .
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
fuente
Escribí este procedimiento inspirado en la respuesta de Cherian. La diferencia es que en mi versión el nombre de usuario es un argumento del procedimiento (y no está codificado). También estoy haciendo un FLUSH PRIVILEGES muy necesario después de eliminar al usuario.
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 ;
También publiqué este código en el sitio web CodeReview ( /codereview/15716/mysql-drop-user-if-exists )
fuente
DROP USER 'user'@'localhost';
El comando anterior eliminará al usuario de la base de datos, sin embargo, es importante saber si el mismo usuario ya está usando la base de datos, esa sesión no terminará hasta que el usuario cierre esa sesión. Es importante tener en cuenta que el usuario eliminado TODAVÍA accederá a la base de datos y realizará cualquier operación. DEJAR AL USUARIO NO BAJA LA SESIÓN DE USUARIO ACTUAL
fuente
Combinando la respuesta de phyzome (que no funcionó de inmediato para mí) con el comentario de andreb (que explica por qué no lo hizo) terminé con este código aparentemente funcional que deshabilita temporalmente el modo NO_AUTO_CREATE_USER si está activo:
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'@'%';
fuente
en la terminal hacer:
Introduce la contraseña.
select user from mysql.user;
ahora elimine el usuario 'the_username'
DROP USER the_unername;
reemplace 'the_username' con el usuario que desea eliminar.
fuente
En caso de tener un servidor escolar donde los alumnos trabajaron mucho. Puede limpiar el desorden de la siguiente manera:
delete from user where User != 'root' and User != 'admin'; delete from db where User != 'root' and User != 'admin'; delete from tables_priv; delete from columns_priv; flush privileges;
fuente
Si quiere decir que desea eliminar una gota de una tabla si existe, puede usar el
DELETE
comando, por ejemplo:DELETE FROM users WHERE user_login = 'foobar'
Si ninguna fila coincide, no es un error.
fuente