web-dev-qa-db-ja.com

すべてのインスタンスのデータベースのユーザーのリストを取得するにはどうすればよいですか?鏡を除く!

MSSQLデータベースの監査のために、各インスタンスで実行されている各データベースのすべてのユーザーのリストを提供するように求められました。

既存のs tackオーバーフローの質問があります

使用することをお勧めします...

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

ただし、いくつかの問題が発生します。

1)いずれかのデータベースがミラーである場合、スクリプトは以下のようにエラーになり、結果を返しません。

"The database "###" cannot be opened. It is acting as a mirror database."

2)データベースの名前に特殊文字(ハイフン-など)が含まれている場合、エラーが発生し、結果が返されません。

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '-'.

3)結果はすべて別の表にあります。理想的には、データベースとユーザーの1つのテーブルを出力するだけです。

誰かがコードを調整して上記を達成するのを手伝ってくれる?

ありがとう

4
anon2002

sp_MSforeachdbは文書化されておらず、サポートされておらず、重大な欠点がいくつかあります。他のものを使用する必要があります。独自のカーソルをsys.databases、 このようなもの:

declare c cursor local for
    select name 
    from sys.databases d
    where name not in ('master','model','tempdb') 
    and d.state=0
declare @db sysname

open c
fetch next from c into @db
while @@fetch_status = 0
begin
  begin try
     declare @sql nvarchar(max) = concat(  N'use ', quotename(@db), N'; 
     select db_name() db, * 
     from sys.database_principals u
     where type = ''U''' 
     )

     --print @sql
     exec ( @sql )

  end try
  begin catch
    print error_message()
  end catch

  fetch next from c into @db
end

close c
deallocate c

または他の誰かのコピー、例えば here