MySQL:检查用户是否存在并放弃它
没有标准的方法来检查一个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';
如果用户不存在(并授予它一个无害的权限),则创build用户,然后删除它。 find解决scheme在这里: http : //bugs.mysql.com/bug.php?id=19166
更新: @浩build议添加IDENTIFIED BY
; @andreb(在评论中)build议禁用NO_AUTO_CREATE_USER
。
从其中一个MySQL论坛find答案。 我们需要使用一个过程来删除用户。
这里的用户是“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 ;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI'; USE
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
; SET SQL_MODE=@OLD_SQL_MODE ;
CREATE USER'test'@'localhost'IDENTIFIED BY'a';
授予数据库名称的所有特权。*'testing'@'localhost'
赠与选项
对于phyzome的答案(最高评分之一),在我看来,如果在授权声明的末尾加上“由…确定”,用户将自动创build。 但是,如果你不这样做,用户不会被创build。 下面的代码适用于我,
GRANT USAGE ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password'; DROP USER 'username'@'localhost';
希望这可以帮助。
DROP USER IF EXISTS 'user'@'localhost' ;
这对我而言没有任何错误在玛丽亚DB,它应该为你工作
对于@ Cherian的回答,可以删除以下几行:
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI'; ... SET SQL_MODE=@OLD_SQL_MODE; ...
这是5.1.23之前的一个bug。 在版本之后,这些不再是必需的。 所以,为了复制/粘贴的方便,这里是删除上面的行相同。 再次举例来说,“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 USER …您可以简单地从mysql.user表中删除用户(如果用户不存在,则不会抛出错误),然后刷新权限以应用更改。
DELETE FROM mysql.user WHERE User = 'SomeUser' AND Host = 'localhost'; FLUSH PRIVILEGES;
– 更新 –
我错了。 像这样删除用户是不安全的。 你确实需要使用DROP USER。 由于可以将mysql选项设置为不通过授权(我使用的一个选项)自动创build用户,所以我仍然不会推荐这个技巧。 下面是一个存储过程snipet适用于我:
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的答案。 不同的是,在我的版本中,用户名是程序的一个参数(而不是硬编码)。 在删除用户之后,我还做了一个非常必要的FLUSH PRIVILEGES。
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网站上发布了这个代码( https://codereview.stackexchange.com/questions/15716/mysql-drop-user-if-exists )
仅供参考,这是一个更好的解决scheme…!
以下SP将通过执行CALL DropUserIfExistsAdvanced('tempuser', '%');
来帮助您删除用户'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'
)
结合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'@'%';
DROP USER 'user'@'localhost';
上面的命令将把用户从数据库中删除,但是,知道同一用户是否已经在使用数据库是非常重要的 ,那么在用户closures该会话之前,该会话将不会结束。 请注意,丢弃的用户将仍然访问数据库并执行任何操作。 删除用户不会丢失当前的用户会话
如果你有一个学校的服务器,学生工作很多。 你可以通过以下方式清理垃圾:
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;
如果你的意思是你想从表中删除一个drop,你可以使用DELETE
命令,例如:
DELETE FROM users WHERE user_login = 'foobar'
如果没有行匹配,这不是一个错误。