sql server:列出每个数据库的用户

6qftjkof  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(527)

我有几个数据库。我想列出database/security/users文件夹中的所有用户,user1和user2,如下所示:

我提出了这个问题:

  1. SELECT name, type_desc
  2. FROM nameOfMyDatabase.sys.database_principals
  3. WHERE name NOT LIKE 'public'
  4. AND name NOT LIKE 'dbo'
  5. AND name NOT LIKE 'guest'
  6. AND name NOT LIKE 'INFORMATION_SCHEMA'
  7. AND name NOT LIKE 'sys'
  8. AND name NOT LIKE 'db%';

它返回我需要的用户,除了数据库中的默认用户。
现在我需要一个查询,它可以对我拥有的所有数据库执行此操作,而不必知道它们的名称或任何关于它们的信息。
我找到了 sp_MSforeachdb ,但不建议多个网站在线使用。但如果这是我唯一的选择,它是怎么工作的?如何在查询的sql语法中引用当前数据库(假设它像一种for each循环一样工作?)

  1. EXEC sp_MSforeachdb 'USE ? SELECT name, type_desc
  2. FROM ''?''.sys.database_principals
  3. Where name not like "public"
  4. and name not like "dbo"
  5. and name not like "guest"
  6. and name not like "INFORMATION_SCHEMA"
  7. and name not like "sys
  8. and name not like "db%"'

(在这段代码中,我使用“”?“”作为对当前数据库的引用,但它返回错误)此外,我只希望在我创建的数据库上运行查询,而不希望在生成的系统数据库(master、model、msdb、tempdb)上运行查询
除了sp\u msforeachdb之外,还有别的方法可以让这个工作吗?

smdncfj3

smdncfj31#

