November 15, 2005 at 6:49 am
Is there an alternative to running sp_change_users_login to fix each orphaned user because I have almost a hundred orphaned users!
Thanks
November 15, 2005 at 6:52 am
You can update the system tables directly.
November 15, 2005 at 6:53 am
Hi Kory,
Please can you explain how to this?
Thanks
November 15, 2005 at 7:13 am
Why wont sp_change_users_login work for you? What are your permissions on the server/database?
If you have 'sysadmin' role I recommend using 'auto fix'. If you are dbo in the database referenced I recommend generating dynamic sql per user using the 'Update_One' option
You must have 'sysadmin' for this method and updating system objects outside of delivered procedures is dangerous and should not be done. I would not conduct it without an experienced understanding of what you are doing and have a good backup!
sp_configure 'allow updates', 1
Go
Reconfigure With OverRide
Go
/* Update dummy db users sid to login sid */
Update dbo.sysusers
Set sid = sl.sid
From master.dbo.syslogins sl
Inner Join userdb.dbo.sysusers su
On sl.name = su.name
Where su.name = 'dummy'
sp_configure 'allow updates', 0
Go
Reconfigure With OverRide
Go
November 15, 2005 at 7:26 am
Select 'Exec sp_change_users_login ''Update_One'','''+su.name+''','''+su.name+''''
From master.dbo.syslogins sl
Inner Join dbo.sysusers su
On sl.name = su.name
Where su.uid > 2
November 15, 2005 at 7:30 am
IMHO it would be better to write a loop that would start sp_change_users_login for each user. I found one script that we used on a DB restored for testing purposes. Not sure whether this is precisely what you need, but it should at least help you to understand what I mean:
DECLARE @name AS varchar(50)
DECLARE cr_logins CURSOR FOR
SELECT name FROM master..syslogins WHERE name IS NOT NULL
OPEN cr_logins
FETCH NEXT FROM cr_logins INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @name
EXEC master..sp_change_users_login 'update_one', @name, @name
FETCH NEXT FROM cr_logins INTO @name
END
CLOSE cr_logins
DEALLOCATE cr_logins
BTW, this is exception, otherwise I avoid cursors - but it makes little difference what you use to start a simple sp over and over.
EDIT : I didn't see the last post by Kory when I wrote this one, and was referring to the updating of system objects when I said that this would be better. If Kory's last solution works, then don't bother to read my post at all
November 15, 2005 at 7:53 am
Thank you both, works perfectly.
Regards
September 7, 2006 at 7:21 am
Hey, Great code here - feeding the userlist without use of a cursor, I love that! However, a question: Isn't this running the procedure for all users whether or not they need relinking? ie. Ultimately, we would only run this procedure for the list of users returned using the 'Report' option. I am researching the system values now to determine how I could do this, but do you have a way to limit this calll to only run on unlinked users, the ones returned in the 'Report' option of this proc?
September 7, 2006 at 11:36 am
That is correct edit the Master or if it is from a restore operation rerestore it is faster than editing the Master. Hope this helps.
Kind regards,
Gift Peddie
Kind regards,
Gift Peddie
September 8, 2006 at 5:18 am
I wanted to pass something by everyone - I think I have a pretty good way to handle all databases on a server. One difficulty with this of course is the blasted restriction on the "USE" command in SPs. However, there is the undocumented sp_MSForEachDB proc that can, in many cases, get around this.
This is the simple proc that makes the call - I chose autofix instead of the update_one since I want to handle updates to the logins and use the sysuser database as the "master" not the syslogins. Also, one important "trick" if you are not aware of it. You must change databases based on the current parm value of the msForEachDb proc, otherwise your proc will execute once for each database but for the same database! the USE command with the "?" directive delimited by semicolon for multiple commands works just fine here. (I included a display on the dbname as well). This pattern should be handy to anyone needing to loop through databases and run procs that need to work on the "current" database. To my knowledge, the "unlinked" users are simply users with a different sid than the master. We simply want to match it, and this accomplished this nicely. Comments appreciated.
First, the driver procedure to loop through the databases -
----------------------------------------------------------
Create PROC uspSearchDBServerForOrphans
AS
Exec sp_MSForEachDB 'USE ?;select db_name();EXEC uspSearchForOrphans '
----------------------------------------------------------
CREATE PROC uspSearchDBServerForOrphans
AS
declare @UserName varchar(50)
declare #curUsers CURSOR
For
select SU.name from Sysusers SU
Right Outer Join master.dbo.syslogins SL
On SL.name = SU.name
and SU.sid <> SL.sid -- Same rowset as 'Report' option
where su.uid > 2
open #curUsers
fetch next from #curUsers into @UserName
while @@fetch_status = 0
begin
exec sp_change_users_login @action = 'auto_fix', @usernamepattern = @UserName
fetch next from #curUsers into @UserName
end
close #curUsers
deallocate #curUsers
---
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply