2011-05-10 57 views
2

我在我的一个Oracle APEX项目中需要为特定应用程序的特定个人实现不同级别的安全性。PL SQL数据透视表VS自定义Json解决方案

首先,我创建了一个包含user表,app表和role表中的信息的笛卡尔。

它看起来像这样:

SELECT 
A.user_id, B.app_id, C.role_id 
FROM user A, app B, role C 
ORDER BY A.user_id ASC, B.app_id ASC, C.role_id ASC 

这让我返回userapp,并role每个组合。无/使用where子句它返回超过303k行。目前差不多有500个用户,6个角色和100多个应用程序。

当我从这个视图中选择一个特定的用户时,它在大约10 ms内返回,这是可以接受的。

现在,我也有一个存储每个用户的应用程序/角色分配的vw。我以下列方式将此表加入笛卡尔。

SELECT 
A.*, 
DECODE(B.app_right_id, null, 0, 1) AS user_access 
FROM 
      vw_user_app_role A -- My cartesian view 
LEFT JOIN vw_tbl_user_app_role B 
     ON A.user_id = B.user_id 
     AND A.app_id = B.app_id 
     AND A.role_id = B.role_id 

这会返回一个非常有用的数据集,类似于

user_id app_id role_id user_access 
50  5  1  0 
50  10  2  1 
50  15  3  1 
75  5  1  1 
75  10  2  0 
75  15  3  0 

我正在考虑什么我的下一个步骤应该是,如果我要创建数据的枢轴,其中APP_ID将是行,role_id将是列,并且user_access将是“数据”。 “数据”最终将作为一个复选框呈现在网站上,并带有适当的行/列标题。

我也在考虑使用纯ajax/json解决方案,我将使用pl sql构建json字符串,并将整个字符串返回给客户端,以便通过jquery进行处理。我很关心第一个选项的难度(我对pl sql非常陌生,而且我不确定如何生成一个在这个版本的oracle中使用的数据透视表(第10版))我关心的是创建一个包含这么多数据的整个json字符串。

任何建议将不胜感激。

编辑

我已经实现了我通过以下SQL所需的数据透视表:

SELECT 
B.application_nm, 
A.user_id, 
MAX(DECODE(b.role_name, 'role 1', A.USER_ACCESS, NULL)) "role 1", 
MAX(DECODE(b.role_name, 'role 2', A.USER_ACCESS, NULL)) "role 2", 
MAX(DECODE(b.role_name, 'role 3', A.USER_ACCESS, NULL)) "role 3", 
MAX(DECODE(b.role_name, 'role 4', A.USER_ACCESS, NULL)) "role 4", 
MAX(DECODE(b.role_name, 'role 5', A.USER_ACCESS, NULL)) "role 5", 
MAX(DECODE(b.role_name, 'role 6', A.USER_ACCESS, NULL)) "role 6" 
FROM 
vw_user_app_access A LEFT JOIN vw_tbl_app B ON A.app_id = B.app_id 
LEFT JOIN vw_tbl_roles C ON A.role_id = C.role_id 
GROUP BY B.application_name, A.user_id 
ORDER BY A.user_id DESC 

唯一的问题是,当在未来,我们必须添加的角色7“。我不得不回到这个查询并添加行MAX(DECODE(b.role_name, 'role 7', A.USER_ACCESS, NULL)) "role 7"

提前思考,这可能是一个不便,但考虑APEX的框架,我将不得不进入报告任何方式手动更新列数相信。

我想这可能是现在的“最佳”的解决方案,除非任何人有任何其他建议...

+0

Oracle在11g之前不支持PIVOT - 换出'CASE'的DECODE是唯一可以做出的改变。并且数据库会比客户端计算得更快... – 2011-05-10 14:45:16

+0

我知道10g中缺少PIVOT,但我一直在寻找其他方式来使用表类型和/或流水线函数来循环10g中的数据。我仍然对这种工作模糊不清,但这正是我所倾向的。 – Patrick 2011-05-10 15:01:58

+0

目前尚不清楚你到底在做什么?你的表结构是什么? – jny 2011-05-10 15:18:39

回答

2

有可能基于动态的SQL查询返回不同的顶点报表区域查询更改时的列数。我已经建立了一个简单的演示on apex.oracle.com。在“列”列表中输入一个新列名称,然后按下“添加行”,然后使用该名称的额外列重新绘制Matrix报表。

你必须:

  1. 基础上返回的SQL来运行作为一个字符串
  2. 选择区域属性“使用通用列名(在运行时分析查询只)”函数报告
  3. 将报表标题类型设置为PL/SQL,然后使用函数将所需的列标题动态返回为冒号分隔的列表。请注意,这可能与列名不同,尽管我的示例对两者使用相同的文本。

如果我的例子不够清楚,我会在稍后添加更多信息 - 现在我已经没有时间了。