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 |
|
RoLYroLLs
Constraint Violating Yak Guru
255 Posts |
Posted - 2005-05-18 : 18:41:27
|
Hello gals and guys.I'm trying to create an administrative controlled menu based of user and group/role permissions. For example: User1 is in user group/role Role1. I have a table with users named User, another named Menu with a list of all the possible menu items and another named UserType listed all the user group/roles. Between them I have a table linking them together UserMenu and UserTypes, since one user can have multiple roles and of course any user can have more than one menu item. Here's some code to build the tables:if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FK_UserMenu_Menu]') and OBJECTPROPERTY(id, N'IsForeignKey') = 1)ALTER TABLE [dbo].[UserMenu] DROP CONSTRAINT FK_UserMenu_MenuGOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FK_UserTypes_User]') and OBJECTPROPERTY(id, N'IsForeignKey') = 1)ALTER TABLE [dbo].[UserTypes] DROP CONSTRAINT FK_UserTypes_UserGOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FK_UserMenu_UserPageType]') and OBJECTPROPERTY(id, N'IsForeignKey') = 1)ALTER TABLE [dbo].[UserMenu] DROP CONSTRAINT FK_UserMenu_UserPageTypeGOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FK_UserTypes_UserType]') and OBJECTPROPERTY(id, N'IsForeignKey') = 1)ALTER TABLE [dbo].[UserTypes] DROP CONSTRAINT FK_UserTypes_UserTypeGOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Menu]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[Menu]GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[User]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[User]GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[UserMenu]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[UserMenu]GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[UserPageType]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[UserPageType]GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[UserType]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[UserType]GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[UserTypes]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[UserTypes]GOCREATE TABLE [dbo].[Menu] ( [MenuID] [int] NOT NULL , [Menu] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [MenuLink] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [MenuDescription] [varchar] (1000) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ) ON [PRIMARY]GOCREATE TABLE [dbo].[User] ( [UserID] [int] NOT NULL , [UserName] [varchar] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [UserPassword] [varchar] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ) ON [PRIMARY]GOCREATE TABLE [dbo].[UserMenu] ( [UserMenuID] [int] NOT NULL , [UserPageTypeID] [int] NOT NULL , [UserID] [int] NOT NULL , [MenuID] [int] NOT NULL ) ON [PRIMARY]GOCREATE TABLE [dbo].[UserPageType] ( [UserPageTypeID] [int] NOT NULL , [UserPageType] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ) ON [PRIMARY]GOCREATE TABLE [dbo].[UserType] ( [UserTypeID] [int] NOT NULL , [UserType] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ) ON [PRIMARY]GOCREATE TABLE [dbo].[UserTypes] ( [UserTypesID] [int] NOT NULL , [UserID] [int] NOT NULL , [UserTypeID] [int] NOT NULL ) ON [PRIMARY]GOALTER TABLE [dbo].[Menu] WITH NOCHECK ADD CONSTRAINT [PK_Menu] PRIMARY KEY CLUSTERED ( [MenuID] ) ON [PRIMARY] GOALTER TABLE [dbo].[User] WITH NOCHECK ADD CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ( [UserID] ) ON [PRIMARY] GOALTER TABLE [dbo].[UserMenu] WITH NOCHECK ADD CONSTRAINT [PK_UserMenu] PRIMARY KEY CLUSTERED ( [UserMenuID] ) ON [PRIMARY] GOALTER TABLE [dbo].[UserPageType] WITH NOCHECK ADD CONSTRAINT [PK_UserPageType] PRIMARY KEY CLUSTERED ( [UserPageTypeID] ) ON [PRIMARY] GOALTER TABLE [dbo].[UserType] WITH NOCHECK ADD CONSTRAINT [PK_UserType] PRIMARY KEY CLUSTERED ( [UserTypeID] ) ON [PRIMARY] GOALTER TABLE [dbo].[UserTypes] WITH NOCHECK ADD CONSTRAINT [PK_UserTypes] PRIMARY KEY CLUSTERED ( [UserTypesID] ) ON [PRIMARY] GOALTER TABLE [dbo].[User] ADD CONSTRAINT [IX_UserName] UNIQUE NONCLUSTERED ( [UserName] ) ON [PRIMARY] GO CREATE INDEX [IX_UserID] ON [dbo].[UserTypes]([UserID]) ON [PRIMARY]GO CREATE INDEX [IX_UserTypeID] ON [dbo].[UserTypes]([UserTypeID]) ON [PRIMARY]GOALTER TABLE [dbo].[UserMenu] ADD CONSTRAINT [FK_UserMenu_Menu] FOREIGN KEY ( [MenuID] ) REFERENCES [dbo].[Menu] ( [MenuID] ) ON DELETE CASCADE ON UPDATE CASCADE , CONSTRAINT [FK_UserMenu_UserPageType] FOREIGN KEY ( [UserPageTypeID] ) REFERENCES [dbo].[UserPageType] ( [UserPageTypeID] ) ON DELETE CASCADE ON UPDATE CASCADE GOALTER TABLE [dbo].[UserTypes] ADD CONSTRAINT [FK_UserTypes_User] FOREIGN KEY ( [UserID] ) REFERENCES [dbo].[User] ( [UserID] ) ON DELETE CASCADE ON UPDATE CASCADE , CONSTRAINT [FK_UserTypes_UserType] FOREIGN KEY ( [UserTypeID] ) REFERENCES [dbo].[UserType] ( [UserTypeID] ) ON UPDATE CASCADE GO ok now here's some data for those tables:delete from [user]delete from usertypedelete from usertypesdelete from usermenudelete from userpagetypedelete from menuinsert into [user](userid,username,userpassword) values(1,'user1','123456')insert into [user](userid,username,userpassword) values(2,'user2','654321')insert into [user](userid,username,userpassword) values(3,'user3','456123')insert into usertype(usertypeid,usertype) values(1,'admin')insert into usertype(usertypeid,usertype) values(2,'finance')insert into usertypes(usertypesid,userid,usertypeid) values(1,1,1) -- User1 is in admin groupinsert into usertypes(usertypesid,userid,usertypeid) values(2,2,2) -- User2 is in finance groupinsert into usertypes(usertypesid,userid,usertypeid) values(3,3,1) -- User3 is in admin groupinsert into usertypes(usertypesid,userid,usertypeid) values(4,3,2) -- User3 is in finance groupinsert into menu(menuid,menu,menulink,menudescription) values(1,'Home','index.asp','Go home')insert into menu(menuid,menu,menulink,menudescription) values(2,'View Users','users.asp','View all registered users')insert into menu(menuid,menu,menulink,menudescription) values(3,'View Financial Reports','finance.asp','View latest finance reports')insert into userpagetype(userpagetypeid,userpagetype) values(1,'user')insert into userpagetype(userpagetypeid,userpagetype) values(2,'usertype')insert into usermenu(usermenuid,userpagetypeid,userid,menuid) values (1,2,1,1)insert into usermenu(usermenuid,userpagetypeid,userid,menuid) values (2,2,1,2)insert into usermenu(usermenuid,userpagetypeid,userid,menuid) values (3,2,2,1)insert into usermenu(usermenuid,userpagetypeid,userid,menuid) values (4,2,2,3)-- at this point 'admin' group/role have access to 'Home' and 'View Users'-- while the 'finance' group/role have access to 'Home' and 'View Financial Reports' but not 'View Users'-- Digested:-- 1 = record id-- 2 = userpagetypeid 2 is usertype...-- 1 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'admin'-- 1 = menu id 1, which is 'Home'-- 2 = record id-- 2 = userpagetypeid 2 is usertype...-- 1 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'admin'-- 2 = menu id 2, which is 'View Users'-- 3 = record id-- 2 = userpagetypeid 2 is usertype...-- 2 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'finance'-- 1 = menu id 1, which is 'Home'-- 4 = record id-- 2 = userpagetypeid 2 is usertype...-- 2 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'finance'-- 3 = menu id 3, which is 'View Financial Reports'insert into usermenu(usermenuid,userpagetypeid,userid,menuid) values (5,1,1,3)-- this adds the ability for 'User1' to have extra access to the 'View Financial Reports'-- Digested:-- 5 = record id-- 1 = userpagetypeid 1 is user...-- 1 = ...the above line tells us this record belongs to userid in the 'user' table, which is 'user1'-- 3 = menu id 3, which is 'View Financial Reports' Now I want to pass the userid to a stored procedure that returns the menu for that user and these are my desired results (based on userid):If I pass a userid of:userid = 1result:(menu,menulink,menudescription) 'Home','index.asp','Go home' 'View Users','users.asp','View all registered users' 'View Financial Reports','finance.asp','View latest finance reports'-- user1's results due to being part of the admin group/role and having an extra record because-- of the last record in the 'usermenu' tableuserid = 2result:(menu,menulink,menudescription) 'Home','index.asp','Go home' 'View Financial Reports','finance.asp','View latest finance reports'-- user2's results due to being part of the finance group/roleuserid = 3result:(menu,menulink,menudescription) 'Home','index.asp','Go home' 'View Users','users.asp','View all registered users'-- user3's results due to being part of the admin group/roleI hope I was helpful in explaining this and hope someone can help me.- RoLY roLLs |
|
|
raclede
Posting Yak Master
180 Posts |
Posted - 2005-05-19 : 03:13:35
|
| CREATE PROCEDURE MenuSelProc (@userID int)ASCREATE TABLE #temp ([id] [int] IDENTITY (1, 1) NOT NULL , menuID INT)INSERT into #temp---------------------------- END START TEMP TABLE ---------------------------- 1) Selects All the menu filtered by @useridSELECT -- return the first non-null menu found COALESCE (UserMenu.MenuID, -- if null then search by UserID then by userPageType ID (SELECT TOP 1 UserMenu.MenuID FROM [USER] INNER JOIN UserTypes ON [USER].UserID = UserTypes.UserID INNER JOIN UserPageType ON UserTypes.UserTypeID = UserPageType.UserPageTypeID INNER JOIN UserMenu ON UserPageType.UserPageTypeID = UserMenu.UserPageTypeID WHERE ([USER].UserID = b.UserID) AND (UserTypes.UserTypeID = c.UserTypeID))) MenuID FROM Menu INNER JOIN UserMenu ON Menu.MenuID = UserMenu.MenuID RIGHT OUTER JOIN [User] b ON UserMenu.UserID = b.UserID LEFT OUTER JOIN UserTypes c ON b.UserID = c.UserIDWHERE (b.UserID = @userID)---------------------------- END FILL TEMP TABLE -------------------------- 2) link all menuID in temp to menuID in menutableSELECT Menu.Menu, Menu.MenuLink, Menu.MenuDescriptionFROM Menu INNER JOIN #temp ON #temp.MenuID = Menu.MenuIDDROP TABLE #tempGOCursors are for those who doesn't know how to use SQL raclede™ |
 |
