如何获取所有实例数据库的用户列表

时间:2010-03-15 06:24:33

标签: sql-server database list

我想程序应该是这样的:

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。:我希望这段代码能够在2000和2005 sql服务器上运行。

3 个答案:

答案 0 :(得分:10)

您还可以使用未记录但使用良好的sp_MSforeachdb存储过程 - 请参阅here for details或查看其他blog post here

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

“?”是将添加到命令的数据库名称的占位符,因为它是针对系统中的每个数据库执行的。

答案 1 :(得分:2)

这是来自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

答案 2 :(得分:0)

以下是如何创建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;