检查DB中是否存在角色?

san*_*084 9 sql database sql-server permissions roles

我想在多个数据库中添加相同角色的用户.但是,该角色可以/不可以存在于所有数据库中.如何检查角色是否存在于数据库中以及是否确实添加了该角色的用户?

例如,IF角色存在BEGIN在角色END中添加用户

Yad*_*ada 15

尝试:

IF DATABASE_PRINCIPAL_ID('role') IS NULL
BEGIN
  -- add user here
  CREATE ROLE role AUTHORIZATION MyUser;
END
Run Code Online (Sandbox Code Playgroud)


Aar*_*and 8

IF EXISTS 
(
  SELECT 1
    FROM sys.database_principals
    WHERE type_desc = 'DATABASE_ROLE'
    AND name = 'name'
)
BEGIN
  -- add user;
END
Run Code Online (Sandbox Code Playgroud)


小智 5

我还不能发表评论,所以我必须补充一下作为答案.

我喜欢尽可能具体,这就是为什么我更喜欢包括主要类型.这就是我投票给Aaron的答案的原因.

如果存在与要添加的角色同名的另一个主体类型,则使用DATABASE_PRINCIPAL_ID可能会产生意外结果.这是因为DATABASE_PRINCIPAL_ID返回当前数据库中主体的ID号,而不是具体类型为数据库角色的主体的ID号.

假设您有一个与数据库角色同名的用户.Yada脚本的状态表示成功,但它不会添加角色,因为已经存在具有该名称的主体.但是,Aaron的脚本会返回以下错误:

用户,组或角色"名称"已存在于当前数据库中.

我宁愿早期(例如,当脚本运行时)比以后(例如,当我的应用程序被使用时)捕获此问题.

这是我通常使用的:

IF NOT EXISTS(SELECT NULL FROM sys.database_principals WHERE [name] = 'role_name' AND [type]='R')
BEGIN
    -- add user;
END
Run Code Online (Sandbox Code Playgroud)

如果我真的想处理这种情况而不显示错误,我可以使用这样的东西:

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
Run Code Online (Sandbox Code Playgroud)