lunes, 16 de agosto de 2010

Asociar usuarios huérfanos en SQL

Aunque éste no es mi tema, pero hoy han solicitado ayuda por el canal habitual (mail a un grupo) y no he podido resistirme a contestar. Es un problema bastante habitual. Migramos una base de datos de un SQL a otro servidor y perdemos los login. Si creamos un nuevo login éste no deja asociarlo directamente al de la base de datos importada (o restaurada) porque el SID es diferente. La solución es sencilla y MS lo tiene reportado, pero para todos aquellos que no les guste meterse con los extensos artículos de Microsoft, o simplemente vagos para buscarlo más allá de un 'googleado', os dejo estos pasos:

1.- Crear el usuario en el Login del SQL con el mismo nombre que en la base de datos, pero sin asociarlo a ninguna base de datos porque no deja.

2.- Correr el script de abajo para cada usuario en el Query Analyzer

sp_change_users_login 'update_one', 'pepe', 'pepe'

Con ésto ya tenemos el usuario pepe asociado tanto al SQL como a la base de datos. Ahora solo falta ir metiendo uno a uno, o si es muy extensa crearse un script para ello.

NOTA: Mi colega Manu, que sí que parece que se lo ha mirado por ahí, me ha mandado el script para hacerlos todos a la vez. Os lo publico para los que quieran echarle un vistazo. Gracias Manu.


-- *** Identificar Usuarios Huérfanos, dejándolos en tabla temporal ***

CREATE TABLE #TMP_DBUSERS
(
   dbname varchar(256)
   ,dbuser varchar(256)
)

DECLARE curDBs CURSOR
READ_ONLY
FOR SELECT name FROM master..sysdatabases

DECLARE @name varchar(256)
OPEN curDBs

FETCH NEXT FROM curDBs INTO @name
WHILE (@@fetch_status <> -1)
BEGIN
   IF (@@fetch_status <> -2)
   BEGIN
      DECLARE @SQLquery AS VARCHAR(2048)
      SELECT @SQLquery = 'INSERT INTO #TMP_DBUSERS '      SELECT @SQLquery = @SQLquery + 'SELECT ''' + @name + ''', name '      SELECT @SQLquery = @SQLquery + 'FROM [' + @name + '].dbo.sysusers '      SELECT @SQLquery = @SQLquery + 'where sid NOT IN (SELECT sid FROM master.dbo.syslogins) '      SELECT @SQLquery = @SQLquery + 'AND islogin=1 '      SELECT @SQLquery = @SQLquery + 'AND name not in (''INFORMATION_SCHEMA'', '
      SELECT @SQLquery = @SQLquery + '''sys'', ''guest'', ''dbo'', ''system_function_schema'')'

      EXEC(@SQLquery)
   END
   FETCH NEXT FROM curDBs INTO @name
END

CLOSE curDBs
DEALLOCATE curDBs
GO


-- *** Comprobar Usuarios Huérfanos
--
*** para los que existe un Login con el mismo nombre.
SELECT * FROM #TMP_DBUSERS
where dbuser in (select name from master..syslogins)

-- *** Comprobar Usuarios Huérfanos
-- *** para los que NO existe un Login con el mismo nombre.
-- *** PD: ostias, pedrín !!!SELECT * FROM #TMP_DBUSERS
where dbuser not in (select name from master..syslogins)

-- *** Generar sentencias sp_change_users_login
-- *** para corregir los Usuarios Huérfanos con Inicio de Sesión conocido
-- *** PD: La salida de este Script, debe ejecutarse como otra Query
-- *** Revisar antes.
SELECT 'USE [' + dbname + ']; ' + CHAR(13)
      + 'EXEC sp_change_users_login ''Update_One'', ''' + dbuser + ''', ''' + dbuser + ''';'
FROM #TMP_DBUSERS
WHERE dbuser IN (select name from master..syslogins)







No hay comentarios: