2009-08-25 11 views
0

J'ai un tas d'enregistrements (commandes) que je veux mettre à la disposition des utilisateurs pour créer des rapports.SQL Server Reporting Services, comment appliquer au mieux les filtres

Les utilisateurs viennent de différents départements, et je voudrais le faire, de sorte que chaque département ne peut voir que leurs propres affaires.

Je n'arrive pas à comprendre comment le faire de la bonne façon.

Ce que j'ai maintenant est: - Un modèle où j'ai placé un filtre sur la table de commande.

Le filtre peut utiliser GetUserID() pour obtenir le nom des utilisateurs, mais je n'arrive pas à comprendre comment j'obtiens de cela à la table "UserDepartment" qui mappe les utilisateurs à des départements spécifiques. Bien sûr, je préférerais une solution par laquelle je n'aurais pas à créer de nouveaux groupes d'accès ou modifier le modèle pour chaque département que quelqu'un pourrait imaginer.

Des indices?

(Utilisation d'un serveur SQL 2008)

EDIT: Ce lien http://blogs.msdn.com/bobmeyers/articles/Implementing_Data_Security_in_a_Report_Model.aspx montre les bases de ce que je suis en train de faire, mais l'auteur semble supposer que chaque enregistrement ont un champ UserName qui peut être adapté.

Dans mon cas, je veux que tous les utilisateurs du département X puissent accéder à la ligne.

+1

Quel est le lien entre l'utilisateur/userdepartment et commande? – gbn

+0

Chaque commande a un DepartmentId au département propriétaire de la commande. – Soraz

Répondre

0

Ceci suppose que les utilisateurs ont des commandes. Ainsi, filtrer par les utilisateurs qui existent dans le même département que l'utilisateur du filtre. Ne pas filtrer les commandes directement.

Je l'ai deviné au schéma et les noms de colonnes: PHEO vous obtenez l'idée ...

SELECT 
    MY STuff 
FROM 
    Order O 
    JOIN 
    UserDept UD ON O.UserCode = UD.UserCode 
WHERE 
    EXISTS (SELECT * 
     FROM 
      UserDept UD2 
     WHERE 
      UD2.UserCode = @MYUSerCode 
      AND 
      UD2.DeptID = UD.DeptID) 

--or 
SELECT 
    MY STuff 
FROM 
    Order O 
    JOIN 
    UserDept D ON O.UserCode = D.UserCode 
    JOIN 
    UserDept U ON D.DeptID = U.DeptID 
WHERE 
    U.UserCode = @MYUSerCode 
+0

Lorsque vous créez un modèle pour SRSS, vous pouvez ajouter des filtres et des champs au modèle, ce qui crée son propre SQL dans les coulisses. Est-ce la même chose? Je crains que si j'utilise SQL pour définir la source de données, je ne serai pas en mesure d'utiliser le GetUserID() du modèle. – Soraz

+0

Désolé, je n'ai pas utilisé de modèles dans SSRS. Sûrement c'est une fonction de données de toute façon: un ensemble joint/filtre basé, et pas quelque chose à faire dans le rapport lui-même? – gbn

+0

@Soraz: Vous pouvez toujours passer l'ID utilisateur en tant que paramètre à la source de données droite? – Faiz

0

Qu'est-ce que vous essayez d'atteindre est difficile en utilisant la méthode GetUserID(). Pour utiliser que votre requête source devrait renvoyer un grand nombre de données redondantes, imaginer quelque chose comme ce qui suit:

/* 
Table: User 
Fields: UserID, LoginName, FullName 

Table: Department 
Fields: DepartmentID, Name 

Table: UserDepartments 
Fields: UserID, DepartmentID 

Table: Order 
Fields: OrderNumber, DepartmentID 
*/ 

SELECT O.OrderNumber, O.DepartmentID, U.LoginName 
FROM Order O 
JOIN Department D ON D.DepartmentID = O.DepartmentID 
JOIN UserDepartments UD ON UD.DepartmentID = D.DepartmentID 
JOIN User U ON U.UserID = UD.UserID 

Cela vous donnera plus de lignes que vous voulez, essentiellement une copie de l'ordre pour chaque utilisateur dans le département qui possède l'ordre.

Maintenant vous pouvez appliquer votre filtre comme décrit dans le lien que vous avez fourni. Cela le filtrera vers une seule copie des rangées de commandes pour l'utilisateur actuel si elles sont dans le bon département. S'il s'agit d'un problème de performances, il existe d'autres alternatives, la plus simple étant d'utiliser un rapport local (.RDLC) dans ASP.NET, WinForms ou WPF et de transférer les informations utilisateur à l'appel de données afin que le filtrage puisse être effectué. SQL

1

Nous avons rencontré un problème similaire et avons fini par écrire une fonction dans SQL.

La fonction fait ce qui suit:

  1. reçu le paramètre de nom d'utilisateur SRSS
  2. Performed une recherche sur la table des autorisations et les enregistrements récupérés (département Id est dans votre cas).
  3. retourné le numéro de service de Ensuite, notre instruction SQL

ressemblait à ceci:

SELECT * DE ASPECT OÙ departmentId IN (SELECT Id DE fn_GetUserDepartmentAllocations (@UserName))

Cela fait nous force à modifier toutes les requêtes sql mais cela nous a permis de le faire avec une logique complexe minimale.

L'autre chose que cela permet est si vous avez un utilisateur qui transcende les limites du département: par exemple un gestionnaire de 2 départements.

CREATE FUNCTION [dbo].[fn_GetUserDepartmentAllocations] 
(
    @UserName NVARCHAR(100) 
) 
RETURNS 
    @TempPermissions TABLE 
(
    DepartmentId Int 
) 
AS 
BEGIN 

     INSERT INTO @TempPermissions  
     SELECT DepartmentId 
     FROM DepartmentPermissions 
     WHERE DepartmentAllowedUsername = @UserName 

    RETURN 
END 

Le principal avantage de le faire de cette façon est il vous permet également d'éditer un endroit pour changer toute la structure des autorisations, vous n'avez pas à passer par chaque rapport pour le changer, au lieu que vous changez Par exemple, vous pourriez avoir un manager qui appartient à 2 départements mais qui n'est pas autorisé à les voir sauf le jeudi (je connais un exemple idiot mais vous obtenez le point si tout va bien).

Hope this helps

Pete

Questions connexes