2015-03-29 5 views
1

Je travaille sur un projet de base de données dans VS2013 qui contient une procédure stockée C# SQL CLR.Projet de base de données VS2013 utilisant SQL CLR - référence non résolue à l'objet [nom_serveur nom_utilisateur] (propriétaire de la base de données)

Le propriétaire de l'assemblage est [nomserveur \ user123]
Le propriétaire de la base de données est également [nomserveur \ user123] (Etre propriétaire de la base, cet utilisateur existe évidemment déjà sur le serveur. J'ai réussi un succès publier de la base de données en commentant le code dans ma procédure CLR SQL et de publication, ce qui suit se produit après avoir Décommentez-out ce code)

Si je tente de construire le projet dans VS, je reçois l'erreur.

Error 1 SQL71501: Assembly: [DatabaseProject] has an unresolved reference to object [servername\User123]. 

... causé par:

CREATE ASSEMBLY [DatabaseProject] AUTHORIZATION [servername\User123] 
FROM 0x4D5A90000300000004000000FFFF0000B8000etcetcetcetc 
WITH PERMISSION_SET = EXTERNAL_ACCESS 
GO 

Ainsi, si VS ajouter un script de création de l'utilisateur dans le dossier \ Security:

CREATE USER [servername\User123] FOR LOGIN [servername\User123] WITH DEFAULT_SCHEMA = dbo 
GO 
GRANT CONNECT TO [servername\User123] 

Ensuite, je peux construire le projet.

Cependant, si j'essaie alors de Publish la base de données, je reçois l'erreur:

Creating [servername\User123]... 
(47,1): SQL72014: .Net SqlClient Data Provider: Msg 15063, Level 16, State 1, Line 1 The login already has an account under a different user name. 
(47,0): SQL72045: Script execution error. The executed script: 
CREATE USER [servername\User123] FOR LOGIN [servername\User123]; 
An error occurred while the batch was being executed. 

Y at-il une « bonne » pour le faire?

Répondre

1

Ce problème est dû à une simple mauvaise compréhension de la façon dont SQL Server gère le «propriétaire» de la base de données en tant que «principal» de base de données. Le concept de « propriétaire de la base » montre de deux façons différentes:

  1. En tant que base de données de niveau utilisateur ayant le nom de dbo et un principal_id de 1. Maintenant, quel serveur niveau Connexion cartes à ce particulier utilisateur (c.-à « principal ») est tout simplement une question de la valeur dans le champ SID dans sys.database_principals:

    SELECT sdp.* 
    FROM [sys].[database_principals] sdp 
    WHERE sdp.[principal_id] = 1; 
    

    Ce champ carte à la SID champ sys.server_principals:

    SELECT sdp.*, '---' AS [---], ssp.* 
    FROM [sys].[database_principals] sdp 
    INNER JOIN [sys].[server_principals] ssp 
         ON ssp.[sid] = sdp.[sid] 
    WHERE sdp.[principal_id] = 1; 
    

    Faites attention aux domaines suivants sys.database_principals:

    • Type
    • type_desc
    • authentication_type
    • authentication_type_desc

    Voyant que la façon dont la base de données est actuellement détenue par une connexion Windows, exécutez la requête immédiatement au-dessus (la 2ème requête - celle à la fois les tables). Ensuite, modifiez la base de données à détenir par sa. Ensuite, ouvrez un nouvel onglet de requête.Enfin, exécutez la même requête dans cette nouvelle fenêtre (de sorte que vous puissiez facilement comparer les résultats "avant" et "après"), en veillant à porter une attention particulière aux 4 champs indiqués ci-dessus, ainsi qu'au champ sid. (S'il vous plaît noter qu'il est possible de créer utilisateur s sans Connexion s et ceux qui ne se présentera pas, de toute évidence, dans une requête JOIN à sys.server_principals, mais cette question est traitant spécifiquement Connexion s).

    De tout cela, vous devriez voir que la spécification d'un Connectez-vous être le « propriétaire » d'une base de données ne pas, en fait, créer un utilisateur pour cette Connexion: il met à jour simplement la définition du dboUtilisateur. Par conséquent, le Login qui possède la base de données techniquement existent dans cette base de données, mais toujours avec le nom de dbo au lieu de son nom réel. C'est pourquoi vous obtenez l'erreur suivante:

    The login already has an account under a different user name.

  2. En tant que base de données rôle que tout utilisateur dans la base de données peut être ajouté à l'ordre à donner ces autorisations.

Pour fixer:

  • Retirez votre script CREATE USER du dossier \ Security.
  • Utilisez plutôt AUTHORIZATION [dbo].