MySQL: जाँच करें कि क्या उपयोगकर्ता मौजूद है और उसे छोड़ दें


84

यह जांचने के लिए मानक तरीका नहीं है कि क्या कोई MySQL उपयोगकर्ता मौजूद है और वह ड्रॉप पर आधारित है। क्या इसके लिए कोई वर्कअराउंड हैं?

संपादित करें: मुझे बिना किसी त्रुटि के इसे चलाने के लिए एक सीधे तरीके की आवश्यकता है
जैसे

DROP USER test@localhost; :    

1
क्या आपका मतलब एक MySQL उपयोगकर्ता है? या एक उपयोगकर्ता रिकॉर्ड जिसे आप MySQL में एक तालिका में संग्रहीत कर रहे हैं?
जेसन कोहेन

ऐसा लगता है कि MariaDB में यह सुविधा है: mariadb.com/kb/en/mariadb/drop-user
Limited प्रायश्चित

1
भविष्य के पाठकों के लिए: MySQL 5.7 में 'DROP USER IF EXISTS' की सुविधा है, देखें stackoverflow.com/questions/598190/…
आंद्रेई एप्योर जुले

1
@AndreiEpure यदि आप इसे केवल एक उत्तर के रूप में रख सकते हैं, तो मैं इसे सही के रूप में चिह्नित करूंगा।
चेरियन

जवाबों:



87

यह मेरे लिए काम किया:

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

यह उपयोगकर्ता बनाता है यदि यह पहले से मौजूद नहीं है (और इसे एक हानिरहित विशेषाधिकार देता है), तो इसे किसी भी तरह से हटा देता है। यहाँ पाया समाधान: http://bugs.mysql.com/bug.php?id=19166

अपडेट: @ हाओ जोड़ने की सिफारिश करता हैIDENTIFIED BY ; @andreb (टिप्पणियों में) अक्षम करने का सुझाव देता है NO_AUTO_CREATE_USER


5
में MySQL मैनुअल पृष्ठ अनुदान वास्तव में यह कहते हैं: "किसी विशेषाधिकार के लिए" पर्याय: उपयोग
stivlo

6
यह अब एक विकल्प नहीं है। :( MySQL का वर्तमान संस्करण अब GRANT स्टेटमेंट के लिए एक नया उपयोगकर्ता नहीं बनाता है। यह एक "फ़ीचर" था जो उन्होंने जोड़ा;) लगता है कि चेरियन का विकल्प केवल वही है जो वर्तमान में काम करता है।
गजब

1
@Zasurus। dev.mysql.com/doc/refman/5.1/en/grant.html (5.5 और 5.6 भी) लगता है कि आप गलत हैं। एक "कोई ऑटो उपयोगकर्ता बनाएँ" विकल्प नहीं है। जब तक मैं मैनुअल को गलत नहीं समझता, यह इंगित करता है कि अनुदान एक उपयोगकर्ता बना देगा यदि यह मौजूद नहीं है।
andreb

@andreb शायद "NO_AUTO_CREATE_USER" विकल्प पर था जब मैंने यह या डिफ़ॉल्ट रूप से कोशिश की थी (जैसा कि मैंने इसे नहीं बदला है)। अगर मुझे समय मिलता है तो मैं इस विकल्प को बंद करने की कोशिश करूंगा और फिर से कोशिश करूंगा। इस विकल्प के साथ कुछ खुली बग रिपोर्टें हैं, शायद उनमें से एक समस्या भी है। :)
गज़ब

@ हाओ का जवाब भी देखें। मुझे IDENTIFIED BYइसे वास्तव में काम करने की आवश्यकता थी ।
मैथ्यू

14

फ़िज़ोम के उत्तर (सबसे अधिक वोट दिए गए) के लिए, यह मुझे लगता है कि यदि आप अनुदान विवरण के अंत में "द्वारा पहचाने" जाते हैं, तो उपयोगकर्ता स्वचालित रूप से बनाया जाएगा। लेकिन यदि आप नहीं करते हैं, तो उपयोगकर्ता नहीं बनाया जाता है। निम्नलिखित कोड मेरे लिए काम करता है,

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

उम्मीद है की यह मदद करेगा।


मेरे पास कुछ पुरानी स्क्रिप्ट्स थीं जो बिना IDENTIIFIED BY 'पासवर्ड' के थीं; हिस्सा है कि 5.6 पर काम किया। लेकिन 5.7 पर नहीं हुआ। IDENTIFIED BY 'पासवर्ड' भाग को जोड़ने से मेरे लिए चाल चली गई।
जॉनसन

13

MySQL मंचों में से एक से इसका जवाब मिला। उपयोगकर्ता को हटाने के लिए हमें एक प्रक्रिया का उपयोग करना होगा।

यहाँ उपयोगकर्ता "परीक्षण" और "डेटाबेस का नाम" डेटाबेस का नाम है।


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


धन्यवाद @Cherian मुझे यकीन नहीं है अगर यह अभी भी 2017 में चीजों को करने का सबसे अच्छा तरीका है लेकिन कम से कम इसका एक तरीका आगे है! मुझे विश्वास नहीं हो रहा है कि यह अभी भी इतना ही कठिन है ...
JMac

