यदि SQL सर्वर लॉगिन पहले से मौजूद है, तो जाँच करना


176

मुझे यह जांचने की आवश्यकता है कि क्या SQL सर्वर पर एक विशिष्ट लॉगिन पहले से मौजूद है, और यदि यह नहीं है, तो मुझे इसे जोड़ने की आवश्यकता है।

मुझे वास्तव में डेटाबेस में लॉगिन जोड़ने के लिए निम्न कोड मिला है, लेकिन मैं इसे IF स्टेटमेंट (किसी तरह) में यह जांचना चाहता हूं कि लॉगिन पहले मौजूद है या नहीं।

CREATE LOGIN [myUsername] WITH PASSWORD=N'myPassword', 
DEFAULT_LANGUAGE=[us_english], 
CHECK_EXPIRATION=OFF, 
CHECK_POLICY=OFF 
GO

मैं समझता हूं कि मुझे सिस्टम डेटाबेस से पूछताछ करने की आवश्यकता है, लेकिन यह सुनिश्चित नहीं है कि कहां से शुरू करें!


10
यह एक महत्वपूर्ण सवाल है, लेकिन जैसा कि वाक्यांशबद्ध है, यह एक महत्वपूर्ण अंतर याद आती है: उपयोगकर्ता बनाम लॉगिन। जॉन से जुड़ा संभावित डुप्लिकेट उपयोगकर्ताओं के बारे में लगता है। यह प्रश्न शीर्षक में "उपयोगकर्ता" कहता है, लेकिन प्रश्न कोड में और स्वीकृत उत्तर में लॉगिन से संबंधित है। मैंने शीर्षक संपादित किया और तदनुसार प्रश्न किया।
लार्स

1
बस @LHH द्वारा टिप्पणी जोड़ने के लिए, लॉगिन SQL सर्वर आवृत्ति के साथ संबद्ध हैं , और उपयोगकर्ता किसी विशिष्ट डेटाबेस से संबद्ध हैं। डेटाबेस उपयोगकर्ताओं को सर्वर लॉगिन से बनाया जा सकता है, इसलिए उनके पास एक विशिष्ट डेटाबेस तक पहुंच है। इस उत्कृष्ट लेख को देखें और वास्तव में यह पूरी श्रृंखला का हिस्सा है (स्टारीवे टू एसक्यूएल सर्वर सिक्योरिटी)
उलटा हुआ इंजीनियर

जवाबों:


141

से यहाँ

If not Exists (select loginname from master.dbo.syslogins 
    where name = @loginName and dbname = 'PUBS')
Begin
    Select @SqlStatement = 'CREATE LOGIN ' + QUOTENAME(@loginName) + ' 
    FROM WINDOWS WITH DEFAULT_DATABASE=[PUBS], DEFAULT_LANGUAGE=[us_english]')

    EXEC sp_executesql @SqlStatement
End

6
sql इंजेक्शन को रोकने के लिए आपको QUOTENAME का उपयोग करना चाहिए। हमलावर @loginName को पास कर सकते हैं जैसेx] with password ''y'';\r\ndrop table foo;\r\n
Remus Rusanu

2
एक स्ट्रिंग के रूप में एक बयान बनाना और फिर सीधे प्रवेश करने के बजाय sp_executesql का उपयोग करना क्यों आवश्यक था CREATE LOGIN [@loginName] FROM ...? मेरी अज्ञानता को क्षमा करें, मैं सीखना चाहता हूँ ...
लार्स

4
@ लार्स: स्टेटमेंट को एक स्ट्रिंग के रूप में बनाना आवश्यक है क्योंकि क्रिएट लॉग इन लॉगिन नाम के लिए एक पैरामीटर का उपयोग नहीं कर सकता है, इसके लिए स्ट्रिंग स्ट्रिंग की आवश्यकता होती है। निश्चित नहीं है कि ऐसा क्यों है, लेकिन मुझे इसका सही तरीका पता चला।
जोसेफ बोगार्ट्स

@JosephBongaarts: ठीक है, धन्यवाद। मुझे लगता है कि यह SELECT स्टेटमेंट्स में टेबल के नाम की तरह है। हो सकता है कि यह विचार हमलों के लिए सतह क्षेत्र को कम करने के लिए है, हालांकि मुझे नहीं पता है कि यह मदद करेगा।
लार्स

1
मुझे लगता QUOTENAME()है कि चारों ओर जाता है @loginName, पूरे बयान नहीं, और फिर आप मैनुअल [और] के परिसीमन से छुटकारा पा सकते हैं @loginName
ब्रायनरी

288

यहाँ SQL Server 2005 में और बाद में अपघटित syslogins दृश्य का उपयोग किए बिना ऐसा करने का एक तरीका है:

IF NOT EXISTS 
    (SELECT name  
     FROM master.sys.server_principals
     WHERE name = 'LoginName')
BEGIN
    CREATE LOGIN [LoginName] WITH PASSWORD = N'password'
END

