我的权限记录绑定到我的应用程序中的每个帐户。每个帐户可以具有一个或多个基于帐户类型的权限记录。这是示例:
<cfquery name="qryUserPerm" datasource="#Application.dsn#"> SELECT AccessType, AccessLevel, State, City, Building FROM Permissions WHERE AccountID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(session.AccountID)#"> </cfquery>
上面的查询将为其中一个帐户产生这样的数据:
RecID AccountID AccessType AccessLevel State City Building 70 285A637D82B9 F B NY New York 8010 71 285A637D82B9 F B NY New York 5412 73 285A637D82B9 F B NY New York 6103 74 285A637D82B9 F B NY New York 3106
正如您在上方看到的,此帐户已分配了4条记录。访问类型可以是“完全”F或“仅查看” V。访问级别可以是州“ S”,城市“ C”或建筑物“ B”。用户一次只能分配一个访问级别,因此,例如,不存在用户可以分配城市和州级别的情况。我的问题是,针对特定访问级别从查询组织数据的最佳方法是什么?在这种情况下,我必须合并列表或数组中的4条记录。州级别只能分配一个权限记录,城市和建筑物可以具有多个记录。这是我所拥有的示例:
F
V
<cfset local.permissionType = ""> <cfset local.permissionLevel = ""> <cfset local.permissionList = ""> <cfloop query="qryUserPerm"> <cfif qryUserPerm.AccessLevel EQ "S"> <cfset local.permissionType = qryUserPerm.AccessType> <cfset local.permissionLevel = qryUserPerm.AccessLevel> <cfset local.permissionList = listAppend(permissionList, "", ",")> <cfelseif qryUserPerm.AccessLevel EQ "C"> <cfset local.permissionType = qryUserPerm.AccessType> <cfset local.permissionLevel = qryUserPerm.AccessLevel> <cfset local.permissionList = listAppend(permissionList, qryUserPerm.City, ",")> <cfelseif qryUserPerm.AccessLevel EQ "B"> <cfset local.permissionType = qryUserPerm.AccessType> <cfset local.permissionLevel = qryUserPerm.AccessLevel> <cfset local.permissionList = listAppend(permissionList, qryUserPerm.Building, ",")> <cfelse> <cfset local.permissionType = ""> <cfset local.permissionLevel = ""> <cfset local.permissionList = listAppend(permissionList, "", ",")> </cfif> </cfloop>
这似乎是多余的,以保持permissionType和permissionLevel环路内,但我不知道现在更好的办法来避免这种情况。同样,如果我必须比较权限列表,这会使过程非常困难。我必须运行相同的过程并构建列表,以便与Session.premissionList当前登录的用户更改其权限的情况进行比较。有什么办法可以将这些记录与SQL合并?还是这种方法是更好的选择?
permissionType
permissionLevel
Session.premissionList
这可以在SQL本身中完成,这可能比处理代码中的数据更有效。
随着数据的一个问题是State,City和Building列必须逆转置,然后被变成了逗号分隔的列表。
State
City
Building
由于使用的是SQL 2008,因此可以访问所需的功能。
查询是:http : //sqlfiddle.com/#!18/0f4f7/1
; WITH cte AS ( SELECT AccountID, AccessType, AccessLevel , CASE AccessLevel WHEN 'S' THEN State WHEN 'C' THEN City WHEN 'B' THEN Building END AS Permissions FROM Permissions WHERE AccountID = <cfqueryparam cfsqltype="cf_sql_integer" value="#session.AccountID#"> /* Dynamic variable here */ ) SELECT DISTINCT AccountID, AccessType, AccessLevel , CASE WHEN AccessLevel = 'S' THEN Permissions ELSE LEFT(ca.pl, COALESCE(LEN(ca.pl),0)-1) END AS PermissionList FROM cte CROSS APPLY ( SELECT p.Permissions + ', ' FROM cte p WHERE p.AccountID = cte.AccountID AND p.AccessType = cte.AccessType AND p.AccessLevel = cte.AccessLevel FOR XML PATH('') ) ca (pl) ;
我先从CTE开始,以建立Permissions基于的“不可透视的”列表AccessLevel。如果可以将其放在SQL视图中,则可以在WHERE此处省略该语句,并在调用视图时调用它。如果可以将View放入数据库,则将是我的首选。
Permissions
AccessLevel
WHERE
之后,我有CTE,我只是选择了基列(AccountID,AccessType和AccessLevel,然后我CROSS APPLY一个逗号分隔的列表Permissions。我用FOR XML PATH('')构建一个逗号分隔的列表。
AccountID
AccessType
CROSS APPLY
FOR XML PATH('')
如果能够将其转换为视图,那将是一个简单的过程
<cfquery name="qryUserPerm" datasource="#Application.dsn#"> SELECT AccessType, AccessLevel, PermissionList FROM myPermissionsView WHERE AccountID = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(session.AccountID)#"> </cfquery>
如果不是,则必须尝试在cfquery标记内运行上述完整查询。
cfquery
这应该给您返回一个数据集,例如:
| AccessType | AccessLevel | PermissionList | |------------|-------------|------------------------| | F | B | 8010, 5412, 6103, 3106 |
您只有一个结果可以使用,而不必循环。
================================================== ====================
如果您想采用代码内方法,我仍然建议您尝试使用它cfscript来构建结构。但是,如果您可以有多个AccessLevel,则结果可能与您认为的不一样。您必须仔细检查您的数据。
cfscript
local.permissionType = q2.AccessType ; local.permissionLevel = q2.AccessLevel ; switch( q2.AccessLevel ) { case "S" : local.permissionList = q2.State ; break ; case "C" : local.permissionList = ListRemoveDuplicates(ValueList(q2.City)) ; break ; case "B" : local.permissionList = ListRemoveDuplicates(ValueList(q2.Building)) ; break ; }
https://trycf.com/gist/e811ec86f0d5a52fd9ce703f897cb5aa/acf2016?theme=monokai