Не существует стандартного способа проверить, существует ли пользователь MySQL, и на основе этого удалить его. Есть ли обходные пути для этого?
Изменить: мне нужен прямой способ запустить это, не вызывая ошибки,
например
DROP USER test@localhost; :
Ответы:
Начиная с MySQL 5.7 вы можете сделать
DROP USER IF EXISTS test
Подробнее: http://dev.mysql.com/doc/refman/5.7/en/drop-user.html
источник
Это сработало для меня:
GRANT USAGE ON *.* TO 'username'@'localhost'; DROP USER 'username'@'localhost';
Это создает пользователя, если он еще не существует (и предоставляет ему безобидную привилегию), а затем удаляет его в любом случае. Нашел решение здесь: http://bugs.mysql.com/bug.php?id=19166
Обновления: @Hao рекомендует добавить
IDENTIFIED BY
; @andreb (в комментариях) предлагает отключитьNO_AUTO_CREATE_USER
.источник
IDENTIFIED BY
был, чтобы это действительно работало.На ответ phyzome (получивший наибольшее количество голосов) мне кажется, что если вы поставите «идентифицировано» в конце утверждения предоставления, пользователь будет создан автоматически. Но если вы этого не сделаете, пользователь не будет создан. Следующий код работает для меня,
GRANT USAGE ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password'; DROP USER 'username'@'localhost';
Надеюсь это поможет.
источник
Нашел ответ на это на одном из форумов MySQL. Нам нужно будет использовать процедуру для удаления пользователя.
Пользователь здесь «test», а «databaseName» - имя базы данных.
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
источник
DROP USER IF EXISTS 'user'@'localhost' ;
это работает для меня, не вызывая никаких ошибок в Maria DB, он должен работать и для вас
источник
Обновление: с MySQL 5.7 вы можете использовать
DROP USER IF EXISTS
оператор. Ссылка: https://dev.mysql.com/doc/refman/5.7/en/drop-user.htmlFYI (и для более старой версии MySQL), это лучшее решение ... !!!
Следующий SP поможет вам удалить пользователя
'tempuser'@'%'
, выполнивCALL DropUserIfExistsAdvanced('tempuser', '%');
Если вы хотите удалить всех пользователей с именами
'tempuser'
(скажем'tempuser'@'%'
,'tempuser'@'localhost'
и'tempuser'@'192.168.1.101'
), выполните SP какCALL DropUserIfExistsAdvanced('tempuser', NULL);
Это удалит всех пользователей с именамиtempuser
!!! шутки в сторону...Теперь взгляните на упомянутый 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 ;
Применение:
CALL DropUserIfExistsAdvanced('tempuser', '%');
удалить пользователя'tempuser'@'%'
CALL DropUserIfExistsAdvanced('tempuser', '192.168.1.101');
удалить пользователя'tempuser'@'192.168.1.101'
CALL DropUserIfExistsAdvanced('tempuser', NULL);
чтобы удалить всех названных пользователей'tempuser'
(например, скажем'tempuser'@'%'
,'tempuser'@'localhost'
и'tempuser'@'192.168.1.101'
)источник
Гм ... К чему все сложности и уловки?
Вместо этого используйте DROP USER ... Вы можете просто удалить пользователя из таблицы mysql.user (что не вызывает ошибки, если пользователь не существует), а затем сбросить привилегии для применения изменения.
DELETE FROM mysql.user WHERE User = 'SomeUser' AND Host = 'localhost'; FLUSH PRIVILEGES;
-- ОБНОВИТЬ --
Я был неправ. Удалять такого пользователя небезопасно. Вам нужно использовать DROP USER. Поскольку можно настроить параметры mysql, чтобы не создавать пользователей автоматически с помощью грантов (вариант, который я использую), я бы все равно не рекомендовал этот трюк. Вот фрагмент из хранимой процедуры, которая мне подходит:
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;
источник
Что касается ответа @ Cherian, можно удалить следующие строки:
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI'; ... SET SQL_MODE=@OLD_SQL_MODE; ...
Это была ошибка до 5.1.23. После этой версии они больше не требуются. Итак, для удобства копирования / вставки здесь то же самое, но с удаленными строками выше. Опять же, например, для целей «test» - это пользователь, а «databaseName» - это база данных; и это было из-за этого бага .
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
источник
Я написал эту процедуру, вдохновившись ответом Чериана. Разница в том, что в моей версии имя пользователя является аргументом процедуры (а не жестко закодировано). Я также выполняю очень необходимые ПРИВИЛЕГИИ ПРОМЫВКИ после удаления пользователя.
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 ;
Я также разместил этот код на сайте CodeReview ( /codereview/15716/mysql-drop-user-if-exists )
источник
DROP USER 'user'@'localhost';
Приведенная выше команда удалит пользователя из базы данных, однако важно знать, что если тот же пользователь уже использует базу данных, этот сеанс не завершится, пока пользователь не закроет этот сеанс. Важно отметить, что удаленный пользователь ВСЕ ЕЩЕ будет получать доступ к базе данных и выполнять любые операции. УДАЛЕНИЕ ПОЛЬЗОВАТЕЛЯ НЕ УДАЛЯЕТ ТЕКУЩУЮ СЕССИЮ ПОЛЬЗОВАТЕЛЯ
источник
Объединив ответ phyzome (который не сработал для меня сразу) с комментарием andreb (который объясняет, почему это не так), я получил этот, казалось бы, рабочий код, который временно отключает режим NO_AUTO_CREATE_USER, если он активен:
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'@'%';
источник
в терминале сделать:
введите пароль.
select user from mysql.user;
теперь удалите пользователя the_username
DROP USER the_unername;
замените the_username на пользователя, которого вы хотите удалить.
источник
Если у вас есть школьный сервер, на котором ученики много работали. Вы можете просто навести порядок:
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;
источник
Если вы имеете в виду, что хотите удалить перетаскивание из таблицы, если она существует, вы можете использовать
DELETE
команду, например:DELETE FROM users WHERE user_login = 'foobar'
Если ни одна строка не соответствует, это не ошибка.
источник