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.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Assigning Roles

Author  Topic 

RoLYroLLs
Constraint Violating Yak Guru

255 Posts

Posted - 2004-07-06 : 18:31:38
Here's the deal.

Objective:
I have a database with a table with user info and other table with possible user roles for the application and a table linking the user to the role.

Rules:
Any user can be in multiple roles; ie: User1 can be of role 'Advertiser' as well as the role of 'Seller'. Only the admin (myself) can make these changes. I'm trying to write a stored procedure (sproc) to compare which roles the user has and the new roles to have. So I figure to cycle thru each possible role (like 7). If the user is part of the role in the current cycle and is not part of the new role sent, then delete that role. And ifthe user is not part of the current role in cycle and is to be part of it the add that urole to the user. (I think that last line was somewhat confusing. Ok well, let's see some code.

Here are the tables:

CREATE TABLE [dbo].[User] (
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[UserID] uniqueidentifier ROWGUIDCOL 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 ,
[UserEmail] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[UserEmailTypeID] [int] NOT NULL ,
[UserEmailVerify] [bit] NOT NULL ,
[UserLastLogin] [datetime] NOT NULL ,
[UserRegistered] [datetime] NOT NULL ,
[UserLastModified] [datetime] NOT NULL ,
[UserLastModifiedBy] [int] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[UserType] (
[UserTypeID] [int] IDENTITY (1, 1) NOT NULL ,
[UserType] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[UserLoginPage] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[UserTypeLastModified] [datetime] NOT NULL ,
[UserTypeLastModifiedBy] [int] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[UserTypes] (
[UserTypesID] [int] IDENTITY (1, 1) NOT NULL ,
[UserID] [int] NOT NULL ,
[UserTypeID] [int] NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[User] WITH NOCHECK ADD
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[UserType] WITH NOCHECK ADD
CONSTRAINT [PK_UserType] PRIMARY KEY CLUSTERED
(
[UserTypeID]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[UserTypes] WITH NOCHECK ADD
CONSTRAINT [PK_UserTypes] PRIMARY KEY CLUSTERED
(
[UserTypesID]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[User] ADD
CONSTRAINT [FK_User_EmailType] FOREIGN KEY
(
[UserEmailTypeID]
) REFERENCES [dbo].[EmailType] (
[EmailTypeID]
)
GO

ALTER TABLE [dbo].[UserTypes] ADD
CONSTRAINT [FK_UserTypes_User] FOREIGN KEY
(
[UserID]
) REFERENCES [dbo].[User] (
[ID]
),
CONSTRAINT [FK_UserTypes_UserType] FOREIGN KEY
(
[UserTypeID]
) REFERENCES [dbo].[UserType] (
[UserTypeID]
)
GO

Now for the sprocs:

CREATE procedure proc_AddUserTypes
@UserID int,
@UserTypeID int,
@UserTypesID int output
as
declare @ErrorCode int
select @ErrorCode = @@Error

declare @TransactionCountOnEntry int

if @ErrorCode = 0
begin
select @TransactionCountOnEntry = @@TranCount
begin transaction
insert
UserTypes
(
UserID,
UserTypeID
)
values
(
@UserID,
@UserTypeID
)

select @UserTypesID = @@Identity, @ErrorCode = @@Error
end

if @@TranCount > @TransactionCountOnEntry
begin
if @ErrorCode = 0
commit transaction
else
rollback transaction
end

return @ErrorCode
GO

CREATE procedure proc_DeleteUserTypes
@UserTypesID int
as
declare @ErrorCode int
select @ErrorCode = @@Error

declare @TransactionCountOnEntry int

if @ErrorCode = 0
begin
select @TransactionCountOnEntry = @@TranCount
begin transaction
delete

from
UserTypes
where
UserTypes.UserTypesID = @UserTypesID

select @ErrorCode = @@Error
end

if @@TranCount > @TransactionCountOnEntry
begin
if @ErrorCode = 0
commit transaction
else
rollback transaction
end

return @ErrorCode
GO

CREATE procedure proc_UpdateUser
@ID int,
@Password varchar(16),
@Email varchar(255),
@EmailTypeID int,
@LastModifiedBy int,
@UserTypeID varchar(600)
as
declare @ErrorCode int
select @ErrorCode = @@Error

declare @TransactionCountOnEntry int

if @ErrorCode = 0
begin
select @TransactionCountOnEntry = @@TranCount
begin transaction
update
[User]
set
[User].UserPassword = @Password,
[User].UserEmail = @Email,
[User].UserEmailTypeID = @EmailTypeID,
[User].UserLastModified = getdate(),
[User].UserLastModifiedBy = @LastModifiedBy
where
[User].ID = @ID

select @ErrorCode = @@Error
end

if @ErrorCode = 0
begin
exec @ErrorCode = proc_ProcessUserTypes @ID, @UserTypeID
end

if @@TranCount > @TransactionCountOnEntry
begin
if @ErrorCode = 0
commit transaction
else
rollback transaction
end

return @ErrorCode
GO

Ok, here is some more info. The '@UserTypeID' in 'proc_UpdateUser' get's sent the list if roles in CSV format whic I then parse in the 'proc_ProcessUserTypes' sproc. Here it is:

CREATE procedure proc_ProcessUserTypes
@ID int,
@UserTypeID varchar(600)
as
declare @ErrorCode int
select @ErrorCode = @@Error

declare @TransactionCountOnEntry int

declare @CurUserTypeID int
declare @Pos int

if @ErrorCode = 0
begin
select @UserTypeID = ltrim(rtrim(@UserTypeID))+ ','
select @Pos = charindex(',', @UserTypeID, 1)

if replace(@UserTypeID, ',', '') <> ''
begin
while @Pos > 0
begin
select @CurUserTypeID = ltrim(rtrim(left(@UserTypeID, @Pos - 1)))
if @CurUserTypeID <> ''
begin
--NEED HELP HERE
--Add
--exec @ErrorCode = proc_AddUserTypes @CurUserTypeID
--Delete
--exec @ErrorCode = proc_DeleteUserTypes @CurUserTypeID

end
select @UserTypeID = right(@UserTypeID, len(@UserTypeID) - @Pos)
select @Pos = charindex(',', @UserTypeID, 1)
end
end
end

if @@TranCount > @TransactionCountOnEntry
begin
if @ErrorCode = 0
commit transaction
else
rollback transaction
end

return @ErrorCode

GO

I noted above where i need the help. I'd like to cycle thru the possible values and do two checks, if they are already part of the role or not and if they are to be assigned the role or not. Any questions? Not clear? Please ask. Thanks.

PS: Sorry if this is sooo long.

- RoLY roLLs

RoLYroLLs
Constraint Violating Yak Guru

255 Posts

Posted - 2004-07-06 : 21:11:54
UPDATE:

Just a little update, I do have this working properly on my asp page, but that requires several requests to the database. IE: if i had to do a major change and remove 3 current roles and add 3 others, that's 6 individual requests. So I want this to be handled on the SQL server. I just don't know how to handle moving thru a record set in T-SQL. If it is possible to just modify my asp code a bit to work on T-SQL, let me know and I'll post it here and work on it and have anyone who wants to work on it as well.

Thanks.

- RoLY roLLs
Go to Top of Page

RoLYroLLs
Constraint Violating Yak Guru

255 Posts

Posted - 2004-07-07 : 11:05:50
UPDATE:

Hmm, not sure if anyone if trying to figure it out or not. But here's a simpler description of what I want to do, if it's even possible in a sproc. Is there a way or iterate thru a recordset inside a sproc? Like in my asp pages I use ADODB to create a recordset and use the MoveNext method to move to the next record. Does something like this to move thru a recordset exists in T-SQL? Maybe I have to keep this at the webserver level? Any kinda push in any direction would be helpful. Thanks.

- RoLY roLLs
Go to Top of Page

MichaelP
Jedi Yak

2489 Posts

Posted - 2004-07-07 : 11:18:12
Here are two possible solutions:
1. Loop through your RS on the client side and issue the (6) database calls.

2. Loops through the RS and build up a string that you can parse in the stored procs to issues the N number of commands. This one will run into the 8000 varchar limit though.

Even though it sucks, #1 might be the best solution here.

[Edit]
I re-read your post, and I think I might have a better solution.
I'm guessing this isn't something that you hit 100's of times a day, maybe more like a handful of times per day, so performance isn't super critical. Why not delete all roles, and only call inserts for what's in your recordset? Basically do #1 as above, but delete all roles first.
[/Edit]

Michael

<Yoda>Use the Search page you must. Find the answer you will.</Yoda>
Go to Top of Page

RoLYroLLs
Constraint Violating Yak Guru

255 Posts

Posted - 2004-07-07 : 15:58:47
Thanks Michael. Your solution #3 was one I had thought about, but hoped I could avoid the multiple INSERTs even if the record was there already. But it seems like the best route to go thru.

I'll work on that, but in the meantime, is "No" the answer to: "Is there a way to move thru a recordset inside a sproc?"

Thanks for your help.



- RoLY roLLs
Go to Top of Page
   

- Advertisement -