2011-08-16 50 views
2

方案:我需要为ASP.Net应用程序的审计人员创建报告。我有一个程序解析授权标记目录中的web.config文件的XML,并创建一个报告,提供哪些用户可以访问站点结构中的哪个文件夹。该报告如下所示。SQL Group通过条件

用户名,名字,姓氏,目录,角色,访问, LastLoginDate

enter image description here

问题:你可以从报告中看到一些目录(与GISMO中间列在其中)显示两次,允许和拒绝用户。我想知道是否有办法以这样的方式对结果进行分组,如果有一个允许目录的行,那么拒绝的不会显示,但否则它们是。

或者,如果这可以在VB.net/C#中操作,那也是一个选项。它回到那里并被输入Excel电子表格。

任何帮助表示赞赏。提前致谢。

编辑:我应该说得更好。我仍然需要拒绝行来显示用户是否不被允许进入目录。但是,如果他们被允许,那么没有任何一点显示拒绝行。

+0

为什么不能加“那里获得=‘允许’”你查询? – Ramy

+0

我应该备份......你的查询是什么样的? – Ramy

+0

@雷米,请阅读编辑我在我的解释中不清楚。 – Gage

回答

1

像这样的东西应该工作,但这个假定你的路并没有如/目录/目录/,/目录/目录/,目录/目录/默认进入.aspx等。您最好的选择是解析数据并删除您创建的.NET流程级别的重复项,因为在该阶段解析通常更容易。

select derived.*, 
     case when exists 
     (select top 1 1 from table_name as t2 where t2.username = derived.username and t2.directory=derived.directory and t2.access = 'allow') then 1 else 0 end as is_allowed, 
     case when exists 
     (select top 1 1 from table_name as t2 where t2.username = derived.username and t2.directory=derived.directory and t2.access = 'deny') then 1 else 0 end as is_denied, 
from 
(
select distinct t.username, t.firstname, t.lastname, t.directory 
    from table_name as t 
) as derived 
4

这适用于Oracle数据库,因此它应该可以在SQL Server上运行或关闭,因为我知道SQL Server 支持CASE操作的主要组件。

CREATE TABLE user_permissions (
    user_role VARCHAR2(10) NOT NULL, 
    dir   VARCHAR2(10) NOT NULL, 
    user_access VARCHAR2(5) NOT NULL 
); 

INSERT INTO user_permissions VALUES ('admin', 'dir1', 'allow'); 
INSERT INTO user_permissions VALUES ('admin', 'dir2', 'allow'); 
INSERT INTO user_permissions VALUES ('power', 'dir1', 'allow'); -- Allow and Deny dir1 
INSERT INTO user_permissions VALUES ('power', 'dir1', 'deny'); 
INSERT INTO user_permissions VALUES ('power', 'dir2', 'deny'); 
COMMIT; 


SELECT UNIQUE j.* 
FROM (
     SELECT user_role, dir, 
       MAX(CASE user_access WHEN 'allow' THEN 1 ELSE 0 END) allowFlag, 
       MAX(CASE user_access WHEN 'deny' THEN 1 ELSE 0 END) denyFlag 
     FROM user_permissions 
     GROUP BY user_role, dir 
    ) t 
JOIN user_permissions j ON (t.user_role = j.user_role AND t.dir = j.dir) 
WHERE j.user_access = 'allow' OR (t.allowFlag = 0 and user_access = 'deny'); 

结果:

USER_ROLE DIR  USER_ACCESS 
---------- ---------- ----------- 
admin  dir1  allow  
admin  dir2  allow  
power  dir1  allow  
power  dir2  deny   

基本上,使用枢轴表的多个行聚合到单个行描述用于该目录的属性。一旦你有了聚合行,很容易比较你声明的属性加入你想要显示的行。

+0

在SQL Server环境中,您不能使用UNIQUE,但可以使用DISTINCT。 –

2

如果你有SQL Server 2005或更新,您可以使用此:

with cte as (
    select ROW_NUMBER() OVER (partition by username, directory order by access) as row, * 
    from report 
) 
select * 
from cte 
where row = 1 

在分区子句,放在任何使“组”是唯一的。

参考: http://msdn.microsoft.com/en-us/library/ms190766.aspx

http://msdn.microsoft.com/en-us/library/ms186734.aspx

+0

您的意思是“通过Access订购”吗?我认为这会更有意义。 –

+0

其实,你是对的,它可能是。改变。干杯! –

1
SELECT UserName, Firstname, LastName, Directory, Roles, Access, LastLoginDate 
FROM Report R 
WHERE Access = 'allow' 
    OR (Access = 'deny' 
     AND NOT EXISTS 
     (SELECT * 
      FROM Report R2 
      WHERE R2.Directory = R.Directory 
      AND R2.UserName = R.UserName 
      AND R2.Roles = R.Roles 
     ) 
    ) 

根据您的意见,这条线应该被删除,所以只有(UserName, Directory)组合检查:

   AND R2.Roles = R.Roles