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.