2010-10-01 10 views
5

Estoy intentando escribir una función de clasificador para el gobernador de recursos de SQL 2008. Me gustaría usar una función de base de datos creada por el usuario para identificar si el usuario debe entrar en un grupo de carga de trabajo en particular. Los inicios de sesión en cuestión son inicios de sesión de SQL. No puedo usar IS_MEMBER(), porque IS_MEMBER se restringe al contexto actual de la base de datos (en este caso, maestro). No puedo usar [base de datos de usuario] .sys.database_principals porque la función del clasificador debe estar vinculada al esquema (restringiendo así las búsquedas al contexto actual de la base de datos). Además, las vistas a las que hace referencia la función también deben estar enlazadas al esquema, lo que significa que no puedo crear una vista en el maestro para hacer referencia a las vistas de seguridad de la base de datos del usuario.¿Cómo creo una función de clasificador de Governor de recursos basada en una función de base de datos?

El objetivo aquí es poder ejecutar básicamente IS_MEMBER() desde el maestro para verificar un rol en otra base de datos.

Respuesta

3

Se puede crear un desencadenador DDL en su base de datos que actualiza una tabla en el maestro para que tenga toda la información del usuario/grupo allí también. A continuación, puede consultar en contra de eso. Probablemente desee adjuntar el activador a ADD_ROLE_MEMBER y DROP_ROLE_MEMBER como mínimo.

Estoy empezando a trabajar con el Gobernador de recursos, por lo que si encuentro una forma "más limpia" de hacerlo, volveré a publicar aquí.

+0

Ooo, me encanta esta solución. Para explicarlo con un poco más de detalle, Tom dice que mantendría una tabla de usuarios en master con su lista de bases de datos, roles y usuarios. Idealmente, SQL Server mantendría esta tabla para usted con desencadenadores DDL, pero no sé si puede configurar desencadenadores DDL en algunas de las tablas de sistema relacionadas que desee. Puede tener que actualizar la lista manualmente. Luego haga que su función de clasificador del gobernador de recursos consulte esa tabla para obtener el grupo de recursos correcto. Brillante. –

+0

Esta podría ser la mejor solución, aunque termines duplicando información entre el maestro y el usuario db y suena como un dolor de cabeza administrativo. No estoy seguro de que me acerque a él creando triggers, ya que me preocuparía que cualquier desencadenante que puse en sprocs/tables del sistema pueda sobrescribirse fácilmente con un parche. Mi enfoque sería construir un procedimiento almacenado en el maestro para vivir con la tabla y analizar los sys.database_principals de las bases de datos de usuario y administrar la tabla de búsqueda. Incluso podría ser posible llamar a este sproc de sincronización desde la propia función del clasificador. –

+0

Una función no puede tener ningún efecto en un objeto fuera de la función en sí, por lo que no sería posible completar una tabla permanente de esa manera. Creo que si tratara de llenar una tabla temporal dentro de la función, entonces tendría un problema con el hecho de que la función debe estar enlazada al esquema. Eso va a causar problemas al pasar por las bases de datos. –

0

MSDN dice:

The following system functions can be used for classification: HOST_NAME(), 
APP_NAME(), SUSER_NAME(), SUSER_SNAME(), IS_SRVROLEMEMBER(), and IS_MEMBER(). 

que pueda sugerir la función de gobernador se ejecuta en la base de datos por defecto del usuario final, y se puede utilizar IS_MEMBER allí.

Si no, supongo que puede unir algunas vistas del sistema para comprobar si el usuario actual tiene un rol. vistas del sistema permiten especificar un nombre de tres partes, como TestDb.sys.database_principals:

select * 
from master.sys.login_token l 
join TestDB.sys.database_principals m 
on  l.sid = m.sid 
join TestDB.sys.database_role_members rm 
on  rm.member_principal_id = m.principal_id 
join TestDB.sys.database_principals r 
on  rm.role_principal_id = r.principal_id 
where r.name = 'testrole' -- Role Name 
     and l.name = SUSER_NAME() -- User Name 

Esto suena bastante complejo e inseguro, así que espero que haya una mejor respuesta :)

+1

Lo sentimos, no puedo usar ____. Sys.database_principals y otras vistas, como se indica en mi pregunta. La función debe estar vinculada a un esquema, por lo que no puede usar nombres de 3 partes. Las pruebas muestran que IS_MEMBER no se ejecuta en el contexto de la base de datos predeterminada, sino en el maestro. Entonces IS_MEMBER no funciona. –

Cuestiones relacionadas