Я пока не могу комментировать, поэтому я должен добавить это как ответ.
Мне нравится быть как можно более конкретным, поэтому я предпочитаю включать основной тип. Вот почему я проголосовал за ответ Аарона.
Использование DATABASE_PRINCIPAL_ID может дать неожиданные результаты, если существует другой основной тип с тем же именем, что и роль, которую вы хотите добавить. Это связано с тем, что DATABASE_PRINCIPAL_ID возвращает идентификационный номер принципала в текущей базе данных, а не специально для принципала с типом роли базы данных.
Допустим, у вас есть пользователь с тем же именем, что и у роли базы данных. Статус сценария Yada будет указывать на успех, но он не будет добавлять роль, поскольку уже существует принципал с таким именем. Однако сценарий Аарона выдаст следующую ошибку:
Имя пользователя, группы или роли уже существует в текущей базе данных.
Я бы предпочел уловить эту проблему раньше (например, при запуске сценария), чем позже (например, когда используется мое приложение).
Вот что я обычно использую:
IF NOT EXISTS(SELECT NULL FROM sys.database_principals WHERE [name] = 'role_name' AND [type]='R')
BEGIN
-- add user;
END
Если я действительно хочу обработать этот сценарий и не показывать ошибку, я мог бы использовать что-то вроде этого:
DECLARE @RoleName sysname,
@PrincipalType NVARCHAR(60);
SET @RoleName = 'role_name';
SET @PrincipalType = (SELECT type_desc FROM sys.database_principals WHERE [name] = @RoleName);
IF @PrincipalType IS NULL
BEGIN
-- Add user;
END
ELSE IF @PrincipalType <> 'DATABASE_ROLE'
BEGIN
--Deal with the issue as desired. Here we're printing out a warning. Important: The status will still indicate that the Query executed successfully when using PRINT to show warnings.
PRINT 'WARNING: The ' + @RoleName + ' database role was not created. A principal already exists in the database with a type of ' + @PrincipalType + '.';
END