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

MySQL:检查用户是否存在并删除它,mysql,database,Mysql,Database,没有标准的方法来检查MySQL用户是否存在,并基于此删除它。有什么解决办法吗 编辑:我需要一种直接的方式来运行此程序,而不会抛出错误 e、 g 如果您的意思是要从表中删除某个drop(如果存在),则可以使用delete命令,例如: DELETE FROM users WHERE user_login = 'foobar' 如果没有匹配的行,这不是错误。从MySQL论坛中找到了答案。我们需要使用一个过程来删除用户 这里的用户是“test”和“databaseName”数据库名称 这对我很有效:

没有标准的方法来检查MySQL用户是否存在,并基于此删除它。有什么解决办法吗

编辑:我需要一种直接的方式来运行此程序,而不会抛出错误
e、 g


如果您的意思是要从表中删除某个drop(如果存在),则可以使用
delete
命令,例如:

 DELETE FROM users WHERE user_login = 'foobar'

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

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

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

这对我很有效:

GRANT USAGE ON *.* TO 'username'@'localhost';
DROP USER 'username'@'localhost';
如果该用户不存在(并授予其无害权限),则会创建该用户,然后以任何方式将其删除。在此处找到解决方案:


更新:添加由标识的
@andreb(在评论中)建议禁用
NO\u AUTO\u CREATE\u USER

关于@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 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网站()上发布了这段代码。

更新: 从MySQL 5.7开始,您可以使用
DROP USER IF EXISTS
语句。 参考:

语法:
删除用户[如果存在]用户[,用户]…

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

仅供参考(对于较旧版本的MySQL),这是一个更好的解决方案

以下SP将通过执行调用DropUserIfExistsAdvanced('tempuser','%'),帮助您删除用户
'tempuser'@'

如果要删除所有名为
'tempuser'
(例如
'tempuser'@'
'tempuser'@'localhost'
'tempuser'@'192.168.1.101'
)的用户,请执行类似SP的
调用dropuserifexistadvanced('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 ;
用法:

调用DropUserIfExistsAdvanced('tempuser','%')
删除用户
'tempuser'@%'

调用DropUserIfExistsAdvanced('tempuser','192.168.1.101')
删除用户
'tempuser'@'192.168.1.101'


调用DropUserIfExistsAdvanced('tempuser',NULL)
删除名为
'tempuser'
的所有用户(例如说
'tempuser'@%
'tempuser'@'localhost'
'tempuser'@'192.168.1.101'

以防您有一个学生经常工作的学校服务器。您可以通过以下方式清理混乱:

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;
对于phyzome的答案(投票率最高的一个),在我看来,如果在grant语句的末尾添加“identified by”,那么用户将自动创建。但如果不这样做,则不会创建用户。以下代码适用于我

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

希望这能有所帮助。

结合phyzome的回答(这对我来说不起作用)和andreb的评论(这解释了为什么它不起作用),我最终得到了这段看似有效的代码,如果它处于活动状态,它会暂时禁用NO_AUTO_CREATE_用户模式:

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

嗯。。。为什么会有这么多复杂和诡计

而不是使用拖放用户。。。您只需从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;
上述命令将从数据库中删除用户,但是,重要的是要知道同一用户是否已经在使用数据库,该会话将在用户关闭该会话之前不会结束。需要注意的是,被删除的用户仍将访问数据库并执行任何操作。

自MySQL 5.7以来,您可以执行
删除用户(如果存在)测试

更多信息:

这对我来说是可行的,不会在Maria DB中抛出任何错误,在terminal do中也应该适用于u:

sudo mysql -u root -p
输入密码

select user from mysql.user;
现在删除用户“the_username”

DROP USER the_unername;

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

您是指MySQL用户吗?或者您存储在MySQL表中的用户记录?看起来MariaDB有这个功能:对于未来的读者:MySQL 5.7有“如果存在就删除用户”的功能,请参阅@Andreepure,如果您可以将此作为答案,我会把它标记为正确的。我认为OP指的是一个真正的数据库用户。这是IMO最简单的解决方案。只需要正确的SQL:DELETE FROM mysql.user其中user='foobar'实际上它说:用法:同义词“no privileges”,这不再是一个选项:(MySQL的当前版本不再为GRANT语句创建新用户。这是他们添加的一项“功能”。)看起来Cherian的选项是目前唯一有效的选项。@Zasurus。(还有5.5和5.6)似乎表明你错了。有一个“无自动用户创建”选项。除非我误解了手册,否则它表明grant将创建一个不存在的用户。@andreb可能在我尝试此操作时或在默认情况下打开了“NO_AUTO_create_user”选项(如我没有更改它)。如果我有时间,我将尝试关闭此选项,然后重试。此op中有一些打开的bug报告
DROP USER 'user'@'localhost';
DROP USER IF EXISTS 'user'@'localhost' ;
sudo mysql -u root -p
select user from mysql.user;
DROP USER the_unername;