|
|
raclede
Posting Yak Master
180 Posts |
Posted - 2005-05-19 : 03:15:47
|
| --- to executeexec menuselproc 1--- resultMenu Menulink DescHome index.asp Go homeView Users users.asp View all registered usersView Financial Reports finance.asp View latest finance reportsCursors are for those who doesn't know how to use SQL raclede™ |
 |
|
|
RoLYroLLs
Constraint Violating Yak Guru
255 Posts |
Posted - 2005-05-19 : 14:33:09
|
Works great! Thanks. Seems like a mess to me, but maybe because I'm so tired. :) Anyhow, I got one problem with this, which I'll try to fix, but seeing as I am worn out for the week, maybe you can help. If we add the following record:insert into usermenu(usermenuid,userpagetypeid,userid,menuid) values (6,1,1,1) This creates a duplicate record of HOME for user 1. I'm sure by adding select distinct it will work. But I post this to thank you and just in case it doesn't work, it's already here :)Have a great one! - RoLY roLLs |
 |
|
|
raclede
Posting Yak Master
180 Posts |
Posted - 2005-05-19 : 21:11:28
|
| just add distinct after the first select commandCursors are for those who doesn't know how to use SQL raclede™ |
 |
|
|
RoLYroLLs
Constraint Violating Yak Guru
255 Posts |
Posted - 2005-05-23 : 10:27:36
|
| Hello...after some testing there seems to be a problem with the above statement. Here's the problem. Add the following user and assign him to the finance department:insert into [user](userid,username,userpassword) values(4,'user4','321654')insert into usertypes(usertypesid,userid,usertypeid) values(5,4,2) -- User4 is in finance grouprunning the above sproc returns the menu HOME only, when it should return Home AND View Financial Reports.Thanks.- RoLY roLLs |
 |
