2010-03-15 34 views
6

我想程序應該是這樣的:如何獲得用戶的列表中的所有實例的數據庫

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(「使用」 + @Db)不起作用。我總是得到當前選擇的數據庫的用戶列表。我應該如何解決這個問題?

P.S .:我希望此代碼可以在2000和2005 SQL Server上工作。

回答

10

你也可以使用無證,但很好用sp_MSforeachdb存儲過程 - 見here for details或看到另一個blog post here

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

的 「?」是將添加到命令中的數據庫名稱的佔位符,因爲它將針對系統中的每個數據庫執行。

+0

+1太棒了!我試圖找出一種方法來使stee1rat代碼以某種方式工作,同時學習,然後你想出了這個宏大的sp_MSforeachdb存儲過程!謝謝! –

+1

這太棒了!非常感謝你!現在,我可以通過使用一個簡單的命令exec sp_msforeachdb'use?'輕鬆地將用戶放在所有數據庫中。 exec sp_dropuser''testuser123''':) 我只是想知道爲什麼這個程序沒有文檔?這很有幫助:) – stee1rat

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 
+0

在ELSE IF LEFT(CAST(ServerProperty('ProductVersion')AS VARCHAR(1)),1)='9''替換爲'ELSE IF LEFT(' CAST(Serverproperty('ProductVersion')AS VARCHAR(2)),2)='11'。 (當然,檢查可以更一般化)。 – knb

相關問題