Tworzy to użytkownika, jeśli jeszcze nie istnieje (i zapewnia mu nieszkodliwe przywileje), a następnie usuwa go w obu przypadkach. Znalezione rozwiązanie tutaj: http://bugs.mysql.com/bug.php?id=19166
To już nie jest opcja. :( Obecna wersja MySQL nie tworzy już nowego użytkownika dla instrukcji GRANT. To była "funkcja", którą dodali.;) Wygląda na to, że opcja Cheriana jest jedyną, która obecnie działa.
GazB
1
@Zasurus. dev.mysql.com/doc/refman/5.1/en/grant.html (także 5.5 i 5.6) wydaje się sugerować, że się mylisz. Dostępna jest opcja „brak automatycznego tworzenia użytkowników”. O ile nie zrozumiem źle instrukcji, oznacza to, że grant utworzy użytkownika, jeśli nie istnieje.
andreb
@andreb Być może opcja „NO_AUTO_CREATE_USER” była włączona, gdy próbowałem tego lub domyślnie (ponieważ nie zmieniłem tego). Jeśli będę miał czas, spróbuję wyłączyć tę opcję i spróbuję ponownie. Jest kilka otwartych zgłoszeń błędów z tą opcją, być może jednym z nich jest również problem. :)
GazB
Zobacz również odpowiedź @ Hao. Potrzebowałem, IDENTIFIED BYaby to faktycznie działało.
Matthew
14
Odpowiadając phyzome (najwyżej głosowanemu), wydaje mi się, że jeśli na końcu oświadczenia o przyznaniu dotacji wstawisz słowo „zidentyfikowany przez”, użytkownik zostanie utworzony automatycznie. Ale jeśli tego nie zrobisz, użytkownik nie zostanie utworzony. Poniższy kod działa dla mnie,
Miałem kilka starych skryptów bez tego IDENTIIFIED BY „hasło”; część, która pracowała nad 5.6. Ale nie na 5.7. Dodanie części IDENTIFIED BY „hasło” załatwiło sprawę.
joensson
13
Znalazłem odpowiedź na to jedno z forów MySQL. Będziemy musieli użyć procedury, aby usunąć użytkownika.
Tutaj użytkownik to „test”, a „databaseName” to nazwa bazy danych.
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI';
USEdatabaseName ;
DROPPROCEDUREIFEXISTSdatabaseName.drop_user_if_exists ;
DELIMITER $$
CREATEPROCEDUREdatabaseName.drop_user_if_exists()
BEGINDECLARE foo BIGINTDEFAULT0 ;
SELECTCOUNT(*)
INTO foo
FROMmysql.userWHEREUser = 'test'andHost = 'localhost';
IF foo > 0 THEN
DROPUSER'test'@'localhost' ;
ENDIF;
END ;$$
DELIMITER ;
CALLdatabaseName.drop_user_if_exists() ;
DROPPROCEDUREIFEXISTSdatabaseName.drop_users_if_exists ;
SET SQL_MODE=@OLD_SQL_MODE ;
Dzięki @Cherian Nie jestem pewien, czy jest to nadal najlepszy sposób robienia rzeczy w 2017 roku, ale przynajmniej jest to droga naprzód! Nie mogę uwierzyć, że to wciąż jest takie trudne ...
JMac,
Po prostu do Twojej wiadomości powinieneś zawsze dołączać adres URL swojego źródła (Np .: Znaleziono odpowiedź z jednego z formularzy mysql . Lub z jednego z formularzy mysql (źródło tutaj)
4
DROPUSERIFEXISTS'user'@'localhost' ;
to działa dla mnie bez rzucania żadnych błędów w Maria DB, powinno działać również dla ciebie
Zamiast tego użyj DROP USER ... Możesz po prostu usunąć użytkownika z tabeli mysql.user (co nie powoduje błędu, jeśli użytkownik nie istnieje), a następnie opróżnić uprawnienia, aby zastosować zmianę.
Myliłem się. Usunięcie takiego użytkownika nie jest bezpieczne. Musisz użyć DROP USER. Ponieważ możliwe jest ustawienie opcji mysql tak, aby nie tworzyły użytkowników automatycznie poprzez grants (opcja, której używam), nadal nie polecałbym tej sztuczki. Oto fragment z procedury składowanej, która działa dla mnie:
DECLARE userCount INTDEFAULT0;
SELECTCOUNT(*) INTO userCount FROM mysql.user WHEREUser = userName AND Host='localhost';
IF userCount > 0 THEN
SET @S=CONCAT("DROP USER ", userName, "@localhost" );
PREPARE stmt FROM @S;
EXECUTE stmt;
SELECTCONCAT("DROPPED PRE-EXISTING USER: ", userName, "@localhost" ) as info;
ENDIF;
FLUSHPRIVILEGES;
Czy udostępniaj, dlaczego to „nie jest bezpieczne”…? Bezpieczne dla kogo w jaki sposób?
dagelf
Cóż, odkąd opublikowałem to ponad rok temu, nie twierdzę, że pamiętam w 100%, o czym mówiłem. Jestem prawie pewien, że chodziło mi o to, że nie powoduje to całkowitego usunięcia użytkownika z systemu. Myślę, że DROP USER daje więcej niż tylko usunięcie wiersza z tabeli mysql.user. Przepraszam, nie mogę sobie przypomnieć, jakie są te szczegóły!
BuvinJ,
Gdybym zgadywał, powiedziałbym, że rekordy uprawnień nie są usuwane, ale zostają „osierocone”? (W zależności od twoich ustawień?)
BuvinJ
2
Jeśli chodzi o odpowiedź @ Cherian, można usunąć następujące wiersze:
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI';
...
SET SQL_MODE=@OLD_SQL_MODE;
...
To był błąd sprzed 5.1.23. Po tej wersji nie są już potrzebne. Tak więc, dla wygody kopiowania / wklejania, tutaj jest to samo z usuniętymi powyższymi wierszami. Na przykład w celach „test” jest użytkownikiem, a „databaseName” jest bazą danych; a to było z tego błędu .
DROPPROCEDUREIFEXISTS databaseName.drop_user_if_exists ;
DELIMITER $$
CREATEPROCEDURE databaseName.drop_user_if_exists()
BEGINDECLARE foo BIGINTDEFAULT0 ;
SELECTCOUNT(*)
INTO foo
FROM mysql.user
WHEREUser = 'test'and Host = 'localhost';
IF foo > 0 THEN
DROPUSER'test'@'localhost' ;
ENDIF;
END ;$$
DELIMITER ;
CALL databaseName.drop_user_if_exists() ;
DROPPROCEDUREIFEXISTS databaseName.drop_users_if_exists ;
CREATEUSER'test'@'localhost'IDENTIFIEDBY'a';
GRANTALLPRIVILEGESON databaseName.* TO'test'@'localhost'WITHGRANTOPTION
Napisałem tę procedurę inspirowaną odpowiedzią Cheriana. Różnica polega na tym, że w mojej wersji nazwa użytkownika jest argumentem procedury (a nie zakodowana na stałe). Robię też bardzo potrzebne PRZYWILEJE FLUSH po usunięciu użytkownika.
DROPPROCEDUREIFEXISTS DropUserIfExists;
DELIMITER $$
CREATEPROCEDURE DropUserIfExists(MyUserName VARCHAR(100))
BEGINDECLARE foo BIGINTDEFAULT0 ;
SELECTCOUNT(*)
INTO foo
FROM mysql.user
WHEREUser = MyUserName ;
IF foo > 0 THEN
SET @A = (SELECTResultFROM (SELECTGROUP_CONCAT("DROP USER"," ",MyUserName,"@'%'") ASResult) AS Q LIMIT1);
PREPARE STMT FROM @A;
EXECUTE STMT;
FLUSHPRIVILEGES;
ENDIF;
END ;$$
DELIMITER ;
Powyższe polecenie spadnie użytkownika z bazy danych, jednak jest ważne , aby wiedzieć, czy ten sam użytkownik korzysta już z bazy danych, że sesja nie zakończy się, dopóki użytkownik nie zamknie tej sesji. Należy pamiętać, że upuszczony użytkownik NADAL będzie uzyskiwał dostęp do bazy danych i wykonywał wszelkie operacje.
UPUSZCZENIE UŻYTKOWNIKA NIE PRZESUWA AKTUALNEJ SESJI UŻYTKOWNIKA
Łącząc odpowiedź phyzome (która nie zadziałała od razu dla mnie) z komentarzem andreba (który wyjaśnia, dlaczego tak się nie stało) otrzymałem ten pozornie działający kod, który tymczasowo wyłącza tryb NO_AUTO_CREATE_USER, jeśli jest aktywny:
Odpowiedzi:
Od MySQL 5.7 możesz zrobić
DROP USER IF EXISTS test
Więcej informacji: http://dev.mysql.com/doc/refman/5.7/en/drop-user.html
źródło
To zadziałało dla mnie:
GRANT USAGE ON *.* TO 'username'@'localhost'; DROP USER 'username'@'localhost';
Tworzy to użytkownika, jeśli jeszcze nie istnieje (i zapewnia mu nieszkodliwe przywileje), a następnie usuwa go w obu przypadkach. Znalezione rozwiązanie tutaj: http://bugs.mysql.com/bug.php?id=19166
Aktualizacje: @Hao zaleca dodanie
IDENTIFIED BY
; @andreb (w komentarzach) sugeruje wyłączenieNO_AUTO_CREATE_USER
.źródło
IDENTIFIED BY
aby to faktycznie działało.Odpowiadając phyzome (najwyżej głosowanemu), wydaje mi się, że jeśli na końcu oświadczenia o przyznaniu dotacji wstawisz słowo „zidentyfikowany przez”, użytkownik zostanie utworzony automatycznie. Ale jeśli tego nie zrobisz, użytkownik nie zostanie utworzony. Poniższy kod działa dla mnie,
GRANT USAGE ON *.* TO 'username'@'localhost' IDENTIFIED BY 'password'; DROP USER 'username'@'localhost';
Mam nadzieję że to pomoże.
źródło
Znalazłem odpowiedź na to jedno z forów MySQL. Będziemy musieli użyć procedury, aby usunąć użytkownika.
Tutaj użytkownik to „test”, a „databaseName” to nazwa bazy danych.
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
źródło
DROP USER IF EXISTS 'user'@'localhost' ;
to działa dla mnie bez rzucania żadnych błędów w Maria DB, powinno działać również dla ciebie
źródło
Aktualizacja: Od MySQL 5.7 możesz użyć
DROP USER IF EXISTS
instrukcji. Odniesienie: https://dev.mysql.com/doc/refman/5.7/en/drop-user.htmlFYI (i dla starszej wersji MySQL), jest to lepsze rozwiązanie ... !!!
Poniższy SP pomoże ci usunąć użytkownika
'tempuser'@'%'
, wykonującCALL DropUserIfExistsAdvanced('tempuser', '%');
Jeśli chcesz usunąć wszystkich użytkowników nazwanych
'tempuser'
(słownie'tempuser'@'%'
,'tempuser'@'localhost'
i'tempuser'@'192.168.1.101'
) wykonywanie SP jakCALL DropUserIfExistsAdvanced('tempuser', NULL);
ta spowoduje usunięcie wszystkich użytkowników nazwanychtempuser
!!! poważnie...Teraz spójrz na wspomniane 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 ;
Stosowanie:
CALL DropUserIfExistsAdvanced('tempuser', '%');
aby usunąć użytkownika'tempuser'@'%'
CALL DropUserIfExistsAdvanced('tempuser', '192.168.1.101');
aby usunąć użytkownika'tempuser'@'192.168.1.101'
CALL DropUserIfExistsAdvanced('tempuser', NULL);
usunięcie wszystkich użytkowników nazwanych'tempuser'
(np., powiedzmy'tempuser'@'%'
,'tempuser'@'localhost'
i'tempuser'@'192.168.1.101'
)źródło
Um ... Po co te wszystkie komplikacje i sztuczki?
Zamiast tego użyj DROP USER ... Możesz po prostu usunąć użytkownika z tabeli mysql.user (co nie powoduje błędu, jeśli użytkownik nie istnieje), a następnie opróżnić uprawnienia, aby zastosować zmianę.
DELETE FROM mysql.user WHERE User = 'SomeUser' AND Host = 'localhost'; FLUSH PRIVILEGES;
-- AKTUALIZACJA --
Myliłem się. Usunięcie takiego użytkownika nie jest bezpieczne. Musisz użyć DROP USER. Ponieważ możliwe jest ustawienie opcji mysql tak, aby nie tworzyły użytkowników automatycznie poprzez grants (opcja, której używam), nadal nie polecałbym tej sztuczki. Oto fragment z procedury składowanej, która działa dla mnie:
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;
źródło
Jeśli chodzi o odpowiedź @ Cherian, można usunąć następujące wiersze:
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI'; ... SET SQL_MODE=@OLD_SQL_MODE; ...
To był błąd sprzed 5.1.23. Po tej wersji nie są już potrzebne. Tak więc, dla wygody kopiowania / wklejania, tutaj jest to samo z usuniętymi powyższymi wierszami. Na przykład w celach „test” jest użytkownikiem, a „databaseName” jest bazą danych; a to było z tego błędu .
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
źródło
Napisałem tę procedurę inspirowaną odpowiedzią Cheriana. Różnica polega na tym, że w mojej wersji nazwa użytkownika jest argumentem procedury (a nie zakodowana na stałe). Robię też bardzo potrzebne PRZYWILEJE FLUSH po usunięciu użytkownika.
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 ;
Opublikowałem również ten kod na stronie CodeReview ( /codereview/15716/mysql-drop-user-if-exists )
źródło
DROP USER 'user'@'localhost';
Powyższe polecenie spadnie użytkownika z bazy danych, jednak jest ważne , aby wiedzieć, czy ten sam użytkownik korzysta już z bazy danych, że sesja nie zakończy się, dopóki użytkownik nie zamknie tej sesji. Należy pamiętać, że upuszczony użytkownik NADAL będzie uzyskiwał dostęp do bazy danych i wykonywał wszelkie operacje. UPUSZCZENIE UŻYTKOWNIKA NIE PRZESUWA AKTUALNEJ SESJI UŻYTKOWNIKA
źródło
Łącząc odpowiedź phyzome (która nie zadziałała od razu dla mnie) z komentarzem andreba (który wyjaśnia, dlaczego tak się nie stało) otrzymałem ten pozornie działający kod, który tymczasowo wyłącza tryb NO_AUTO_CREATE_USER, jeśli jest aktywny:
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'@'%';
źródło
w terminalu zrobić:
Podaj hasło.
select user from mysql.user;
teraz usuń użytkownika „the_username”
DROP USER the_unername;
zamień „the_username” na użytkownika, którego chcesz usunąć.
źródło
Jeśli masz szkolny serwer, na którym uczniowie dużo pracowali. Możesz po prostu posprzątać bałagan:
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;
źródło
Jeśli masz na myśli, że chcesz usunąć drop z tabeli, jeśli istnieje, możesz użyć
DELETE
polecenia, na przykład:DELETE FROM users WHERE user_login = 'foobar'
Jeśli żaden wiersz nie pasuje, nie jest to błąd.
źródło