请尝试以下操作

  1. EXEC sp_MSforeachdb '
  2. IF ''?'' NOT IN (''master'',''msdb'',''tempdb'', ''model'')
  3. BEGIN
  4. USE [?]
  5. SELECT name, type_desc
  6. FROM [?].sys.database_principals
  7. WHERE name NOT LIKE ''public''
  8. AND name NOT LIKE ''dbo''
  9. AND name NOT LIKE ''guest''
  10. AND name NOT LIKE ''INFORMATION_SCHEMA''
  11. AND name NOT LIKE ''sys''
  12. AND name NOT LIKE ''db%''
  13. END'
  14. ``` `sp_MsForEachDb` 所以这就是为什么不推荐它。但是,如果您只需要在单个查询中使用它,而不是在生产代码中使用它,请随意使用它。 `?` 被你的数据库名替换,你在哪里失踪了 `[` 以及 `]` 在数据库名称周围。
  15. 您还使用双引号而不是两个单引号。因为在字符串中使用单引号,所以需要使用单引号对其进行转义。
展开查看全部
0pizxfdo

0pizxfdo2#

还有很多其他用户创建的版本 sp_msforeachdb 在外面。我将(无耻地)在这里使用我自己的版本,您可以在这里阅读更多内容:spu msforeachdb的无光标版本。为完整起见,我将包括以下ddl:

  1. USE master;
  2. GO
  3. IF NOT EXISTS (SELECT 1 FROM sys.types WHERE [name] = N'objectlist')
  4. CREATE TYPE dbo.objectlist AS table ([name] sysname);
  5. GO
  6. CREATE OR ALTER PROC sp_foreachdatabase @Command nvarchar(MAX),
  7. @Delimit_Character nchar(1) = N'?', --Character to be replaced with a delimit identified version of the datbaase name I.e. [master]
  8. @Quote_Character nchar(1) = N'&', --Character to be replaced with a single quoted (') version of the datbaase name I.e. 'master'
  9. @Skip_System bit = 0, --Omits master, msdb, tempdb and model. Ignored if @Database_List has data.
  10. @Skip_User bit = 0, --Omits all user databases. Ignored if @Database_List has data.
  11. @Database_List dbo.objectlist READONLY, --If @Skip_System and @Skip_User equal 1, and this is empty, an error will be thrown
  12. @Auto_Use bit = 0, --Automatically starts each command agaisnt a database with a USE
  13. @Exit_On_Error bit = 1, --If an error is occurs against a single database, the command will still be run against the remainder. Otherwise everything is rolled back
  14. --This does not effect the @Pre_Command and @Post_Command statements
  15. @Pre_Command nvarchar(MAX) = NULL, --Command to run before @Command. Does not use Character Replacements. Run against master DB.
  16. @Post_Command nvarchar(MAX) = NULL, --Command to run after @Command. Does not use Character Replacements. Run against master DB.
  17. @Command_Run nvarchar(MAX) = NULL OUTPUT --Returns the generated and replaced command, for trouble shooting
  18. AS BEGIN
  19. --Do some checking of passed values first
  20. --Check that @Skip_System, @Skip_User aren't both 0 or that @Database_List has some rows
  21. IF (@Skip_System = 1 AND @Skip_User = 1 AND NOT EXISTS (SELECT 1 FROM @Database_List))
  22. THROW 62401, N'System and User databases cannot be skipped if a Database List is not supplied.', 16;
  23. IF @Delimit_Character IS NULL
  24. THROW 62402, N'@Delimit_Replace cannot have a value of NULL.', 16;
  25. IF @Quote_Character IS NULL
  26. THROW 62403, N'@Quoted_Replace cannot have a value of NULL.', 16;
  27. IF @Skip_User IS NULL
  28. THROW 62404, N'@Skip_User cannot have a value of NULL.', 16;
  29. IF @Skip_System IS NULL
  30. THROW 62405, N'@Skip_System cannot have a value of NULL.', 16;
  31. IF @Auto_Use IS NULL
  32. PRINT N'@Auto_Use has a value of NULL. Behaviour will be as if the value is 0.';
  33. DECLARE @CRLF nchar(2) = NCHAR(13) + NCHAR(10);
  34. DECLARE @RC int;
  35. --Add the Pre Command to the batch
  36. SET @Command_Run = ISNULL(N'/* --- Pre Command Begin. --- */' + @CRLF + @CRLF + N'USE master;' + @CRLF + @CRLF + @Pre_Command + @CRLF + @CRLF + N'/* --- Pre Command End. --- */', N'');
  37. --Get the databases we need to deal with
  38. --As @Database_List might be empty and it's READONLY, and we're going to do the command in database_id order we need another variable.
  39. DECLARE @DBs table (database_id int,
  40. database_name sysname);
  41. IF EXISTS (SELECT 1 FROM @Database_List)
  42. INSERT INTO @DBs (database_id,database_name)
  43. SELECT d.database_id,
  44. d.[name]
  45. FROM sys.databases d
  46. JOIN @Database_List DL ON d.[name] = DL.[name];
  47. ELSE
  48. INSERT INTO @DBs (database_id,database_name)
  49. SELECT d.database_id,
  50. d.[name]
  51. FROM sys.databases d
  52. WHERE (d.database_id <= 4 AND @Skip_System = 0) OR (d.database_id > 4 AND @Skip_User = 0);
  53. SET @Command_Run = @Command_Run + @CRLF + @CRLF +
  54. N'/* --- Begin command for each database. --- */' + @CRLF + @CRLF +
  55. CASE WHEN @Exit_On_Error = 0 THEN N'--Turning XACT_ABORT off due to @Exit_On_Error parameter' + @CRLF + @CRLF + N'SET XACT_ABORT OFF;' + @CRLF + N'DECLARE @Error nvarchar(4000);' ELSE N'SET XACT_ABORT ON;' END +
  56. (SELECT @CRLF + @CRLF +
  57. N'/* --- Running @Command against database ' + QUOTENAME(DB.database_name,'''') + N'. --- */' + @CRLF + @CRLF +
  58. CASE WHEN @Auto_Use = 1 THEN N'USE ' + QUOTENAME(DB.database_name) + N';' + @CRLF + @CRLF ELSE N'' END +
  59. N'BEGIN TRY' + @CRLF + @CRLF +
  60. REPLACE(REPLACE(@Command, @Delimit_Character, QUOTENAME(DB.database_name)),@Quote_Character, 'N' + QUOTENAME(DB.database_name,'''')) + @CRLF + @CRLF +
  61. 'END TRY' + @CRLF +
  62. N'BEGIN CATCH' + @CRLF +
  63. CASE WHEN @Exit_On_Error = 0 THEN N' SET @Error = N''The following error occured during the batch, but has been skipped:'' + NCHAR(13) + NCHAR(10) + ' + @CRLF +
  64. N' N''Msg '' + CONVERT(nvarchar(6),ERROR_NUMBER()) + '', Level '' + CONVERT(nvarchar(6),ERROR_SEVERITY()) + '', State '' + CONVERT(nvarchar(6),ERROR_STATE()) + '', Line '' + CONVERT(nvarchar(6),ERROR_LINE()) + NCHAR(13) + NCHAR(10) +' + @CRLF +
  65. N' ERROR_MESSAGE();' + @CRLF +
  66. N' PRINT @Error;' + @CRLF +
  67. N' SET @RC = ERROR_NUMBER();'
  68. ELSE N' THROW;'
  69. END + @CRLF +
  70. N'END CATCH;' + @CRLF +
  71. N'/* --- Completed @Command against database ' + QUOTENAME(DB.database_name,'''') + N'. --- */'
  72. FROM @DBs DB
  73. FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)') + @CRLF + @CRLF +
  74. CASE WHEN @Exit_On_Error = 0 THEN N'--Turning XACT_ABORT back on due to @Exit_On_Error parameter' + @CRLF + @CRLF + N'SET XACT_ABORT ON;' ELSE N'' END;
  75. SET @Command_Run = @Command_Run + ISNULL(@CRLF + @CRLF + N'/* --- Post Command Begin. --- */' + @CRLF + @CRLF + N'USE master;' + @CRLF + @CRLF + @Post_Command + @CRLF + @CRLF + N'/* --- Post Command End. --- */', N'');
  76. EXEC sp_executesql @Command_Run, N'@RC int OUTPUT', @RC = @RC;
  77. SET @RC = ISNULL(@RC, 0);
  78. RETURN @RC;
  79. END;
  80. GO

如果需要,可以将其添加为系统对象;我在这篇文章中谈到了如何做。
输入后,可以进行查询,并根据需要输入替换字符:

  1. USE master;
  2. GO
  3. DECLARE @SQL nvarchar(MAX),
  4. @CRLF nchar(2) = NCHAR(13) + NCHAR(10);
  5. SET @SQL = N'SELECT & AS databasename, name, type_desc' + @CRLF + --& by default injects the database's name in quotes ('') and a N prefix
  6. N'FROM ?.sys.database_principals' + @CRLF + --? by default injects the database's name in brackets ([])
  7. N'WHERE name NOT LIKE ''public''' + @CRLF +
  8. N' AND name NOT LIKE ''dbo''' + @CRLF +
  9. N' AND name NOT LIKE ''guest''' + @CRLF +
  10. N' AND name NOT LIKE ''INFORMATION_SCHEMA''' + @CRLF +
  11. N' AND name NOT LIKE ''sys''' + @CRLF +
  12. N' AND name NOT LIKE ''db%'';';
  13. DECLARE @CommandRun nvarchar(MAX);
  14. EXEC sp_foreachdatabase @Command = @SQL, --The above SQL is the command to run
  15. @Skip_system = 1, --Skips system databases
  16. @Auto_Use = 1, --Automatically puts a USE at the start of each database
  17. @Command_Run = @CommandRun OUTPUT; --For debugging
  18. PRINT @CommandRun;
  19. GO
展开查看全部

相关问题