有几种方法可以解决这个问题:
- 组合数据库并按公司选择
- 一个数据库中用于分隔公司的架构。为此需要进行一些维护。
- 每个公司的独立数据库。跨公司的聚合可能很复杂。
假设对于有权访问组合数据库的内部人员而言这不是安全问题,最简单的方法是组合数据库,并在报告中包含逻辑以确保人们只能看到他们被允许访问的公司。
这里有两个问题:
- 确定谁在运行报告
- 确定可以为哪些公司生成报告
Reporting Services 使用@UserId 全局变量为您解决了第一个问题。
我假设你有一个表格Company,看起来有点像这样:
CompanyId | Name | ParentCompanyId
----------+-------------+----------------
1 | ABC Inc. |
2 | DEF Co. | 1
3 | GHI Ltd. | 1
4 | XYZ Corp. |
我们需要一种将其映射到他们可以为其运行报告的公司的方法,因此我们创建了一个包含 UserId 和 CompanyId 字段的表,以将用户映射到他们的公司。
UserId | Name | CompanyId
----------+-------------+----------
10 | Alyssa | 1
20 | David | 2
30 | Gloria | 3
40 | Xavier | 4
所以 Alyssa 可以看到 ABC Inc 及其子公司 DEF Co 和 GHI Ltd,而 David 只能看到 DEF Co,Gloria 只能看到 GHI Ltd,Xavier 只能看到 XYZ Corp。
在您的报告中,您可以根据关系选择数据:
SELECT Invoices.CompanyId, Invoices.Number, Invoices.Date, Invoices.Amount
FROM Invoices
INNER JOIN Companies ON Invoices.CompanyId = Companies.CompanyId
INNER JOIN Users ON Users.UserId = @UserId
AND ((Companies.CompanyId = Users.CompanyId) OR (Companies.ParentCompanyId = Users.CompanyId))
好的,这确保用户只能看到与用户关联的公司和子公司的数据:David 只能看到 DEF Co 的发票,而 Alyssa 可以看到 ABC Inc、DEF 的所有发票Co 和 GHI Ltd.
现在,如果 Alyssa 只想见 DEF Co,她需要能够选择该公司。根据此查询创建@CompanyId 参数:
SELECT Companies.CompanyId, Companies.Name
FROM Companies
INNER JOIN Users ON Users.UserId = @UserId
AND ((Companies.CompanyId = Users.CompanyId) OR (Companies.ParentCompanyId = Users.CompanyId))
这显示了用户可以选择的所有公司。设置参数的默认值以从查询中获取其值:
SELECT CompanyId FROM Users WHERE UserId = @UserId
然后我们只需将这个参数添加到我们的查询中:
SELECT Invoices.CompanyId, Invoices.Number, Invoices.Date, Invoices.Amount
FROM Invoices
INNER JOIN Companies ON Invoices.CompanyId = Companies.CompanyId
INNER JOIN Users ON Users.UserId = @UserId
AND ((Users.CompanyId = Companies.CompanyId) OR (Users.CompanyId = Companies.ParentCompanyId))
AND ((@CompanyId = Companies.CompanyId) OR (@CompanyId = Companies.ParentCompanyId))
报告订阅
现在我们开始通过订阅交付报告,而我们围绕使用 @UserId 的策略失败了,因为报告调度程序在其自己的帐户下运行报告,而不是我们想要定位的用户。
让我们创建一个名为User 的隐藏参数并将其设为第一个参数。对于它的可用值属性,创建如下查询:
SELECT UserId, Name
FROM Users
WHERE UserId = @UserId OR @UserId = 'MyDomain\ReportingAccount'
其中MyDomain\ReportingAccount 是您的报告所用的帐户。此查询在实际用户运行报表时仅允许特定用户详细信息,但在报表调度程序运行时允许所有用户。
将User 参数的默认值属性设为=User!UserId。当您的报告计划程序运行报告时,对于 User 参数,请提供您要为您发送电子邮件的人的 UserId。
因此,当用户运行报告时,它会选择唯一可能的用户(即他们自己),而当调度程序运行报告时,它会从所有可用用户中选择您想要的用户。作为一个隐藏参数,用户永远不会看到它,所以不知道其中的区别。
如果用户试图变聪明并通过将其作为 URL 中的参数传递来欺骗另一个用户,则它不会是参数可用值的有效选择,因此会失败。
现在只需将上面用于公司选择的查询中的 @UserId 替换为 @User 即可,一切正常。