2017-10-01 5 views
-1

Disons que je TableA qui a 5 colonnes:SQL Server sélectionner des colonnes uniquement avec des autorisations

Col1 
Col2 
Col3 
Col4 
Col5 

et je suis connecté à SQL Server via User1. Cette Utilisateur1 dispose des autorisations pour sélectionner col1, col2, col3 ne

je peux faire

select * 
from information_schema.COLUMN_PRIVILEGES 

et boucle pour toutes les colonnes de retour et de construire mon instruction select, mais j'ai plus de 500 instructions select dans mon projet (BIG HR Management System), j'ai donc besoin d'un autre moyen avec moins de modification de code.

Maintenant, si j'essaie

Select * from TableA 

il renvoie une erreur.

Alors, comment puis-je sélectionner uniquement les colonnes avec des autorisations sans changer tout mon code?

Modifié: Je veux une méthode pour remplacer exception SQL lors de la sélection d'une colonne sans autorisation, il suffit de retourner nulle et montrer aucune exception

Édité 2: - select * était juste un exemple, d'être plus simple: si j'ai 2 utilisateurs SQL Server, le premier a la permission dans col1 - col3 le second est autorisé à col4-col6 quelle est la meilleure méthode pour sélectionner des colonnes avec l'autorisation de chaque utilisateur

+2

Fixez votre application pour qu'elle ne récupère que les colonnes nécessaires. Vous devrez peut-être construire les requêtes en fonction de ce à quoi les utilisateurs ont accès. –

+2

Vous devriez toujours sélectionner uniquement les colonnes dont vous avez besoin plutôt que d'utiliser '*', donc je ne vois pas le problème. –

+0

Ce projet a environ 10 ans de développement, il me faudra un mois pour corriger toutes les requêtes – mothana

Répondre

1

Je suis entièrement d'accord avec les commentaires suggérant que différentes requêtes soient écrites pour différents comportements, plutôt que de le faire de manière dynamique pour chaque utilisation r. Bien que je comprenne le désir de le faire dynamiquement (et vous le pouvez certainement), il va probablement être d'un effort égal, ou plus pour modifier toutes vos requêtes existantes pour travailler dynamiquement. Par ailleurs, vous avez dit requêtes au lieu de procédures. Aucun indice si c'est réellement ce que vous faites, mais si votre application construit seulement ad hoc sql, je recommanderais d'utiliser des procédures stockées à la place. Si vous l'êtes déjà, ignorez ce dernier commentaire.

Cela dit, voici un peu de code qui illustre comment vous pouvez le faire dynamiquement. Que vous écriviez ce code dans chacune de vos procédures, ou construisiez une fonction qui renvoie une chaîne (représentant les colonnes auxquelles l'utilisateur a droit) ou construisiez ce comportement dans une procédure stockée distincte qui est appelée par chaque proc, j'espère que cela devrait pointer vous vers votre solution.

J'ai construit une petite maquette ici, donc cela devrait être entièrement rechargeable. Je viens de choisir l'un des comptes de service existants (NT Service \ SQLWriter) en tant qu'utilisateur arbitraire à des fins d'illustration.

-- Assumes you have a dB called test 
use test 
go 

-- Set up test table 
if object_id('test.dbo.colpriv', 'U') is not null drop table test.dbo.colpriv 
create table dbo.colpriv 
(
    Col1 int, 
    Col2 int, 
    Col3 int 
) 
insert into dbo.colpriv values (1, 3, 5) 

grant select on dbo.colpriv (Col1, Col3) to [NT SERVICE\SQLWriter] 

go 

declare 
    @Principal varchar(100) = 'NT SERVICE\SQLWriter', -- Just picked one out of a hat from sys.server_principials 
    @Sql nvarchar(max), 
    @Columns nvarchar(max) 

select 
    @Columns = stuff((select ',' + quotename(column_name) 
         from test.INFORMATION_SCHEMA.COLUMN_PRIVILEGES 
         where table_name = 'colpriv' 
          and grantee = @Principal 
         order by column_name 
         for xml path('')), 1, 1, ''), 
    @Sql = ' 
     select ' + @Columns + ' 
     from dbo.colpriv' 

exec sp_executesql @Sql