2010-11-18 8 views
0

SQL Server 2000データベースでASP.netメンバシップシステムを使用しています。私は何をしたい(それがより良いかどうか、ストアドプロシージャ)次の列を持つテーブルを返しますどのビューを作成することです:クロス集計のような3つのテーブルからのデータの表示をSQLビューに表示

(ユーザ名以外の)列がすべてASP.netを含むように生成され
UserName | Role1 | Role2 | Role3 | .... | Role*N* 

アプリケーション内のロール。

これは一般的なものである必要があります(つまり、新しい役割を追加するときは、手順/ビューでその新しい役割を補うことができます)。そのロール内のユーザーがいる場合は、ロールフィールドの値を1(真)または0(偽)にします。私は、動的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

これは、タイプのクエリ「列に行」一般的なように思える:凝集物およびcaseを使用してSQL Server 2000でピボットを偽造

。あなたは、メンバーシップをあまり重視せずに質問を再検討し、関連するテーブル定義を投稿することができます。多くのSQLに精通したユーザーの中には、その質問に答えることができます。 – Greg

+0

おそらくあなたの権利。私は定義を追加しました。 – MAW74656

答えて

0

ビューを動的にその中のデータに基づいて列を追加することはできません。どちらもストレートクエリではありません。テーブル内のデータに基づいて自動的に変更したいので、pivotのような構文を使用してビューとクエリを完全に除外します。

あなたが私たちに与えた制約を考えると、十分な列を持つ一時テーブルを生成して(動的に)それを設定するだけです。これは、sprocが終了したときにテーブルが削除されるため、sprocが一時テーブルを作成して返すことができないため、依然として問題があります。

もう1つの方法は、pivotというクエリを動的に生成して実行するsprocを作成することです。これはかなり面倒です。新しい役割が頻繁に追加されるため、これは絶対条件ですか?それはそれを難し​​くしている唯一のものです。

あなたが望む出力を与えるために、静的なピボットクエリは次のようになります。

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ジェネレータは更新を維持しなければならない2行がありますが、それらはUpdateMeコメントが付いています。

ここにMSSQLがインストールされていないため、このクエリはテストできませんが、かなり近いはずです。 pivotの参考情報が参考になる場合があります。

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 
+0

私は新しい役割を持つことを主張します。しかし、すべてのビューで一時テーブルを作ることは難しい部分ではない、私はすでに働いている。私たちは細胞を移植するだけです。この必要がなければ、プロシージャコールをハードコーディングするだけの問題であることを理解しています。私はそれをハードコードしたくない。 – MAW74656

+0

また、動的テーブル内のグローバルtempテーブルとして単純に宣言できるので、一時テーブル上のポイントが完全に正しいとは限りません。 – MAW74656

+0

グローバルな一時テーブルは、このようなアプリケーションで並行性の問題を引き起こします。注意してください。あなた自身の選択は、動的にクエリを生成して一時テーブルを生成し、 'exec'または' sp_executesql'で実行することになります。それは書くのが難しいはずがありませんが、それは乱雑で非常に手順的です。 – Donnie

関連する問題