2009-09-04 4 views
137

Je dois vérifier si une connexion spécifique existe déjà sur SQL Server, et si ce n'est pas le cas, je dois l'ajouter.Vérification de l'existence d'une connexion SQL Server

J'ai trouvé le code suivant pour ajouter réellement la connexion à la base de données, mais je veux envelopper ceci dans une instruction IF (en quelque sorte) pour vérifier si la connexion existe en premier. Je comprends que j'ai besoin d'interroger une base de données du système, mais je ne sais pas par où commencer!

+0

Quelle version de SQL Server? – pjp

+10

Ceci est une question importante, mais comme formulé, il semble manquer une distinction importante: utilisateur ou connexion. Le doublon potentiel auquel Jon est lié semble vraiment concerner les utilisateurs. Cette question dit "utilisateur" dans le titre, mais traite des connexions dans le code de la question et dans la réponse acceptée. J'ai édité le titre et la question en conséquence. – LarsH

+1

Juste pour ajouter au commentaire de @LarsH, ** les connexions ** sont associées à une instance de serveur SQL, et ** les utilisateurs ** sont associés à une base de données spécifique. Les utilisateurs de la base de données peuvent être créés à partir des connexions au serveur, de sorte qu'ils ont accès à une base de données spécifique. Voir [cet excellent article] (http://www.sqlservercentral.com/articles/Stairway+Series/109975/) et en fait toute la série dont il fait partie (Stariway to SQL Server Security) – DaveBoltman

Répondre

116

De here

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 
+2

+1. Meilleure réponse que la mienne. Bonne réponse. – David

+6

vous devez utiliser QUOTENAME pour empêcher l'injection SQL. L'attaquant peut passer un @loginName comme 'x] avec le mot de passe '' y ''; \ r \ ndrop table foo; \ r \ n' –

+0

Bon, merci les gars! –

5

Cela fonctionne sur SQL Server 2000.

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

sur SQL 2005, changer la 2ème ligne à

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

Je ne suis pas sûr de SQL 2008, mais je suppose que ce sera le même que SQL 2005 et sinon, cela devrait vous donner une idée de Avant de commencer à chercher.

8

Essayez ceci (remplacer « utilisateur » avec le nom de connexion réelle):

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

BEGIN 
    --create login here 
END 
+0

@ Marc: Désolé mais vous avez tort. La table [syslogins] conserve les connexions et la table [sysusers] conserve les utilisateurs. – abatishchev

27

En outre mineur à ce fil, en général, vous voulez éviter d'utiliser les vues qui commencent par sys.sys * comme Microsoft les inclut uniquement pour la rétrocompatibilité. Pour votre code, vous devriez probablement utiliser sys.server_principals. Cela suppose que vous utilisez SQL 2005 ou supérieur.

+0

Testé, fonctionne et plus actuel que les autres réponses. +1 à vous aussi. – David

+0

bon à savoir, merci! – Marc

+0

Oui, avec 2005 Microsoft a enlevé l'accès direct aux tables système. Pour ne pas casser l'ancien code, ils incluent des vues portant le même nom que les anciennes tables.Cependant, ils sont uniquement destinés à un code plus ancien et un code plus récent devrait utiliser les nouvelles vues. Dans BOL, effectuez une recherche sur Mapping System Tables pour savoir ce que vous devez utiliser. – Bomlin

246

est ici une façon de le faire dans SQL Server 2005 et plus tard sans utiliser les syslogins déconseillés voir:

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

La vue server_principals est utilisé au lieu de sql_logins parce que ce dernier ne répertorie pas les connexions Windows.

Si vous devez vérifier l'existence d'un utilisateur dans une base de données particulière avant de les créer, vous pouvez le faire:

USE your_db_name 

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

Nice, merci! –

+15

Meilleure réponse, pas de SQL dynamique impliqué, ni utilisation de vue obsolète. Merci! –

+4

Dans le cas de SQL Azure, les deux tables cibles sont sys.sql_logins et sys.sysusers. Cela peut être pratique si vous incluez cette variable dans la réponse. – Brett

4

ce que vous voulez exactement vérifier la connexion ou l'utilisateur? une connexion est créée au niveau du serveur et un utilisateur est créé au niveau de la base de données donc un login est unique au serveur

Un utilisateur est également créé pour une connexion, un utilisateur sans connexion est un utilisateur orphelin et n'est pas utile ne peux pas effectuer la connexion serveur sql sans connexion

peut-être u besoin de ce

chèque de connexion

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

le retour de requête ci-dessus « X » si la connexion existe nulle autre retour

puis créez une connexion

CREATE LOGIN <username> with PASSWORD=<password> 

cela crée une connexion avec un serveur SQL.mais il accepte que des mots de passe

créer un utilisateur dans chaque base de données que vous voulez pour se connecter comme

CREATE USER <username> for login <username> 

assign exécuter les droits à l'utilisateur

GRANT EXECUTE TO <username> 

VOUS devez disposer des autorisations SYSADMIN ou dire « sa »pour court

vous pouvez écrire une procédure SQL pour que, sur une base de données

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

Vous devez d'abord vérifier l'existence de connexion à l'aide syslogins voir:

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

Ensuite, vous devez vérifier votre existence de base de données:

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 
+0

Je ne sais pas - en disant que "vous devez vérifier l'existence de connexion en utilisant syslogins view", puis en publiant du code qui n'utilise pas cette vue ressemble à un copier-coller. En outre, après la première instruction, la ligne "Ensuite, vous devez vérifier l'existence de votre base de données", en utilisant la forme parallèle, semble demander à quelqu'un de vérifier l'existence d'une base de données, pas un utilisateur DB. Et vous devez spécifier que le deuxième lot doit être exécuté dans la base de données cible. Dans l'ensemble, c'est juste une très mauvaise explication. Et puisque vous l'avez ajouté cinq ans après la réponse la plus élevée mise à jour dit la même chose, mais mieux ... –

1

Vous pouvez utiliser la fonction intégrée:

SUSER_ID ([ 'myUsername' ]) 

via

IF [value] IS NULL [statement] 

comme:

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

Questions connexes