MySQL 사용자가 존재하는지 확인하는 표준 방법은 없으며이를 기반으로 삭제합니다. 이에 대한 해결 방법이 있습니까?
편집 : 오류 던지고없이이를 실행하는 직선 방법이 필요
예를
DROP USER test@localhost; :
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 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
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.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'
)
음 ... 왜 모든 합병증과 속임수?
대신 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
나는 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 웹 사이트 ( /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'@'%';