|
|
raclede
Posting Yak Master
180 Posts |
Posted - 2005-05-23 : 20:49:21
|
| maybe you forgot this one insert into usermenu(usermenuid,userpagetypeid,userid,menuid) values (4,2,4,3)-- at this point 'admin' group/role have access to 'Home' and 'View Users'-- while the 'finance' group/role have access to 'Home' and 'View Financial Reports' but not 'View Users'-- Digested:-- 1 = record id-- 2 = userpagetypeid 2 is usertype...-- 1 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'admin'-- 1 = menu id 1, which is 'Home'-- 2 = record id-- 2 = userpagetypeid 2 is usertype...-- 1 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'admin'-- 2 = menu id 2, which is 'View Users'-- 3 = record id-- 2 = userpagetypeid 2 is usertype...-- 2 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'finance'-- 1 = menu id 1, which is 'Home'-- 4 = record id-- 2 = userpagetypeid 2 is usertype...-- 2 = ...the above line tells us this record belongs to usertypeid in the 'usertype' table, which is 'finance'-- 3 = menu id 3, which is 'View Financial Reports'"Wisdom is knowing what to do next, skill is knowing how to do it, and virtue is doing it. ""The questions you ask consistently will create either enervation or enjoyment, indignation or inspiration, misery or magic. Ask the questions that will uplift your spirit and push you along the path of human excellence. "K.I.S.S - Keep it simple stupidraclede™ |
 |
|
|
|
|
|
|
|