बस FYI करें, आपको हमेशा अपने स्रोत के url को रोकना चाहिए (उदाहरण के लिए: mysql रूपों में से एक से उत्तर मिला । या mysql रूपों में से एक से (यहाँ स्रोत)

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

मारिया डीबी में किसी भी त्रुटि के बिना मेरे लिए काम करता है, यह यू के लिए भी काम करना चाहिए


2
MySQL 5.7 और ऊपर, सुनिश्चित करें। ... मेरे लिए भाग्यशाली, हमारे द्वारा उपयोग किया जाने वाला नवीनतम संस्करण 5.5 है।
tetsujin

4

अपडेट: MySQL 5.7 के अनुसार आप DROP USER IF EXISTSस्टेटमेंट का उपयोग कर सकते हैं । Ref: https://dev.mysql.com/doc/refman/5.7/en/drop-user.html

वाक्य - विन्यास: DROP USER [IF EXISTS] user [, user] ...

उदाहरण: DROP USER IF EXISTS 'jeffrey'@'localhost';

FYI करें (और MySQL के पुराने संस्करण के लिए), यह एक बेहतर उपाय है ... !!!

निम्नलिखित SP आपको 'tempuser'@'%'निष्पादित करके उपयोगकर्ता को निकालने में मदद करेगाCALL DropUserIfExistsAdvanced('tempuser', '%');

यदि आप नाम वाले सभी उपयोगकर्ताओं 'tempuser'(कहना 'tempuser'@'%', 'tempuser'@'localhost'और 'tempuser'@'192.168.1.101') CALL DropUserIfExistsAdvanced('tempuser', NULL);को हटाना चाहते हैं तो SP को क्रियान्वित करें जैसे यह नाम वाले सभी उपयोगकर्ताओं को हटा देगा tempuser!!! गंभीरता से ...

अब उल्लेख एसपी पर एक नजर है 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')


3

उम ... क्यों सभी जटिलताओं और चालें?

बल्कि फिर 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;

साझा करें कि यह "सुरक्षित क्यों नहीं है" ...? किस तरह से सुरक्षित रहें?
dagelf

खैर, जब से मैंने एक साल से अधिक समय पहले यह पोस्ट किया है, मैं 100% को याद करने का दावा नहीं करूंगा कि मैं क्या जिक्र कर रहा था। मुझे पूरा यकीन है कि मेरा मतलब था कि यह विश्वसनीयता को पूरी तरह से सिस्टम से नहीं हटाता है। मुझे लगता है कि DROP USER केवल mysql.user टेबल से एक पंक्ति को हटाने से अधिक पूरा करता है। क्षमा करें, मैं नहीं सोच सकता कि वे विवरण अब क्या हैं!
BuvinJ

अगर मैं अनुमान लगा रहा था कि मैं कहूंगा कि विशेषाधिकार रिकॉर्ड हटाए नहीं गए हैं, लेकिन "अनाथ" हो गए हैं? (अपनी सेटिंग्स पर निर्भर करता है?)
BuvinJ

2

@ चेरियन के उत्तर के बारे में, निम्नलिखित पंक्तियों को हटाया जा सकता है:

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

यह एक बग प्री 5.1.23 था। उस संस्करण के बाद अब इनकी आवश्यकता नहीं है। तो, कॉपी / पेस्ट सुविधा के लिए, यहाँ ऊपर की पंक्तियों को हटा दिया गया है। फिर से, उदाहरण के प्रयोजनों के लिए "परीक्षण" उपयोगकर्ता है और "डेटाबेसनाम" डेटाबेस है; और यह इस बग से था ।

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

2

मैंने यह प्रक्रिया चेरियन के उत्तर से प्रेरित होकर लिखी थी। अंतर यह है कि मेरे संस्करण में उपयोगकर्ता नाम प्रक्रिया का एक तर्क है (और हार्ड कोडित नहीं है)। मैं उपयोगकर्ता को छोड़ने के बाद एक बहुत ही आवश्यक FLIVH 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 ) पर भी पोस्ट किया है


2
DROP USER 'user'@'localhost';

उपरोक्त आदेश उपयोगकर्ता को डेटाबेस से हटा देगा, हालांकि, यह जानना महत्वपूर्ण है कि क्या वही उपयोगकर्ता पहले से ही डेटाबेस का उपयोग कर रहा है, जब तक कि उपयोगकर्ता उस सत्र को बंद नहीं करता, तब तक वह सत्र समाप्त नहीं होगा। यह नोट करना महत्वपूर्ण है कि गिरा दिया गया उपयोगकर्ता डेटाबेस तक पहुंच जाएगा और कोई भी ऑपरेशन करेगा। उपयोगकर्ता का उपयोग करते हुए क्ररेंट USER सत्र को ड्रॉप नहीं करता है


0

Andreb की टिप्पणी के साथ phyzome के उत्तर (जो मेरे लिए अभी काम नहीं आया) का संयोजन (जो बताता है कि यह क्यों नहीं हुआ) मैं इस प्रतीत होता है कि काम कोड के साथ समाप्त हो गया है जो अस्थायी रूप से 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'@'%';

0

टर्मिनल में करें:

sudo mysql -u root -p

पासवर्ड दर्ज करे।

select user from mysql.user;

अब उपयोगकर्ता 'the_username' हटाएं

DROP USER the_unername;

उस उपयोगकर्ता के साथ 'the_username' को बदलें जिसे आप हटाना चाहते हैं।


-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;

-6

यदि आपका मतलब है कि आप किसी तालिका से एक बूंद को हटाना चाहते हैं यदि वह मौजूद है, तो आप DELETEकमांड का उपयोग कर सकते हैं , उदाहरण के लिए:

 DELETE FROM users WHERE user_login = 'foobar'

यदि कोई पंक्तियाँ मेल नहीं खाती हैं, तो यह कोई त्रुटि नहीं है।


2
मुझे लगता है कि ओपी एक वास्तविक डेटाबेस उपयोगकर्ता को संदर्भित करता है।
टॉमालक

6
यह सबसे सरल उपाय IMO है। बस सही एसक्यूएल की जरूरत है: DELETE mysql.user से जहां उपयोगकर्ता = 'फ़ॉबर'
जॉन रिक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.