我需要从第三方系统中提取数据(我对其设计没有任何影响)。它是一个SQL Server 2005数据库使用位图来存储用户权限。它有五个INT字段,最多可提供5 * 32 = 160个权限。它存储许多类型的权限,并重新使用每种类型的位图。总共有6个字段可以驱动特权。可以将每个权限分配给给定类型的特定项目。
类型的一个例子是“table”,因此该上下文中的项目将是表名。
特权表如下所示:
ID | PRIVTYPE | USERNAME | ITEMNAME | BITMAP1 | BITMAP2 | BITMAP3 | BITMAP4 | BITMAP5
例如
123 | Table | Joe | Customers | 0x408 | 0x1 | 0x5c | 0x1000 | 0x0
另一个表包含每个位表示的权限。它看起来像这样:
PRIVTYPE | BITMAP_ID | BITVALUE | PRIVILEGE_NAME
例如,与上述位图相关的条目为:
Table | 1 |0x8 | View
Table | 1 |0x400 | Edit
Table | 2 |0x1 | Report
Table | 3 |0x4 | View Address Data
Table | 3 |0x8 | View Order Data
Table | 3 |0x10 | View Payment Data
Table | 3 |0x40 | View System Data
Table | 4 |0x1000| View Hidden Fields
我想以某种方式将权限表解析为一个新的表或视图,每个用户的每个项目权限都有一条记录。像这样:
USERNAME | ITEMNAME |PRIVILEGE_NAME
Joe | Table | Customers | View
Joe | Table | Customers | Edit
Joe | Table | Customers | Report
Joe | Table | Customers | view Address Data
Joe | Table | Customers | view Order Data
Joe | Table | Customers | view Payment Data
Joe | Table | Customers | view System Data
Joe | Table | Customers | view Hidden Fields
我认为我需要通过运行select语句来创建视图,该语句将为权限表中的每一行返回多行:位掩码字段中的每个设置位都有一行。因此,例如,权限表中的一行在位掩码中设置了3位将导致返回三行。
我搜索了将表分成多行的答案。我看过各种连接和枢轴,但我找不到能满足我需要的东西。以上可能吗?任何指导赞赏...
答案 0 :(得分:1)
您可以取消第一个表(下面称为@UserPrivileges
)并将其连接到第二个表(@Privileges
)上的特权类型,位图ID以及第一个位图之间的按位AND结果表格和BITVALUE
在第二个表格中。
以下是我的实施。
设定:
DECLARE @UserPrivileges TABLE (
ID int,
PRIVTYPE varchar(50),
USERNAME varchar(50),
ITEMNAME varchar(50),
BITMAP1 int,
BITMAP2 int,
BITMAP3 int,
BITMAP4 int,
BITMAP5 int
);
INSERT INTO @UserPrivileges
(ID, PRIVTYPE, USERNAME, ITEMNAME, BITMAP1, BITMAP2, BITMAP3, BITMAP4, BITMAP5)
SELECT 123, 'Table', 'Joe', 'Customers', 0x408, 0x1, 0x5c, 0x1000, 0x0
;
DECLARE @Privileges TABLE (
PRIVTYPE varchar(50),
BITMAP_ID int,
BITVALUE int,
PRIVILEGE_NAME varchar(50)
);
INSERT INTO @Privileges (PRIVTYPE, BITMAP_ID, BITVALUE, PRIVILEGE_NAME)
SELECT 'Table', 1, 0x8 , 'View ' UNION ALL
SELECT 'Table', 1, 0x400 , 'Edit ' UNION ALL
SELECT 'Table', 2, 0x1 , 'Report ' UNION ALL
SELECT 'Table', 3, 0x4 , 'View Address Data ' UNION ALL
SELECT 'Table', 3, 0x8 , 'View Order Data ' UNION ALL
SELECT 'Table', 3, 0x10 , 'View Payment Data ' UNION ALL
SELECT 'Table', 3, 0x40 , 'View System Data ' UNION ALL
SELECT 'Table', 4, 0x1000, 'View Hidden Fields'
;
查询:
WITH unpivoted AS (
SELECT
ID,
PRIVTYPE,
USERNAME,
ITEMNAME,
RIGHT(BITMAP_ID, 1) AS BITMAP_ID, -- OR: STUFF(BITMAP_ID, 1, 6, '')
-- OR: SUBSTRING(BITMAP_ID, 7, 999)
-- OR: REPLACE(BITMAP_ID, 'BITMAP', '')
BITMAP_VAL
FROM UserPrivileges
UNPIVOT (
BITMAP_VAL FOR BITMAP_ID IN (
BITMAP1, BITMAP2, BITMAP3, BITMAP4, BITMAP5
)
) u
),
joined AS (
SELECT
u.USERNAME,
u.PRIVTYPE,
u.ITEMNAME,
p.PRIVILEGE_NAME
FROM unpivoted u
INNER JOIN Privileges p
ON u.PRIVTYPE = p.PRIVTYPE
AND u.BITMAP_ID = p.BITMAP_ID
AND u.BITMAP_VAL & p.BITVALUE <> 0
)
SELECT * FROM joined
结果:
USERNAME PRIVTYPE ITEMNAME PRIVILEGE_NAME -------- -------- --------- ------------------ Joe Table Customers View Joe Table Customers Edit Joe Table Customers Report Joe Table Customers View Address Data Joe Table Customers View Order Data Joe Table Customers View Payment Data Joe Table Customers View System Data Joe Table Customers View Hidden Fields
答案 1 :(得分:0)
如果这是一个OFF OFF任务或者只能运行RARELY的东西,那么CURSORS!
否则,只需在插入中执行6个不同的select语句:
INSERT INTO FOO (myName, myValue)
SELECT myName, myCol1
From BAR
UNION
SELECT myName, myCol2
FROM BAR
UNION
SELECT myName, myCol3
FROM BAR