Сделайте представление SQL, показывающее данные из 3 таблиц, таких как кросс-таблица - PullRequest
0 голосов
/ 18 ноября 2010

Я использую систему членства ASP.net с базой данных SQL Server 2000. Что я хочу сделать, это создать представление (или хранимую процедуру, если это лучше), которая будет возвращать таблицу со следующими столбцами:

UserName  |  Role1  |  Role2  |  Role3  |  ....  | Role*N*

Где создаются столбцы (кроме имени пользователя) для включения всех ролей ASP.net в приложении.

Мне нужно, чтобы это было универсальным (то есть, когда я добавляю новую Роль, я хочу, чтобы процедура / представление компенсировали и перечисляли эту новую Роль как новый столбец). Я хочу, чтобы значения в полях Role были равны 1 (True) или 0 (false), если пользователь в этой роли. Я могу создать таблицу, в которой есть такие столбцы, используя динамический SQL для создания переменного числа столбцов, но я не могу их заполнить.

Как мне это сделать?

Таблицы приведены ниже:

CREATE TABLE [dbo].[aspnet_Users](
    [ApplicationId] [uniqueidentifier] NOT NULL,
    [UserId] [uniqueidentifier] NOT NULL,
    [UserName] [nvarchar](256) NOT NULL,
    [LoweredUserName] [nvarchar](256) NOT NULL,
    [MobileAlias] [nvarchar](16) NULL,
    [IsAnonymous] [bit] NOT NULL,
    [LastActivityDate] [datetime] NOT NULL,
PRIMARY KEY NONCLUSTERED 
(
    [UserId] ASC
) ON [PRIMARY]
) ON [PRIMARY]



CREATE TABLE [dbo].[aspnet_Roles](
    [ApplicationId] [uniqueidentifier] NOT NULL,
    [RoleId] [uniqueidentifier] NOT NULL,
    [RoleName] [nvarchar](256) NOT NULL,
    [LoweredRoleName] [nvarchar](256) NOT NULL,
    [Description] [nvarchar](256) NULL,
PRIMARY KEY NONCLUSTERED 
(
    [RoleId] ASC
) ON [PRIMARY]
) ON [PRIMARY]



CREATE TABLE [dbo].[aspnet_UsersInRoles](
    [UserId] [uniqueidentifier] NOT NULL,
    [RoleId] [uniqueidentifier] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [UserId] ASC,
    [RoleId] ASC
) ON [PRIMARY]
) ON [PRIMARY]

1 Ответ

0 голосов
/ 22 ноября 2010

Представления не могут динамически добавлять столбцы на основе данных в них.Ни один не может прямые запросы.Поскольку вы хотите, чтобы оно автоматически изменялось в зависимости от данных в таблице, это полностью исключает представления и запросы с использованием таких конструкций, как pivot.

В значительной степени ваш единственный выбор, учитывая ограничения, которые вы нам дали,создать временную таблицу с достаточным количеством столбцов (динамически) и заполнить ее.Это по-прежнему проблематично, так как sproc не может создать и вернуть временную таблицу, поскольку таблица будет отброшена при выходе из sproc.

Другой вариант - написать sproc, который динамически генерирует запрос pivot и выполняеттот.Это будет довольно грязно, хотя.Новые роли добавляются так часто, что это абсолютное требование?Это единственное, что делает его таким трудным.

Статический сводный запрос, чтобы получить желаемый результат, может выглядеть примерно так:

select
  UserName,
  [1] as Role1, [2] as Role2, [3] as Role3 -- UpdateMe
from (
  select
    u.UserName,
    r.RoleID
    IsUserInRole(u.UserName, r.RoleName) RoleFlag
  from
    aspnet_users u
    cross join aspnet_roles r) source
  pivot (
    RoleFlag for RoleID in 
      ([1],[2],[3]) -- UpdateMe
  ) PivotTable

Есть две строки, которые ваш динамический SQLгенератор должен постоянно обновляться, они помечены UpdateMe комментариями.

У меня не установлен MSSQL, поэтому я не могу протестировать этот запрос, но он должен быть довольно близко.Может быть полезна ссылка pivot.

Поддельные сводки в SQL Server 2000 с использованием агрегатов и case:

select
  UserName,
  max(case when src.RoleID = 1 then RoleFlag else 0 end) Role1,  --Repeat N times
  ...
from (
  select
    u.UserName,
    r.RoleID
    IsUserInRole(u.UserName, r.RoleName) RoleFlag
  from
    aspnet_users u
    cross join aspnet_roles r) src
group by
  UserName
...