Dépannage de la visibilité des métadonnées des vues partitionnées distribuées

Si un utilisateur dont les privilèges sont restreints tente d'insérer, de mettre à jour ou de supprimer des données via une vue partitionnée distribuée, SQL Server génère l'erreur suivante :

Erreur 4436 « Impossible de mettre à jour la vue UNION ALL '%1!s!' car une colonne de partitionnement est introuvable ».

Ce problème n'affecte pas les vues partitionnées localement en particulier lorsque toutes les tables sous-jacentes existent sur la même instance de SQL Server.

Historique

Pour les requêtes distribuées, SQL Server doit pouvoir lire la définition SQL des contraintes CHECK sur les tables du serveur distant (lié). Cela signifie que l'appelant d'une requête distribuée doit avoir les autorisations CONTROL, ALTER, TAKE OWNERSHIP ou VIEW DEFINITION sur la table distante. Si l'appelant de la requête distribuée ne possède pas une de ces autorisations, la requête échoue et génère l'erreur 4436.

Notes

Si un utilisateur ne possède aucune de ces autorisations, la valeur de la colonne definition dans sys.check_constraints est NULL lorsque l'utilisateur interroge le catalogue.

Pour résoudre l'erreur 4436

Pour rendre la définition de la contrainte CHECK visible pour l'appelant, accordez-lui l'autorisation VIEW DEFINITION sur chaque table cible sous-jacente à la vue partitionnée distribuée.

Par exemple, supposons que Server1 et Server2 sont des serveurs fédérés et ont été définis comme serveurs liés l'un à l'autre. Supposons que master.dbo.t1 est la table partitionnée à laquelle tous les membres du rôle de base de données dpv_users peuvent accéder. Supposons que dpv_users contient tous les utilisateurs ayant un accès SELECT, INSERT, UPDATE et DELETE via la vue partitionnée distribuée.

Exécutez le code suivant sur chaque serveur lié.

CREATE TABLE t1(c INT PRIMARY KEY CHECK (...)) ; -- CHECK is different on each server.
GO

GRANT SELECT, INSERT, UPDATE, DELETE, VIEW DEFINITION ON t1 TO dpv_users ;
GO

CREATE VIEW the_dpv AS
    SELECT * FROM Server1.master.dbo.t1
    UNION ALL
    SELECT * FROM Server2.master.dbo.t1 
GO