web-dev-qa-db-fra.com

Le principal du serveur ne peut pas accéder à la base de données dans le contexte de sécurité actuel de SQL Server MS 2012.

J'essaie d'accéder à la base de données de mon serveur d'hébergement par le biais de SQL Server Management Studio, tout se passe bien jusqu'à la connexion, mais lorsque j'utilise la commande use myDatabase, cela me donne l'erreur suivante:

The server principal "****" is not able to access the database "****" under the current security context.

J'ai cherché et les fournisseurs de services d'hébergement ont répertorié this réparer le problème.

Mais cela ne fonctionne probablement pas pour moi car c'est pour SQL Server Management Studio 2008, mais j'utilise SQL Server Management Studio 2012.

Cela peut-il être un problème? Et si oui que peut-on me dire son alternative dans SSMS 2012?

81
Maven

Vérifiez si votre utilisateur est mappé sur la base de données à laquelle vous essayez de vous connecter.

70
Scott

La même erreur s'est produite lors du déploiement d'un rapport sur SSRS dans notre environnement PROD. Il a été constaté que le problème pouvait même être reproduit avec une déclaration «use». La solution consistait à resynchroniser la référence de compte GUID de l'utilisateur avec la base de données en question (c'est-à-dire en utilisant "sp_change_users_login" comme vous le feriez après la restauration d'une base de données). Un script de stock (piloté par le curseur) permettant de resynchroniser tous les comptes est joint:

USE <your database>
GO

-------- Reset SQL user account guids ---------------------
DECLARE @UserName nvarchar(255) 
DECLARE orphanuser_cur cursor for 
      SELECT UserName = su.name 
      FROM sysusers su
      JOIN sys.server_principals sp ON sp.name = su.name
      WHERE issqluser = 1 AND
            (su.sid IS NOT NULL AND su.sid <> 0x0) AND
            suser_sname(su.sid) is null 
      ORDER BY su.name 

OPEN orphanuser_cur 
FETCH NEXT FROM orphanuser_cur INTO @UserName 

WHILE (@@fetch_status = 0)
BEGIN 
--PRINT @UserName + ' user name being resynced' 
exec sp_change_users_login 'Update_one', @UserName, @UserName 
FETCH NEXT FROM orphanuser_cur INTO @UserName 
END 

CLOSE orphanuser_cur 
DEALLOCATE orphanuser_cur
16
Anonymous

J'ai passé un bon bout de temps à lutter contre ce problème, puis j'ai réalisé que je commettais une simple erreur en oubliant à quelle base de données je ciblais ma connexion. J'utilisais la fenêtre de connexion SQL Server standard pour entrer les informations d'identification:

 SQL Server Connection Window

Je devais vérifier l'onglet Connection Properties pour vérifier que je choisissais la bonne base de données pour me connecter. J'avais accidentellement quitté l'option Connexion à la base de données définie ici sur une sélection d'une session précédente. C'est pourquoi je ne pouvais pas me connecter à la base de données I pensée à laquelle je tentais de me connecter.

 Connection Properties

Notez que vous devez cliquer sur le bouton Options >> pour que Connection Properties et les autres onglets apparaissent.

6
Phil Ringsmuth

Dans mon cas, le message était dû à un synonyme qui, par inadvertance, incluait le nom de la base de données dans le "nom d'objet". Lorsque j'ai restauré la base de données sous un nouveau nom, le synonyme désignait toujours l'ancien nom de la base de données. Étant donné que l'utilisateur ne disposait pas d'autorisations dans l'ancienne base de données, le message est apparu. Pour résoudre ce problème, j'ai supprimé et recréé le synonyme sans qualifier le nom de l'objet avec le nom de la base de données:

    USE [new_db]
GO

/****** Object:  Synonym [dbo].[synTable]    Script Date: 10/15/2015 9:45:01 AM ******/
DROP SYNONYM [dbo].[synTable]
GO

/****** Object:  Synonym [dbo].[synTable]    Script Date: 10/15/2015 9:45:01 AM ******/
CREATE SYNONYM [dbo].[synTable] FOR [dbo].[tTheRealTable]
GO
3
Joshua Yeidel

Cela a fonctionné pour moi:

use <Database>
EXEC  sp_change_users_login @Action='update_one', @UserNamePattern='<userLogin>',@LoginName='<userLogin>';

Le problème peut être visualisé avec:

SELECT sid FROM sys.sysusers WHERE name = '<userLogin>'
SELECT sid FROM sys.syslogins WHERE name = '<userLogin>';
1
azak

SQL Les connexions sont définies au niveau du serveur et doivent être mappées sur Utilisateurs dans des bases de données spécifiques.

Dans l'explorateur d'objets SSMS, sous le serveur que vous souhaitez modifier, développez Sécurité > Logins , puis double-cliquez sur l'utilisateur approprié. affichera la boîte de dialogue "Propriétés de la connexion".

Sélectionnez Mappage utilisateur , qui affichera toutes les bases de données sur le serveur, celles ayant déjà un mappage sélectionné. À partir de là, vous pouvez sélectionner d'autres bases de données (en veillant bien à sélectionner les rôles de chaque base de données auxquels l'utilisateur doit appartenir), puis cliquez sur OK pour ajouter les mappages.

enter image description here

Ces mappages peuvent être déconnectés après une restauration ou une opération similaire. Dans ce cas, l'utilisateur peut toujours exister dans la base de données mais n'est pas mappé sur un login. Si cela se produit, vous pouvez exécuter ce qui suit pour restaurer la connexion:

USE {database};
ALTER USER {user} WITH login = {login}

Vous pouvez également supprimer l'utilisateur de la base de données et le recréer à partir de la boîte de dialogue Propriétés de la connexion, mais toute appartenance à un rôle ou autre paramètre devra être recréé.

1
Toby J

J'ai rencontré la même erreur lors de l'utilisation de SMO (Server Management Objects) dans vb.net (je suis sûr que c'est la même chose en C #)

Le commentaire de Techie Joe sur le message initial était un avertissement utile sur le fait que de nombreux événements supplémentaires se produisaient dans l'hébergement mutualisé. Cela a pris un peu de temps à comprendre, mais le code ci-dessous montre qu'il faut être très spécifique dans la façon dont ils accèdent aux bases de données SQL. L'erreur 'serveur principal ...' semble apparaître chaque fois que les appels SMO ne sont pas précisément spécifiques dans l'environnement d'hébergement partagé.

Cette première section de code visait un serveur SQL Express local et reposait sur une authentification Windows simple. Tout le code utilisé dans ces exemples est basé sur le tutoriel SMO de Robert Kanasz dans cet article du site Code Project :

  Dim conn2 = New ServerConnection()
  conn2.ServerInstance = "<local pc name>\SQLEXPRESS"
  Try
    Dim testConnection As New Server(conn2)
    Debug.WriteLine("Server: " + testConnection.Name)
    Debug.WriteLine("Edition: " + testConnection.Information.Edition)
    Debug.WriteLine(" ")

    For Each db2 As Database In testConnection.Databases
      Debug.Write(db2.Name & " - ")
      For Each fg As FileGroup In db2.FileGroups
        Debug.Write(fg.Name & " - ")
        For Each df As DataFile In fg.Files
          Debug.WriteLine(df.Name + " - " + df.FileName)
        Next
      Next
    Next
    conn2.Disconnect()

  Catch err As Exception
    Debug.WriteLine(err.Message)
  End Try

Le code ci-dessus trouve très bien les fichiers .mdf de chaque base de données sur le serveur SQLEXPRESS local car l’authentification est gérée par Windows et s’applique à toutes les bases de données.

Dans le code suivant, il y a 2 sections itératives pour les fichiers .mdf. Dans ce cas, seule la première itération à la recherche d'un groupe de fichiers fonctionne et ne trouve qu'un seul fichier car la connexion est établie avec une seule base de données dans l'environnement d'hébergement partagé.

La deuxième itération, qui est une copie de l'itération qui a fonctionné ci-dessus, s'étouffe immédiatement car elle est écrite de telle sorte qu'elle tente d'accéder à la 1ère base de données dans l'environnement partagé, ce qui n'est pas celui auquel l'ID utilisateur/mot de passe s'applique. le serveur SQL renvoie une erreur d'autorisation sous la forme de l'erreur 'serveur principal ...'.

Dim sqlConnection1 As New System.Data.SqlClient.SqlConnection
sqlConnection1.ConnectionString = "connection string with User ID/Password to a specific database in a shared hosting system. This string will likely also include the Data Source and Initial Catalog parameters"
Dim conn1 As New ServerConnection(sqlConnection1)
Try
  Dim testConnection As New Server(conn1)
  Debug.WriteLine("Server: " + testConnection.Name)
  Debug.WriteLine("Edition: " + testConnection.Information.Edition)
  Debug.WriteLine(" ")

  Dim db2 = testConnection.Databases("the name of the database to which the User ID/Password in the connection string applies")
  For Each fg As FileGroup In db2.FileGroups
    Debug.Write(fg.Name & " - ")
    For Each df As DataFile In fg.Files
      Debug.WriteLine(df.Name + " - " + df.FileName)
    Next
  Next

  For Each db3 As Database In testConnection.Databases
    Debug.Write(db3.Name & " - ")
    For Each fg As FileGroup In db3.FileGroups
      Debug.Write(fg.Name & " - ")
      For Each df As DataFile In fg.Files
        Debug.WriteLine(df.Name + " - " + df.FileName)
      Next
    Next
  Next

  conn1.Disconnect()

Catch err As Exception
  Debug.WriteLine(err.Message)
End Try

Dans cette seconde boucle d'itération, le code est bien compilé, mais comme SMO n'a pas été configuré pour accéder précisément à la base de données correcte avec la syntaxe exacte, cette tentative a échoué.

Alors que je viens d’apprendre à SMO, j’ai pensé que d’autres débutants apprécieraient de savoir qu’il existe une explication plus simple de cette erreur: nous l’avons tout simplement mal codée.

0
Alan

Nous avons eu la même erreur même si l'utilisateur était correctement mappé à la connexion. 

Après avoir tenté de supprimer l'utilisateur, il s'est avéré que quelques SP contenaient "avec exécuter en tant que" cet utilisateur.

Le problème a été résolu en supprimant ces SP, l'utilisateur, en recréant l'utilisateur lié à la connexion et en recréant les SP.

Il est possible qu'il soit dans cet état à la suite d'une restauration à partir d'une sauvegarde (à un moment où la connexion associée n'existait pas) ou d'une synchronisation de schéma en bloc (s'il est possible de créer un SP avec execute comme même si l'utilisateur n'existe pas Cela aurait également pu être lié à cette réponse .

0
crokusek