Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-27 : 13:54:51
|
| Hello Guys,I'm looking for some help writing what I guess is likely to end up being a bit of a complex query. I've put a little thought into the design aspect of this and think I've come up with the best solution to the problem, but if you have any other ideas then I'd love to hear them.This is for the user authentication system on my latest web application which will be 'role' based and quite granular so it offers a fair amount of controll over whats entitlements my users have in the application. My database layout looks somthing like this, I've cut out any of the irrelevant columns to keep it simple for you.User----User_ID - Int [Primary Key]Entitlement-----------Entitlement_ID - Int [Primary Key]EntitlementName - VarcharEntitlementGroup----------------EntitlementGroup_ID - Int [Primary Key]EntitlementGroupEntitlement---------------------------EntitlementGroupEntitlement_ID - Int [Primary Key]EntitlementGroup_ID - IntEntitlement_ID - IntUserEntitlement---------------UserEntitlement_ID - Int [Primary Key]User_ID - IntEntitlement_ID - IntPermitRevoke - TinyIntUserEntitlementGroup--------------------UserEntitlementGroup - Int [Primary Key]User_ID - IntEntitlementGroup_ID - IntNow, the idea behind this is that my application has a whole host of different 'entitlements' such as 'create account' and 'edit profile' and so on, and so forth. To make it easy to apply these entitlements to a user, I've created the entitlements groups, which are essentialy 'roles' such as 'admin'. Each group can have many entitlements and each entitlement can belong to several groups.Each user can then have several groups assigned to them, and each group can be assigned to several users. In addition to assigning a group to a user, I've added an additional level which can be used to 'permit' or 'revoke' additional entitlements to thier standard roles, so i could then give a user the 'admin' role, but remove the entitlement to delete a contact or somthing like that. This extra layer is controlled by the UserEntitlement table, you'll see the tinyint switch for each additional permission, dependant on whether its been permitted or revoked.Now the query I'm looking to build will return ALL entitlements from the entitlements table, and then list a 1 or a 0 dependant on whether the user has that entitlement or not.To do this the first thing the query has to do is set all the entitlements to 1 which are contained within the 'groups' assigned to the user, and assume that all other permissions are not granted, then go through the 'UserEntitlement' table and make changes to any settings found in it.I know this is very complicated, so let me try and explain it using an example.Entitlements------------1 - Add Contact2 - Edit Contact3 - Move Contact4 - Delete ContactEntitlements Group------------------1 - AdminEntitlementsGroupEntitlements-----------------------------1 - 11 - 21 - 31 - 4So far we now have a group called 'admin' which has all the entitlements assigned to it.UserEntitlementGroup--------------------1 - 1Now, user 1 has the admin group assigned to them, and as a result user 1 now has all the entitlements.UserEntitlements----------------1 - 4 - 0Now, I've taken the user and the entitlement to 'delete contact' and set it to 0, which means the user does not have that entitlement any more.So the returned results will look like this.User 1------Add Contact - 1Edit Contact - 1Move Contact - 1Deletecontact - 0I know thats taken alot of explaining so I'm sure you'll have quite a few questions, feel free to let me know and I'll answer them as best I can, I'm really struggling to picture how this query is going to come together, I would guess we start by selecting all the entitlements from the table and then doing a LEFT OUTER with the others, this will ensure that all the entitlements are returned, its just a case of the rest of it now :-DThanks guys for any help you can offer.Many Thanks,Rob |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-05-28 : 04:10:50
|
| something similar toselect e.*from entitlementsleft join (select * from UserEntitlementGroup as eg inner join EntitlementsGroup as f on f.col1 = eg.col1 inner join ...) as oon o.entitlementid = e.entitlementidPeter LarssonHelsingborg, Sweden |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 11:14:03
|
Thanks for getting back to me Peter,Unfortunatly my SQL skills are not so great so trying to place together the rest of that query is proving difficult. Someone else on another board has suggested this methodselect Rights Name, isnull(entitlement id field of UserEntitleMentTableId,entitlement id field of normal join) Rightsfrom.......... But again, this is a little over my head, using lots of joins and things. Are you able to eleborate on your example a little more for me?Many thanks,Rob |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2007-05-28 : 11:19:08
|
| first of all: what kind of database engine are you using?Oracle, MS Sql server, mySql???This is a site only for MS Sql Server, so if you're using another db engine we can't really halp you much._______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenp |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 11:32:41
|
| Hey Spirit,I should have mentioned this earlier, I'm running SQL Server 2005 Standard, so this should be right up your street.Thanks,Rob |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2007-05-28 : 11:39:00
|
cool.well as far as i know this is invalid syntax for sql server:select Rights Name, isnull(entitlement id field of UserEntitleMentTableId,entitlement id field of normal join) Rightsfromwell first of all read up on joins joins are performed between 2 sets on a common key.inner join returns only data that appear in both columns.what Peso did is called a subquery. read about that too.It's basically a select statement returning a set that he joined to your table._______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenp |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 11:55:15
|
| Thanks for getting back to me Spirit,I have a pretty fair grasp of JOIN's and Subqueries, but what I'm struggling to do here is have the query return the dataset that I want. See, the bit referance that I want in the second column of my query results doesnt realy exist, we'll have to fabricate it out of my data. Let me give another quick example of my data.Entitlement-----------1 - Add User2 - Delete UserThis is my entitlement table, I have two columns, one of which is the ID for the entitlement, the other is a freindly name for the entitlement, its this name that I want returned in the left column of my query, I also want ALL the entitlements returned in my query, regardless of what is in the other tables.EntitlementGroupEntitlement---------------------------1 - 11 - 2What this does is add both entitlement into a group (ID 1), this group is then likely to be assigned to a user in the table below like this.UserEntitlementGroup--------------------1 - 1User 1 now has group 1 assigned to them, so with a basic JOIN we could return all the entitlements assigned to user one, but we need a little more information than that, and this is where i get totaly lost.I have another table, that lets me overright the standard entitlements assigned in that group table, I use the bit column to define if the entitlment is granted additionaly, or if it should be revoke additionaly.UserEntitlement---------------1 - 1 - FalseNow in my final results I want to return all the entitlements, and then set a true/false value, all of those entitlements found belonging to a group assigned to a user should be set to True, as should any additional ones granted in the UserEntitlement table, and all those NOT found in the groups assigned to the user should be set to False, as should those revoked in the UserEntitlement table, so my final query results for this example would look like.User_ID EntitlementName Entitled1 1 False1 2 TrueIts difficult for me to explain, I hope i'm doing an ok job.Thanks for any further help on this.Rob |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2007-05-28 : 12:02:25
|
| please follow instructions in this link:http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxthis is the best way to get help fast.because from reading it i didn't quite understand your requirement._______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenp |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 12:24:57
|
| Thanks Spirit,Whats the simplest way to generate those DDL and DML scripts?Thanks,Rob |
 |
