Проверить, существует ли роль в БД? - PullRequest
9 голосов
/ 02 февраля 2010

Я хочу добавить пользователей в одной роли в более чем одну базу данных. Однако роль может / не может присутствовать во всей базе данных. Как я могу проверить, существует ли роль в базе данных и добавляет ли она пользователей в этой роли?

например. ЕСЛИ роль существует НАЧАТЬ Добавить пользователя в роли END

Ответы [ 4 ]

15 голосов
/ 02 февраля 2010

попробовать:

IF DATABASE_PRINCIPAL_ID('role') IS NULL
BEGIN
  -- add user here
  CREATE ROLE role AUTHORIZATION MyUser;
END
7 голосов
/ 02 февраля 2010
IF EXISTS 
(
  SELECT 1
    FROM sys.database_principals
    WHERE type_desc = 'DATABASE_ROLE'
    AND name = 'name'
)
BEGIN
  -- add user;
END
5 голосов
/ 29 января 2013

Я пока не могу комментировать, поэтому я должен добавить это как ответ.

Мне нравится быть как можно более конкретным, поэтому я предпочитаю включать основной тип. Вот почему я проголосовал за ответ Аарона.

Использование 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
0 голосов
/ 17 января 2017

Чтобы указать базу данных, в которой вы хотите создать роль, вам нужно использовать

USE [DATABASE_NAME];

тогда вы могли бы продолжить ответ Яды, и это будет так

USE [DATABASE_NAME];
IF DATABASE_PRINCIPAL_ID('role') IS NULL
BEGIN
-- add user here
CREATE ROLE role AUTHORIZATION MyUser;
END
...