Es muy habitual que durante nuestro día a día recurramos a alguno de los procedimientos almacenados de sistema de la «familia» sp_help. Los motivos pueden ser varios, desde el desconocimiento de una DMV que nos proporcione la información, las costumbres heredadas, etc. Normalmente cuando acudimos a la ayuda sobre dichos procedimientos se nos advierte que son heredados y que debemos utilizar las DMVs correspondientes. Por ejemplo si nos centramos en uno de ellos, sp_helprotect, podemos analizar dicho impacto más detalladamente.El procedimiento sp_helprotect devuelve un listado de permisos para los objetos y usuario que le indiquemos. Su sintaxis es la siguiente:

sp_helprotect [ [ @name = ] object_statement ]          [ , [ @username = ] security_account]    

     [ , [ @grantorname = ] grantor]            

     [ , [ @permissionarea = ] type]

El siguiente script crea un par de logins/usuarios sobre la base de datos AdventureWorks2008 y a continuación asigna ciertos permisos a dichos usuarios.

USE AdventureWorks2008

GO

CREATE LOGIN loginA WITH PASSWORD=‘loginA’, DEFAULT_DATABASE=AdventureWorks2008, CHECK_POLICY=OFF, CHECK_EXPIRATION=OFF

GO

CREATE LOGIN loginB WITH PASSWORD=‘loginB’, DEFAULT_DATABASE=AdventureWorks2008, CHECK_POLICY=OFF, CHECK_EXPIRATION=OFF

GO

CREATE USER userA FOR LOGIN loginA

GO

CREATE USER userB FOR LOGIN loginB

GO

GRANT SELECT ON Person.Person TO userA

GO

DENY DELETE ON Person.Person TO userB

GO

DENY VIEW DEFINITION ON Person.Person TO userB

GO

GRANT SELECT ON Schema::Person to userA

Si a continuación preguntamos a SQL Server los permisos de dichos usuarios mediante sp_helprotect obtendremos los siguientes datos:

exec sp_helprotect null,‘userA’

GO

exec sp_helprotect null,‘userB’

Como podemos ver no existe constancia del permiso de SELECT sobre el esquema Person del usuario userA. Sin embargo si utilizamos las DMV para obtener esta información podemos comprobar cómo sí nos aparecen todos los permisos asignados:

SELECT

    permission_name Permiso,

    class_desc Tipo_Objeto,

    COALESCE (OBJECT_SCHEMA_NAME (major_id),‘.’) Esquema,

    COALESCE (OBJECT_NAME(major_id),‘.’) Objeto,

    USER_NAME(grantee_principal_id) Usuario,

    USER_NAME(grantor_principal_id) Otorgador

FROM sys.database_permissions

JOIN sys.database_principals

ON principal_id=grantee_principal_id

WHERE name IN (‘userA’,‘userB’)

ORDER BY name

La conclusión de este post es que las DMVs deben ser utilizadas como norma si no queremos sorpresas, dejando el uso de elementos heredados como los procedimientos almacenados sp_helpXXXX, vistas de sistema, etc. únicamente como una salvaguarda de compatibilidad. Desgraciadamente aún existen muchos servidores SQL Server 2000 en uso lo cual dificulta la labor de los DBA y hace que deban tener scripts para sus procesos administrativos diferentes para cada versión.

Por suerte las diferencias entre SQL Server 2005 y 2008 son mínimas en lo que a DMVs se refiere (se han añadido nuevas y se ha añadido alguna columna a algunas de las existentes) por lo que el coste de adaptación en este caso será mínimo. Eso sí, como bien se indica en la presentación de las DMVs en los BOL, no se nos garantiza que seguirán estando ahí, con la misma funcionalidad, etc. en siguientes versiones.

 

Rubén Garrigós