2010-02-25 3 views
1

Я взял код здесь: Check if role consists of particular user in DB?Убедитесь, что пользователь принадлежит к БД роли

SELECT * 
      FROM sys.database_role_members AS RM 
      JOIN sys.database_principals AS U 
      ON RM.member_principal_id = U.principal_id 
      JOIN sys.database_principals AS R 
      ON RM.role_principal_id = R.principal_id 
      WHERE U.name = 'operator1' 
      AND R.name = 'myrole1' 

, что запрос возвращает 1 строку. Это означает, что пользователь 'operator1' принадлежит роли 'myrole1'. Теперь я пытаюсь создать хранимую процедуру для этого:

CREATE PROCEDURE [dbo].[Proc1] 
(
    @userName varchar, 
    @roleName varchar 
) 
AS 

IF EXISTS(SELECT * 
      FROM sys.database_role_members AS RM 
      JOIN sys.database_principals AS U 
      ON RM.member_principal_id = U.principal_id 
      JOIN sys.database_principals AS R 
      ON RM.role_principal_id = R.principal_id 
      WHERE U.name = @userName 
      AND R.name = @roleName) 
      RETURN 0 
ELSE RETURN -1 

Я использую стандартную команду из SQL Server 2008 «Выполнить хранимую процедуру»

DECLARE @return_value int 

EXEC @return_value = [dbo].[Proc1] 
     @userName = N'operator1', 
     @roleName = N'myrole1' 

SELECT 'Return Value' = @return_value 

GO 

она всегда возвращает -1. ПОЧЕМУ ???

ответ

2

Вам необходимо определить атрибут длины для каждого из параметров вашей процедуры. Если изменить начало хранимого объявления процедуры к следующему, он возвращает правильный ответ:

CREATE PROCEDURE [dbo].[Proc1] 
(
    @userName varchar(255), 
    @roleName varchar(255) 
) 
AS 

Без атрибутов длины, SQL Server автоматически определяет длину переменных, как 1, так что пользователь и роль соответствовала соответственно «o» и «m». SQL Server несовместим с тем, как он обрабатывает переменные без спецификатора длины - иногда они имеют длину 30, а иногда они имеют длину 1. Лучше всего всегда указывать атрибуты длины для строковых переменных. Смотрите следующий SQL статье блога для получения дополнительной информации:

http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length.aspx

+0

Спасибо за вход, тамплиер. Извините за долгосрочный ответ. Я не знал, что я должен отметить ваш ответ как полезный и другие вещи ... –

0

Этот код не является хорошим, потому что он может вернуться ложным, если пользователь является членом группы, которая затем является членом роли.

Пользователь встроенной функции IS_MEMBER() - это намного проще и всегда защищать.

Смежные вопросы