Server_principals दृश्य का उपयोग sql_logins के बजाय किया जाता है क्योंकि बाद वाले Windows लॉगिन को सूचीबद्ध नहीं करते हैं।

यदि आपको उन्हें बनाने से पहले किसी विशेष डेटाबेस में उपयोगकर्ता के अस्तित्व की जांच करने की आवश्यकता है, तो आप ऐसा कर सकते हैं:

USE your_db_name

IF NOT EXISTS
    (SELECT name
     FROM sys.database_principals
     WHERE name = 'Bob')
BEGIN
    CREATE USER [Bob] FOR LOGIN [Bob] 
END

17
सर्वश्रेष्ठ उत्तर, कोई डायनेमिक sql शामिल नहीं है, और न ही कोई दृश्य दृश्य उपयोग। धन्यवाद!
कैस्पर लियोन नील्सन

7
SQL Azure के मामले में, दो लक्ष्य तालिकाएँ sys.sql_logins और sys.sysusers हैं - उत्तर में इसे शामिल करना अच्छा हो सकता है।
ब्रेट

उपयोगी नहीं है अगर आपकी स्क्रिप्ट को एक चर उपयोगकर्ता नाम का उपयोग करने की आवश्यकता है।
रॉस प्रेसर

@ डेरेक मॉरिसन हम SID के लिए एक और शर्त जोड़ सकते हैं
एस्ट्रोयॉन

30

इस धागे के एक मामूली जोड़ के रूप में, सामान्य तौर पर आप उन विचारों का उपयोग करने से बचना चाहते हैं जो sys.sys * से शुरू होते हैं क्योंकि Microsoft केवल पश्चगामी संगतता के लिए उन्हें शामिल करता है। अपने कोड के लिए, आपको संभवतः sys.server_principals का उपयोग करना चाहिए। यह मान लिया गया है कि आप SQL 2005 या उससे अधिक का उपयोग कर रहे हैं।


परीक्षण किया, काम करता है, और अन्य उत्तरों की तुलना में अधिक वर्तमान। आप को भी +1।
डेविड

हाँ, 2005 के साथ Microsoft ने सिस्टम टेबलों तक सीधी पहुँच बना ली। पुराने कोड को तोड़ने से रोकने के लिए, उनमें ऐसे विचार शामिल हैं जिनका नाम पुराने तालिकाओं के समान था। हालांकि, वे केवल पुराने कोड के लिए ही हैं और नए कोड को नए विचारों का उपयोग करना चाहिए। BOL में, आप क्या उपयोग करना चाहिए, यह जानने के लिए मैपिंग सिस्टम टेबल्स पर एक खोज करें।
बोमलिन

11

आप अंतर्निहित फ़ंक्शन का उपयोग कर सकते हैं:

SUSER_ID ( [ 'myUsername' ] )

के जरिए

IF [value] IS NULL [statement]

पसंद:

IF SUSER_ID (N'myUsername') IS NULL
CREATE LOGIN [myUsername] WITH PASSWORD=N'myPassword', 
DEFAULT_LANGUAGE=[us_english], 
CHECK_EXPIRATION=OFF, 
CHECK_POLICY=OFF 
GO

https://technet.microsoft.com/en-us/library/ms176042(v=sql.110).aspx


नीति और समाप्ति जाँच अक्षम करने वाले वैकल्पिक क्षेत्रों को शामिल करने के लिए बनाया गया।
आर्किबाल्ड

8

इसे आज़माएं ('उपयोगकर्ता' को वास्तविक लॉगिन नाम से बदलें):

IF NOT EXISTS(
SELECT name 
FROM [master].[sys].[syslogins]
WHERE NAME = 'user')

BEGIN 
    --create login here
END

@Marc: क्षमा करें, लेकिन आप गलत हैं। तालिका [syslogins] लॉगिन रखता है और तालिका [sysusers] उपयोगकर्ताओं को रखता है।
18

6

यह SQL Server 2000 पर काम करता है।

use master
select count(*) From sysxlogins WHERE NAME = 'myUsername'

SQL 2005 पर, दूसरी पंक्ति को बदल दें

select count(*) From syslogins WHERE NAME = 'myUsername'

मैं SQL 2008 के बारे में निश्चित नहीं हूं, लेकिन मैं यह अनुमान लगा रहा हूं कि यह SQL 2005 के समान होगा और यदि नहीं, तो यह आपको एक विचार दे सकता है कि टी कहां से शुरू हो रही है।


5

आप वास्तव में लॉगिन या उपयोगकर्ता के लिए क्या चाहते हैं? एक लॉगिन सर्वर स्तर पर बनाया जाता है और एक उपयोगकर्ता डेटाबेस स्तर पर बनाया जाता है ताकि सर्वर में एक लॉगिन अद्वितीय हो

एक उपयोगकर्ता भी एक लॉगिन के खिलाफ बनाया गया है, लॉगिन के बिना एक उपयोगकर्ता एक अनाथ उपयोगकर्ता है और यू के रूप में उपयोगी नहीं है क्योंकि लॉगिन के बिना sql सर्वर लॉगिन बाहर नहीं कर सकता

