MySQL:检查用户是否存在并删除它

时间:2009-02-28 15:48:54

标签: mysql database

没有标准的方法来检查MySQL用户是否存在并基于该用户丢弃它。这有什么变通方法吗?

编辑:我需要一个直接的方法来运行它而不会抛出错误
e.g。

DROP USER test@localhost; :    

14 个答案:

答案 0 :(得分:88)

这对我有用:

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

如果用户尚未存在(并授予其无害特权),则会创建该用户,然后以任一方式删除它。在此处找到解决方案:http://bugs.mysql.com/bug.php?id=19166

更新:@Hao recommends添加IDENTIFIED BY; @andreb(在评论中)建议禁用NO_AUTO_CREATE_USER

答案 1 :(得分:37)

从MySQL 5.7开始,您可以执行DROP USER IF EXISTS test

更多信息:http://dev.mysql.com/doc/refman/5.7/en/drop-user.html

答案 2 :(得分:13)

从一个MySQL论坛找到答案。我们需要使用一个过程来删除用户。

这里的用户是“test”,“databaseName”是数据库名称。


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'; GRANT ALL PRIVILEGES ON databaseName.* TO 'test'@'localhost' WITH GRANT OPTION

答案 3 :(得分:13)

对于phyzome的答案(最受高度评价的答案),在我看来,如果你把"标识为"在grant语句的末尾,将自动创建用户。但是如果你不这样做,就不会创建用户。以下代码适用于我,

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

希望这有帮助。

答案 4 :(得分:4)

DROP USER IF EXISTS 'user'@'localhost' ;

对我有用而不会在Maria DB中出现任何错误,它也适用于你

答案 5 :(得分:3)

<强>更新 从MySQL 5.7开始,您可以使用DROP USER IF EXISTS语句。 参考:https://dev.mysql.com/doc/refman/5.7/en/drop-user.html

  

语法:DROP USER [IF EXISTS] user [, user] ...

     

示例:DROP USER IF EXISTS 'jeffrey'@'localhost';

仅供参考(对于旧版本的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'

答案 6 :(得分:3)

嗯...为什么所有的并发症和伎俩?

而不是使用DROP USER ...你可以简单地从mysql.user表中删除用户(如果用户不存在则不会抛出错误),然后刷新权限以应用更改。

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

- 更新 -

我错了。删除这样的用户是不安全的。您需要使用DROP USER。由于可以将mysql选项设置为不通过授权自动创建用户(我使用的选项),我仍然不会推荐这个技巧。这是一个适用于我的存储过程的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;

答案 7 :(得分:2)

关于@ Cherian的回答,可以删除以下行:

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

这是5.1.23之前的错误。在那个版本之后,不再需要这些。因此,对于复制/粘贴方便,这里删除上面的行是一样的。同样,例如,“test”是用户,“databaseName”是数据库;这来自this 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

答案 8 :(得分:2)

我写了这个程序,灵感来自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

上发布了此代码

答案 9 :(得分:2)

DROP USER 'user'@'localhost';

以上命令会将用户从数据库中删除,但是,重要以确定同一用户是否已在使用该数据库,该会话将在用户关闭该会话之前结束。重要的是要注意,被删除的用户将仍然访问数据库并执行任何操作。 DROPPING THE USER DOES NOT DROP THE CURRENT USER SESSION

答案 10 :(得分:0)

结合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'@'%';

答案 11 :(得分:0)

在终端上执行

sudo mysql -u root -p

输入密码。

select user from mysql.user;

现在删除用户“ the_username”

DROP USER the_unername;

将“ the_username”替换为您要删除的用户。

答案 12 :(得分:-1)

如果你有一个学生服务器,学生工作很多。你可以通过以下方式清理乱七八糟的东西:

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;

答案 13 :(得分:-5)

如果您要删除表中的drop(如果存在),可以使用DELETE命令,例如:

 DELETE FROM users WHERE user_login = 'foobar'

如果没有匹配的行,则不是错误。