web-dev-qa-db-fra.com

ne peut pas s'exécuter en tant que principal de la base de données car le principal n'existe pas - DB Restoration

J'ai reçu une sauvegarde de base de données d'un de mes clients et maintenant j'essaye de la restaurer dans mon système.

J'ai essayé de rechercher ce problème sur Google et j'ai essayé la plupart des solutions suggérées, mais aucune ne fonctionne. Quelqu'un peut-il suggérer une solution spécifique pour cette erreur après la restauration de la base de données?

Capture d'écran de l'erreur Screenshot of error

Merci d'avance!

5
iKishanSojitra

Lorsque vous restaurez une base de données, elle contient des utilisateurs de base de données . Ces utilisateurs sont transportés avec la base de données, chaque fois que vous effectuez une sauvegarde et une restauration sur un autre serveur SQL.

Sur vos serveurs SQL source et cible, vous aurez les connexions SQL Server . Ces connexions sont soit des comptes SQL Server (connexions natives SQL Server), soit des comptes Windows Server/Domain (comptes Windows).

Connexions SQL Server

Les connexions SQL Server (connexions SQL natives ou comptes Windows) sont stockées dans la base de données master et ont un SID unique attribué à chaque connexion SQL. Vous pouvez récupérer une liste des connexions SQL Server lorsque vous interrogez la vue du catalogue système sys.server_principals .

select * from sys.server_principals

Vous recevrez une liste des connexions SQL Server pour votre instance SQL Server.

Remarque: ce sont les connexions SQL Server et non les utilisateurs de la base de données.

Utilisateurs de base de données

Les utilisateurs de la base de données peuvent être interrogés en interrogeant la vue du catalogue système sys.database_principles de chaque base de données d'utilisateurs en émettant la requête suivante:

USE [<your_db>]
GO
SELECT * FROM sys.database_principals

Vous recevrez une liste d'utilisateurs de base de données auxquels des privilèges de base de données leur sont attribués.

Remarque: ce sont les utilisateurs de la base de données et non les connexions SQL Server.

Comportement normal

Lorsque vous créez une base de données et affectez un "utilisateur" à la base de données avec certains privilèges, vous effectuez en fait ce qui suit (en partie en arrière-plan):

  1. Création d'une connexion SQL Server avec mot de passe (sys.server_principal)
  2. Création d'un utilisateur de base de données dans la base de données (sys.database_principal)
  3. Octroi d'autorisations à l'utilisateur de la base de données (dans différentes tables, selon les privilèges)

Dans ce cas, le SID de la connexion SQL (sys.server_principal) correspondra au SID de l'utilisateur de la base de données (sys.database_principal).

Restaurer le comportement

Lorsque vous restaurez une base de données à partir d'un serveur SQL source, les utilisateurs de la base de données (connexions SQL Server natives et comptes Windows locaux uniquement) dans la base de données source auront des SID différents que les connexions SQL Server sur le serveur cible. Cela est dû au fait que le SID est unique pour la connexion Native SQL Server source et cible ou le compte Windows local.

Les connexions SQL Server basées sur les comptes de domaine Windows auront toujours le même SID, car SQL Server récupérera ces valeurs d'Active Directory.

Lorsque vous restaurez la base de données de la source vers le serveur SQL cible, les SID des connexions natives SQL Server seront incompatibles, même si un utilisateur peut être répertorié dans le sys.server_principals catalogue de gestion système de l'instance SQL Server et dans le sys.database_principals catalogue de gestion du système de la base de données restaurée.

Solution

Pour rectifier cela et vous permettre de naviguer dans la "Connexion SQL Server | autorisations" et/ou les "Propriétés de la base de données | Autorisations", vous pouvez relier ces utilisateurs de base de données orphelins à la connexion SQL Server.

Basculez vers votre base de données utilisateur et interrogez les utilisateurs de la base de données orphelins :

USE [your_db]
GO
sp_change_users_login 'Report'

Si un utilisateur est signalé comme orphelin, vous pouvez reconnecter la connexion SQL Server avec l'utilisateur de la base de données en lançant la commande suivante:

USE [your_db]
GO
sp_change_users_lgoin 'Update_one', '<database_user>', '<sql_server_login>'

Cela reliera la connexion (native) à SQL Server (sys.server_principal) sur votre instance cible, avec l'utilisateur de base de données (sys.database_principal) de la base de données restaurée.

Alternative

Voyant comme sp_change_users_login est obsolète, vous pouvez obtenir le même résultat avec ALTER USER instruction:

USE [<your_db>]
GO
ALTER USER <database_user> 
    WITH LOGIN = <sql_server_login>

Dans certains cas

... lorsque vous recevez une sauvegarde de base de données d'un client, il se peut que vous ne disposiez pas d'une connexion SQL Server correspondante à lier à l'utilisateur de base de données. Dans ce cas, vous pouvez créer une connexion SQL Server sans affecter d'autorisations à la base de données restaurée, puis lier la connexion SQL Server nouvellement créée à l'utilisateur de la base de données avec les instructions mentionnées ci-dessus.

8
John aka hot2use

L'erreur que vous obtenez provient du code que la boîte de dialogue SSMS (sur votre image) lance.

Lorsque vous interrogez le serveur sur les autorisations effectives d'un utilisateur via cette boîte de dialogue, le serveur tente de se faire passer pour l'utilisateur sélectionné, c'est-à-dire lorsque vous cliquez sur test_user, effective permissions le code qu'il lance est celui-ci:

EXECUTE AS USER = N'test_user';
SELECT 
    permission_name AS [Permission]
FROM fn_my_permissions(N'[yourDB]', N'DATABASE')
ORDER BY permission_name;
REVERT;

C'est dans le cas où l'utilisateur (test_user) est créé sans connexion.

Dans le cas où l'utilisateur a une connexion correspondante, le serveur essaie de se faire passer pour cette connexion correspondante car elle peut correspondre à plus d'utilisateurs en cas de groupe login = win.

Il y a d'autres cas où l'utilisateur est créé à partir de certificate, par exemple, mais je ne peux pas surveiller maintenant quel code est exécuté dans ce cas.

Pour savoir quel code est exécuté par le serveur dans votre cas, utilisez simplement SQL Server Profiler, vous verrez ce qu'il essaie de personnaliser et trouver la cause de l'erreur.

Je sais comment recevoir cette erreur dans le cas particulier du groupe Windows: comme elle ne peut pas être empruntée, vous obtenez exactement cette erreur.

Autres causes possibles: il se peut que vous n'ayez pas l'autorisation d'emprunter l'identité de cet utilisateur. Exécutez-vous le code en tant que sysadmin? Sinon, cela peut être votre cas

MISE À JOUR

J'ai pu le reproduire tout à l'heure. Les utilisateurs orphelins qui ont été portés avec votre base de données restaurée vers un autre serveur produiront la même erreur si vous essayez de les emprunter..

S'il existe une connexion existante portant le même nom pour votre utilisateur orphelin (mais avec un sid différent), vous pouvez résoudre ce problème en exécutant le code suivant:

alter user test_user with login = test_user

Si vous n'avez pas de connexion correspondante, vous pouvez la recréer avec le même sid, ou simplement créer une nouvelle connexion et mettre à jour l'utilisateur existant comme je l'ai fait ci-dessus.

Si vous n'avez pas du tout besoin de cet utilisateur, laissez-le tomber

0
sepupic