Как получить список пользователей для всех баз данных экземпляра - PullRequest
6 голосов
/ 15 марта 2010

Полагаю, процедура должна выглядеть примерно так:

declare @db varchar(100)
declare @user varchar(100)
declare c cursor for select name from sys.sysdatabases        

open c

fetch next from c into @db

while @@fetch_status = 0
begin
    print @db   
    exec ('use ' + @db)

    declare u cursor for select name from sys.sysusers
        where issqlrole <> 1 and hasdbaccess <> 0 and isntname <> 1

    open u   

    fetch next from u into @user

    while @@fetch_status = 0
    begin
        print @user
        fetch next from u into @user
    end

    print '--------------------------------------------------'
    close u     
    deallocate u    
    fetch next from c into @db
end

close c
deallocate c

Но проблема в том, что exec ('use' + @db) не работает. И я всегда получаю список пользователей выбранной базы данных. Как мне это исправить?

P.S .: Я хочу, чтобы этот код работал на серверах SQL 2000 и 2005.

Ответы [ 3 ]

10 голосов
/ 15 марта 2010

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

exec sp_MSforeachdb 'select * from ?.sys.sysusers'

"?" является заполнителем для имени базы данных, которое будет добавлено к команде, поскольку оно выполняется для каждой базы данных в вашей системе.

2 голосов
/ 15 марта 2010

Вот хороший запрос от http://www.sqlservercentral.com/scripts/Administration/63841/ Если у вас нет учетной записи, это бесплатная регистрация и очень хороший ресурс.

Помещает все в временную таблицу, затем вы можете делать с ней все, что захотите.

USE MASTER
GO

BEGIN
    IF LEFT(CAST(Serverproperty('ProductVersion') AS VARCHAR(1)), 1) = '9'
        IF EXISTS (SELECT TOP 1 *
                    FROM Tempdb.sys.objects (nolock)
                    WHERE name LIKE '#TUser%')
            DROP TABLE #TUser
    ELSE
        IF LEFT(CAST(Serverproperty('ProductVersion') AS VARCHAR(1)), 1) = '8'
            IF EXISTS (SELECT TOP 1 *
                        FROM Tempdb.dbo.sysobjects (nolock)
                        WHERE name LIKE '#TUser%')
                DROP TABLE #TUser

        CREATE TABLE #tuser 
        (
            ServerName varchar(256),
            DBName SYSNAME,
            [Name] SYSNAME,
            GroupName SYSNAME NULL,
            LoginName SYSNAME NULL,
            default_database_name SYSNAME NULL,
            default_schema_name VARCHAR(256) NULL,
            Principal_id INT,
            sid VARBINARY(85)
        )

        IF LEFT(CAST(Serverproperty('ProductVersion') AS VARCHAR(1)), 1) = '8'
            INSERT INTO #TUser
            EXEC sp_MSForEachdb
            '
            SELECT 
            @@SERVERNAME,
            ''?'' as DBName,
            u.name As UserName,
            CASE 
            WHEN (r.uid IS NULL) THEN ''public''
            ELSE r.name
            END AS GroupName,
            l.name AS LoginName,
            NULL AS Default_db_Name,
            NULL as default_Schema_name,
            u.uid,
            u.sid
            FROM [?].dbo.sysUsers u
            LEFT JOIN ([?].dbo.sysMembers m 
            JOIN [?].dbo.sysUsers r
            ON m.groupuid = r.uid)
            ON m.memberuid = u.uid
            LEFT JOIN dbo.sysLogins l
            ON u.sid = l.sid
            WHERE u.islogin = 1 OR u.isntname = 1 OR u.isntgroup = 1
            /*and u.name like ''tester''*/
            ORDER BY u.name
            '
        ELSE IF LEFT(CAST(Serverproperty('ProductVersion') AS VARCHAR(1)), 1) = '9'
            INSERT INTO #TUser
            EXEC sp_MSForEachdb
            '
            SELECT 
            @@SERVERNAME,
            ''?'',
            u.name,
            CASE 
            WHEN (r.principal_id IS NULL) THEN ''public''
            ELSE r.name
            END GroupName,
            l.name LoginName,
            l.default_database_name,
            u.default_schema_name,
            u.principal_id,
            u.sid
            FROM [?].sys.database_principals u
            LEFT JOIN ([?].sys.database_role_members m
            JOIN [?].sys.database_principals r 
            ON m.role_principal_id = r.principal_id)
            ON m.member_principal_id = u.principal_id
            LEFT JOIN [?].sys.server_principals l
            ON u.sid = l.sid
            WHERE u.TYPE <> ''R''
            /*and u.name like ''tester''*/
            order by u.name
            '

    SELECT *
    FROM #TUser
    ORDER BY DBName, [name], GroupName

    DROP TABLE #TUser
END
0 голосов
/ 03 апреля 2018

Вот как создать список всех пользователей всех баз данных в экземпляре SQL Server.Я думаю, это то, что вы ищете.

Если вам нужен список всех пользователей для всех баз данных для всех экземпляров, вы можете изменить скрипт для этого.Просто разверните методы, используемые в сценарии.

https://tidbytez.com/2018/02/05/how-to-create-a-list-of-all-users-of-all-databases-in-a-sql-server-instance/

SET NOCOUNT ON;

DECLARE @Database TABLE (DbName SYSNAME);
DECLARE @DbName AS SYSNAME;
DECLARE @sql AS VARCHAR(MAX);
DECLARE @ServerName AS SYSNAME;

SET @ServerName = (
        SELECT @@SERVERNAME
        );

IF OBJECT_ID(N'tempdb..#User') IS NOT NULL
BEGIN
    DROP TABLE #User
END;

CREATE TABLE #User (
    ServerName SYSNAME
    ,DbName SYSNAME
    ,UserName SYSNAME NULL
    ,LoginType VARCHAR(255) NULL
    ,Permission VARCHAR(255) NULL
    ,StateOf VARCHAR(255) NULL
    ,AccessLevel VARCHAR(255) NULL
    ,ObjectName SYSNAME NULL
    );

SET @DbName = '';

INSERT INTO @Database (DbName)
SELECT NAME
FROM master.dbo.sysdatabases
WHERE NAME <> 'tempdb'
ORDER BY NAME ASC;

WHILE @DbName IS NOT NULL
BEGIN
    SET @DbName = (
            SELECT MIN(DbName)
            FROM @Database
            WHERE DbName > @DbName
            )
    /*
    PUT CODE HERE
    */
    SET @sql = '
INSERT INTO #User (
    ServerName
    ,DbName
    ,UserName
    ,LoginType
    ,Permission
    ,StateOf
    ,AccessLevel
    ,ObjectName
    )
SELECT ''' + @ServerName + ''' AS ServerName
    ,''' + @DbName + ''' AS DbName
    ,princ.name AS UserName
    ,princ.type_desc AS LoginType
    ,perm.permission_name AS Permission
    ,perm.state_desc AS StateOf
    ,perm.class_desc AS AccessLevel
    ,object_name(perm.major_id) AS ObjectName
FROM ' + QUOTENAME(@DbName) + '.sys.database_principals princ
LEFT JOIN ' + QUOTENAME(@DbName) + '.sys.database_permissions perm ON perm.grantee_principal_id = princ.principal_id
'

    EXEC (@sql)
END;

SELECT *
FROM #User;

DROP TABLE #User;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...