Sql server 如何获取所有实例数据库的用户列表
我想程序应该是这样的:Sql server 如何获取所有实例数据库的用户列表,sql-server,database,list,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
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不起作用。我总是得到当前所选数据库的用户列表。我该如何解决这个问题
备注:我希望此代码在2000和2005 sql Server上都能运行。您也可以使用未记录但使用良好的sp_MSforeachdb存储过程-请参阅或参阅另一个: 那个?是将添加到命令中的数据库名称的占位符,因为它将针对系统中的每个数据库执行。这里是一个很好的查询,如果您没有帐户,这是一个免费注册,也是一个非常好的资源 把所有东西都放在临时表中,然后你可以用它做任何你想做的事情
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
下面介绍如何创建SQL Server实例中所有数据库的所有用户的列表。我想这就是你要找的 如果您想要所有实例的所有数据库的所有用户的列表,您应该能够修改脚本来实现这一点。只需扩展脚本中使用的技术
+1太棒了!我试图找出一种方法,使stee1rat代码以某种方式工作,同时学习,然后你想出了这个强大的sp_MSforeachdb存储过程!谢谢太棒了!非常感谢你!现在,我可以使用一个简单的命令exec sp_msforeachdb'use?;轻松地删除所有数据库中的用户?;exec sp_dropuser testuser123”:我只是想知道为什么这个过程没有文档记录?它非常有用:如果LEFTCASTServerproperty'ProductVersion'作为VARCHAR1,1='9'替换为ELSE,如果LEFTCASTServerproperty'ProductVersion'作为VARCHAR2,2='11',这一行在SQL Server 2012中仍然有效。当然,检查可以更一般化。
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
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;