|
|
spirit1
Cybernetic Yak Master
11752 Posts |
Posted - 2007-05-28 : 12:33:46
|
| well... you cna script objects in SSMS.insert statemens:http://vyaskn.tripod.com/code.htm#inserts_______________________________________________Causing trouble since 1980blog: http://weblogs.sqlteam.com/mladenp |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 12:35:50
|
| Members TableGO/****** Object: Table [dbo].[Member] Script Date: 05/28/2007 17:32:56 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[Member]( [Member_ID] [int] IDENTITY(1,1) NOT NULL, [CreatedDate] [datetime] NOT NULL, [ModifiedDate] [datetime] NOT NULL, [Active] [tinyint] NOT NULL, [Locked] [tinyint] NOT NULL, CONSTRAINT [PK_Member] PRIMARY KEY CLUSTERED ( [Member_ID] ASC)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]) ON [PRIMARY]Entitlement TableGO/****** Object: Table [dbo].[Entitlement] Script Date: 05/28/2007 17:33:25 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[Entitlement]( [Entitlement_ID] [int] IDENTITY(1,1) NOT NULL, [Name] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, CONSTRAINT [PK_Entitlement] PRIMARY KEY CLUSTERED ( [Entitlement_ID] ASC)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]) ON [PRIMARY]GOSET ANSI_PADDING OFFUserEntitlement TableGO/****** Object: Table [dbo].[UserEntitlement] Script Date: 05/28/2007 17:33:50 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[UserEntitlement]( [User_ID] [int] NOT NULL, [Entitlement_ID] [int] NOT NULL, [AllowRevoke] [bit] NOT NULL) ON [PRIMARY]GOUSE [YourBlue]GOALTER TABLE [dbo].[UserEntitlement] WITH CHECK ADD CONSTRAINT [FK_UserEntitlement_Entitlement] FOREIGN KEY([Entitlement_ID])REFERENCES [dbo].[Entitlement] ([Entitlement_ID])GOALTER TABLE [dbo].[UserEntitlement] WITH CHECK ADD CONSTRAINT [FK_UserEntitlement_Member] FOREIGN KEY([User_ID])REFERENCES [dbo].[Member] ([Member_ID])Entitlement GroupGO/****** Object: Table [dbo].[EntitlementGroup] Script Date: 05/28/2007 17:34:15 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[EntitlementGroup]( [EntitlementGroup_ID] [int] IDENTITY(1,1) NOT NULL, [GroupName] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, CONSTRAINT [PK_EntitlementGroup] PRIMARY KEY CLUSTERED ( [EntitlementGroup_ID] ASC)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]) ON [PRIMARY]GOSET ANSI_PADDING OFFEntitlementGroupEntitlement TableGO/****** Object: Table [dbo].[EntitlementGroupEntitlement] Script Date: 05/28/2007 17:34:39 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[EntitlementGroupEntitlement]( [Entitlement_ID] [int] NOT NULL, [EntitlementGroup_ID] [int] NOT NULL) ON [PRIMARY]GOUSE [YourBlue]GOALTER TABLE [dbo].[EntitlementGroupEntitlement] WITH CHECK ADD CONSTRAINT [FK_EntitlementGroupEntitlement_Entitlement] FOREIGN KEY([Entitlement_ID])REFERENCES [dbo].[Entitlement] ([Entitlement_ID])GOALTER TABLE [dbo].[EntitlementGroupEntitlement] WITH CHECK ADD CONSTRAINT [FK_EntitlementGroupEntitlement_EntitlementGroup] FOREIGN KEY([EntitlementGroup_ID])REFERENCES [dbo].[EntitlementGroup] ([EntitlementGroup_ID])UserEntitlementGroup TableGO/****** Object: Table [dbo].[UserEntitlementGroup] Script Date: 05/28/2007 17:35:00 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[UserEntitlementGroup]( [User_ID] [int] NULL, [EntitlementGroup_ID] [int] NULL) ON [PRIMARY]GOUSE [YourBlue]GOALTER TABLE [dbo].[UserEntitlementGroup] WITH CHECK ADD CONSTRAINT [FK_UserEntitlementGroup_Member] FOREIGN KEY([User_ID])REFERENCES [dbo].[Member] ([Member_ID])That should get you going with some empty tables I hope, sorry if thats not quite right, fingers crossed it'll help.Rob |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 12:50:44
|
| Create MemberINSERT INTO [YourDB].[dbo].[Member] ([CreatedDate] ,[ModifiedDate] ,[Active] ,[Locked]) VALUES ('2007-01-01', '2007-01-01', 1, 0)Create EntitlementsINSERT INTO [YourDB].[dbo].[Entitlement] ([Name]) VALUES ('Add User')INSERT INTO [YourDB].[dbo].[Entitlement] ([Name]) VALUES ('Edit User')INSERT INTO [YourDB].[dbo].[Entitlement] ([Name]) VALUES ('Delete User')Set The Revoke for Entitlement 3INSERT INTO [YourBlue].[dbo].[UserEntitlement] ([User_ID] ,[Entitlement_ID] ,[AllowRevoke]) VALUES (1 ,3 ,False)Create a Group Called AdminINSERT INTO [YourBlue].[dbo].[EntitlementGroup] ([GroupName]) VALUES ('Admin')Assign all entitlements to admin groupINSERT INTO [YourBlue].[dbo].[EntitlementGroupEntitlement] ([Entitlement_ID] ,[EntitlementGroup_ID]) VALUES (1 ,1)INSERT INTO [YourBlue].[dbo].[EntitlementGroupEntitlement] ([Entitlement_ID] ,[EntitlementGroup_ID]) VALUES (3 ,1)INSERT INTO [YourBlue].[dbo].[EntitlementGroupEntitlement] ([Entitlement_ID] ,[EntitlementGroup_ID]) VALUES (2 ,1)Assign user the admin groupINSERT INTO [YourBlue].[dbo].[UserEntitlementGroup] ([User_ID] ,[EntitlementGroup_ID]) VALUES (1 ,1) |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 12:54:57
|
| Finally, results would look like this.Member.Member_ID ------------- Entitlement.EntitlementName ------- Entitled1 ----------- 1 ------------- True1 ----------- 2 ------------- True1 ----------- 3 ------------- FalseThis gets ALL the entitlements from the entitlement table, and then sets the entitled colummn to True if the entitlement is assigned to the user indevidualy in the 'UserEntitlement' table or belongs to the group assigned to the user.And sets it to False if it is revoked indevidualy in the UserEntitlement table or is not in the groups assigned to the user.Thanks again mate,Rob |
 |
|
|
SirRawlins
Starting Member
14 Posts |
Posted - 2007-05-28 : 12:55:49
|
| Sorry,1 ----------- Add User ------------- True1 ----------- Edit User ------------- True1 ----------- Delete User ------------- False |
 |
|
|
|
|
|
|
|