शायद आपको इसकी आवश्यकता है

लॉगिन के लिए जाँच करें

select 'X' from master.dbo.syslogins where loginname=<username>

उपरोक्त क्वेरी वापसी 'X' के लिए है, यदि लॉगिन मौजूद है, तो अन्य अशक्त है

फिर एक लॉगिन बनाएं

CREATE LOGIN <username> with PASSWORD=<password>

यह sql सर्वर में एक लॉगिन बनाता है। लेकिन यह केवल मजबूत पासवर्ड स्वीकार करता है

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

CREATE USER <username> for login <username>

उपयोगकर्ता को निष्पादित अधिकार प्रदान करें

 GRANT EXECUTE TO <username>

आप जरूरी के लिए SYSADMIN अनुमतियाँ या 'सा' कहेंगे

आप एक डेटाबेस पर उसके लिए एक sql प्रक्रिया लिख ​​सकते हैं

create proc createuser
(
@username varchar(50),
@password varchar(50)
)
as
begin
if not exists(select 'X' from master.dbo.syslogins where loginname=@username)
begin
 if not exists(select 'X' from sysusers where name=@username)
 begin
exec('CREATE LOGIN '+@username+' WITH PASSWORD='''+@password+'''')
exec('CREATE USER '+@username+' FOR LOGIN '+@username)
exec('GRANT EXECUTE TO '+@username)
end
end
end

5

लॉगिन, रोल्स, उपयोगकर्ताओं आदि के बीच नामकरण संघर्ष को संभालने के typeलिए आपको Microsoft sys.database_principals प्रलेखन के अनुसार कॉलम की जांच करनी चाहिए

उपयोगकर्ता नाम इत्यादि में विशेष अध्यायों को संभालने के लिए, तदनुसार N'<name>'और उपयोग करें [<name>]

लॉगिन बनाएं

USE MASTER
IF NOT EXISTS (SELECT 1 FROM master.sys.server_principals WHERE 
[name] = N'<loginname>' and [type] IN ('C','E', 'G', 'K', 'S', 'U'))
    CREATE LOGIN [<loginname>] <further parameters>

डेटाबेस उपयोगकर्ता बनाएँ

USE <databasename>
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE 
[name] = N'<username>' and [type] IN ('C','E', 'G', 'K', 'S', 'U'))
    CREATE USER [<username>] FOR LOGIN [<loginname>]

डेटाबेस भूमिका बनाएँ

USE <databasename>
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE 
[name] = N'<rolename>' and Type = 'R')
    CREATE ROLE [<rolename>]

उपयोगकर्ता को भूमिका में जोड़ें

USE <databasename>
EXEC sp_addrolemember N'<rolename>', N'<username>'

भूमिका का अधिकार देना

USE <databasename>
GRANT SELECT ON [<tablename>] TO [<rolename>]
GRANT UPDATE ON [<tablename>] ([<columnname>]) TO [<rolename>]
GRANT EXECUTE ON [<procedurename>] TO [<rolename>]


-1

पहले आपको syslogins दृश्य का उपयोग करके लॉगिन अस्तित्व की जांच करनी होगी:

IF NOT EXISTS 
    (SELECT name  
     FROM master.sys.server_principals
     WHERE name = 'YourLoginName')
BEGIN
    CREATE LOGIN [YourLoginName] WITH PASSWORD = N'password'
END

फिर आपको अपने डेटाबेस के अस्तित्व की जाँच करनी होगी:

USE your_dbname

IF NOT EXISTS
    (SELECT name
     FROM sys.database_principals
     WHERE name = 'your_dbname')
BEGIN
    CREATE USER [your_dbname] FOR LOGIN [YourLoginName] 
END

1
मुझे पता नहीं है - यह कहना कि "आपको syslogins दृश्य का उपयोग करके लॉगिन अस्तित्व की जांच करनी है", फिर कोड पोस्ट करना जो उस दृश्य का उपयोग नहीं करता है वह प्रतिलिपि और पेस्ट समस्या जैसा दिखता है। इसके अलावा, पहले बयान के बाद, लाइन "फिर आपको अपने डेटाबेस के अस्तित्व की जांच करनी होगी", समानांतर रूप का उपयोग करते हुए, ऐसा लगता है कि आप किसी डेटाबेस के अस्तित्व की जांच करने के लिए कह रहे हैं, न कि डीबी स्तर के उपयोगकर्ता। और आपको यह निर्दिष्ट करने की आवश्यकता है कि दूसरे बैच को लक्ष्य DB के अंदर चलाने की आवश्यकता है। कुल मिलाकर, यह सिर्फ एक बहुत ही खराब व्याख्या है। और जब से आपने इसे पांच साल के लिए जोड़ा, तब तक सबसे ज्यादा उत्तोलित किए गए उत्तर ने भी यही कहा, लेकिन बेहतर ...
लाफिंग वेरगिल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.