0

我想将“锁定”或“可编辑”的所有列名放入每个字段名的“可见者”字段中。有数百列,所以我正在寻找一种自动化的方式来做到这一点。

例如:

Field Name                   visible by   Business Development   VC Panel          Admin
Certification_Complete__c                   Hidden                 Lock             Editable
Certification_Status__c                     Hidden                 Hidden           Editable    

至:

Field Name                  visible by     Business Development    VC Panel        Admin
Certification_Complete__c  **VC Panel,Admin**   Hidden             Lock            Editable
Certification_Status__c     **Admin**           Hidden             Hidden          Editable

非常感谢

4

1 回答 1

3

您的表结构是获得此结果的问题的一部分。理想情况下,您应该考虑将表重组为更规范的结构。

您可以将结构更改为类似于以下内容:

CREATE TABLE certs
(
  [cert_id] int, 
  [FieldName] varchar(25)
);

INSERT INTO certs ([cert_id], [FieldName])
VALUES (1, 'Certification_Complete__c'),
    (2, 'Certification_Status__c');

CREATE TABLE permissions
(
  [permission_id] int, 
  [permissionName] varchar(20)
);

INSERT INTO permissions ([permission_id], [permissionName])
VALUES (1, 'Business Development'),
    (2, 'VC Panel'),
    (3, 'Admin');

CREATE TABLE certs_permissions
(
  [cert_id] int, 
  [permission_id] int, 
  [permission_type] varchar(8)
);

INSERT INTO certs_permissions ([cert_id], [permission_id], [permission_type])
VALUES
    (1, 1, 'Hidden'),
    (1, 2, 'Lock'),
    (1, 3, 'Editable'),
    (2, 1, 'Hidden'),
    (2, 2, 'Hidden'),
    (2, 3, 'Editable');

然后,您可以通过连接表并使用 PIVOT 函数将行转换为列来获得结果。代码将与此类似:

;with cte as
(
  select c.cert_id, c.fieldname, p.permissionName, 
    cp.permission_type
  from certs c
  inner join certs_permissions cp
    on c.cert_id = cp.cert_id
  inner join permissions p
    on cp.permission_id = p.permission_id
) 
select fieldname,
  visibleby, 
  [Business Development], 
  [VC Panel],
  [Admin]
from
(
  select c1.fieldname,
    STUFF(
         (SELECT ', ' + cast(t.permissionName as varchar(50))
          FROM cte t
          where c1.fieldname = t.fieldname
            and t.permission_type in ('Lock', 'Editable')
          FOR XML PATH (''))
          , 1, 1, '')  AS [visibleby],
    c1.permissionname,
    c1.permission_type
  from cte c1
) d
pivot
(
  max(permission_type)
  for permissionname in ([Business Development], [VC Panel],
                          [Admin])
) piv

请参阅SQL Fiddle with Demo。这给出了一个结果:

|                 FIELDNAME |        VISIBLEBY | BUSINESS DEVELOPMENT | VC PANEL |    ADMIN |
---------------------------------------------------------------------------------------------
|   Certification_Status__c |            Admin |               Hidden |   Hidden | Editable |
| Certification_Complete__c |  VC Panel, Admin |               Hidden |     Lock | Editable |

如果您不想对所有列值进行硬编码,则可以更改上面的脚本以轻松实现动态 SQL 以生成要执行的查询字符串。

如果您无法修复数据库结构,那么我建议您分两步进行。使用动态 SQL 规范化您当前的数据库结构,以便您可以轻松获取逗号分隔的visible_by值列表。当您使用 UNPIVOT 函数时,您可以将数据扔到一个临时表中,该表可用于获取逗号分隔的列表。代码将与此类似:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @colsUnpivot = STUFF((SELECT distinct ','+ quotename(c.column_name)
                   from INFORMATION_SCHEMA.COLUMNS as C
                   where (TABLE_NAME = 'yt') and
                      c.column_name not in ('Field Name', 'visible by')
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select [Field Name], [visible by], colList, value
     into temp
     from yt
     unpivot
     (
       value
       for colList in ('+ @colsunpivot +')
     ) u'

exec(@query);

select distinct 
  t.[field name], 
  STUFF(
         (SELECT ', ' + cast(t2.colList as varchar(50))
          FROM temp t2
          where t.[Field Name] = t2.[Field Name]
            and t2.value in ('Lock', 'Editable')
          FOR XML PATH (''))
          , 1, 1, '')  AS [visible by],
  t.[Business Development],
  t.[VC Panel], 
  t.[Admin]
from yt t;

drop table temp;

请参阅带有演示的 SQL Fiddle

于 2013-06-05T19:18:38.240 回答