sql视图与其他表一致
给定表sql视图与其他表一致,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,给定表客户,示例: CustomerID FirstName MiddleInitial LastName 64 Abby A Garcia 65 Abby C Mehta 66 Abby E Chandra 67 Abby J Kapoor 68
客户
,示例:
CustomerID FirstName MiddleInitial LastName
64 Abby A Garcia
65 Abby C Mehta
66 Abby E Chandra
67 Abby J Kapoor
68 Abby J Sanchez
69 Abby K Kovár
70 Abby L Sai
71 Abby M Lopez
72 Abby P Gonzalez
73 Abby P Rana
我想根据另一个表中的定义限制对(表、列、行)的访问,比如说m_Customers
,定义如下:
MetadataID Field Type Access
1 Customers table "Group1","Group2","Group3"
2 MiddleInitial column "Group1","Group3"
3 18 row "Group1","Group3"
基于此,您如何制定一个查询,以确保您:
- 在*Group3“中,您无法看到
列和MiddleInitials
CustomerId=18的行
- 在“Group4”中,您无法看到Customers表中的数据
有什么想法吗?您的排除和包含似乎是混合的。第3组包含在列客户和第18行中,但第4组不包含在表客户中。请使您的m_客户表仅包含有访问权限的客户或受限制的客户,而不是两者都包含 为m_客户更改数据结构以使用每个组的记录通常会更快、更容易
MetadataID Field Type Access
1 Customers table Group1
2 Customers table Group2
3 Customers table Group3
4 MiddleInitial column Group1
5 MiddleInitial column Group3
6 18 row Group1
7 18 row Group3
这里有两个选项;您可以检查性能
SELECT MAX(col.customerID) AS customerID, MAX(col.FirstName) AS FirstName, MAX(col.MiddleInitial) AS MiddleIntitial, MAX(col.LastName) AS LastName
FROM Customers AS c
INNER JOIN m_Customers AS mRow ON mRow.[Type] = 'row' AND mRow.CustomerID = c.Field AND mRow.Access = @group
LEFT JOIN (
SELECT
IIF(mCol.Field = 'customerID', c.customerID, NULL) AS customerID,
IIF(mCol.Field = 'Firstname', c.FirstName, NULL) AS FirstName,
IIF(mCol.Field = 'MiddleInitial', c.FirMiddleInitialstName, NULL) AS MiddleInitial,
IIF(mCol.Field = 'LastName', c.LastName, NULL) AS LastName
FROM Customers AS c
INNER JOIN m_Customers AS mCol ON mCol.[Type] = 'column' AND mCol.Field = 'MiddleInitial' AND mCol.Access = @group
) AS col ON col.customerID = c.CustomerID
GROUP BY col.customerID, col.FirstName, col.MiddleInitial, col.LastName
或
考虑将列的名称从类型更改为非保留字。什么是组,DBMS知道它们的角色吗?如果知道,我宁愿为每个角色编写一个视图,授予角色对该视图的访问权,并取消对表的访问权。如果不知道,您可以编写一个传递组的表函数,该函数使用动态SQL。但是r逻辑对我来说似乎有点奇怪:为什么规则表中的第一条规则是“grant”规则,而其他规则是“deny”规则?您没有存储
“Group1”、“Group2”、“Group3”“
作为一个字符串,是吗?链接表中肯定有三行?@matbaile string,我想使用模式匹配不,只是不。在关系数据库中,列表不能作为字符串存储。您也可以不使用关系数据库。如果视图中存在大量的,
,则可以实现这一点,但不能修改要选择的列数(如果存在限制,可以强制返回空值)。最好的方法是使用动态SQL,它只能在SP内部。这似乎与您的两个示例相矛盾,如果您的表中包含您看不到的内容,那么Group4应该可以看到所有内容。
SELECT customerID.customerID, FirstName.FirstName, MiddleInitial.MiddleInitial, LastName.LastName
FROM Customers AS c
INNER JOIN m_Customers AS mRow ON mRow.[Type] = 'row' AND mRow.CustomerID = c.Field AND mRow.Access = @group
LEFT JOIN (
SELECT c.customerID
FROM Customers AS c
INNER JOIN m_Customers AS mCol ON mCol.[Type] = 'column' AND mCol.Field = 'customerID' AND mCol.Access = @group
) AS customerID ON customerID.customerID = c.customerID
LEFT JOIN (
SELECT c.customerID, c.FirstName
FROM Customers AS c
INNER JOIN m_Customers AS mCol ON mCol.[Type] = 'column' AND mCol.Field = 'FirstName' AND mCol.Access = @group
) AS FirstName ON FirstName.customerID = c.customerID
LEFT JOIN (
SELECT c.customerID, c.MiddleInitial
FROM Customers AS c
INNER JOIN m_Customers AS mCol ON mCol.[Type] = 'column' AND mCol.Field = 'MiddleInitial' AND mCol.Access = @group
) AS MiddleInitial ON MiddleInitial.customerID = c.customerID
LEFT JOIN (
SELECT c.customerID, c.LastName
FROM Customers AS c
INNER JOIN m_Customers AS mCol ON mCol.[Type] = 'column' AND mCol.Field = 'LastName' AND mCol.Access = @group
) AS LastName ON LastName.customerID = c.customerID