Вы не должны использовать устаревшие отсталые взгляды на совместимость (search this page for sysusers
, for example). Вместо этого вы должны использовать sys.database_principals
и sys.database_role_members
. Имейте в виду, что текущему соединению может быть предоставлен доступ за пределами области действия базы данных (например, они возвратят пустые результаты, если пользователь окажется sysadmin
, и в этом случае им не нужно явно предоставлять членство в роли или конкретное разрешения). Кроме того, для разрешений, явно назначенных за пределами роли роли, которая будет переопределять функции, предоставленные этой ролью, вы должны дополнительно проверить sys.database_permissions
. Вот автономный пример, который вы можете проверить (если у вас еще нет логина с именем blatfarA
или базы данных под названием floob
).
CREATE LOGIN blatfarA WITH PASSWORD = 'foo', CHECK_POLICY = OFF;
GO
CREATE DATABASE floob;
GO
USE floob;
GO
CREATE USER blatfarB FROM LOGIN [blatfarA] WITH DEFAULT_SCHEMA = dbo;
GO
GRANT SELECT, UPDATE ON SCHEMA::dbo TO blatfarB;
DENY INSERT, EXECUTE ON SCHEMA::dbo TO blatfarB;
GO
EXEC sp_addrolemember N'db_datareader', N'blatfarB'
GO
Чтобы проверить:
EXECUTE AS LOGIN = N'blatfarA';
GO
DECLARE @login NVARCHAR(256), @user NVARCHAR(256);
SELECT @login = login_name FROM sys.dm_exec_sessions WHERE session_id = @@SPID;
SELECT @user = d.name
FROM sys.database_principals AS d
INNER JOIN sys.server_principals AS s
ON d.sid = s.sid
WHERE s.name = @login;
SELECT u.name, r.name
FROM sys.database_role_members AS m
INNER JOIN sys.database_principals AS r
ON m.role_principal_id = r.principal_id
INNER JOIN sys.database_principals AS u
ON u.principal_id = m.member_principal_id
WHERE u.name = @user;
SELECT class_desc, major_id, permission_name, state_desc
FROM sys.database_permissions
WHERE grantee_principal_id = USER_ID(@user);
GO
REVERT;
Результаты:
name name
-------- -------------
blatfarB db_datareader
class_desc major_id permission_name state_desc
---------- -------- --------------- ----------
DATABASE 0 CONNECT GRANT
SCHEMA 1 INSERT DENY
SCHEMA 1 EXECUTE DENY
SCHEMA 1 SELECT GRANT
SCHEMA 1 UPDATE GRANT
ВЫМЫТЬ:
USE master;
GO
ALTER DATABASE floob SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
DROP DATABASE floob;
GO
DROP LOGIN blatfarA;
GO
Эй, спасибо, это намного лучше. Между тем, я обнаружил, что моя первая попытка не всегда давала правильные результаты. Я изменил принятый ответ. –
Возможно, вы упростите код в демо, чтобы использовать 'CURRENT_USER' вместо того, чтобы беспокоиться о запросе' @ login'. Старые привычки умирают с трудом. –
«Старые привычки умереть» - вы очень правы! –