0

以下のスクリプトがあり、システム データベースを除くデータベースの動的リストに対してこれを実行できるようにしたいと考えています。それは簡単です。注意が必要なのは、修正コマンドを実行する対象となるユーザーのリストがデータベースごとに異なる可能性があることです。これは 3 番目のカーソルでしょうか? 以下の私の試みは、各データベースのユーザーを適切に入力していません。どんな助けでも大歓迎です。

SET nocount ON
GO
SET QUOTED_IDENTIFIER OFF
GO
--
-- Declare and define variables
--

DECLARE @databasename VARCHAR(50) -- database name
DECLARE @sqlcommand nvarchar(256) -- SQL Command generated

-- 範囲内のデータベース名を @name に含めます

DECLARE db_cursor CURSOR FOR
  SELECT NAME
  FROM   master.dbo.sysdatabases
  WHERE  NAME NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'DBATools' ) -- don't include the databases
OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @databasename

WHILE @@FETCH_STATUS = 0
  BEGIN
      PRINT 'Fixing Logins for '
            + Cast(@databasename AS VARCHAR)

      DECLARE curSQL CURSOR FOR
        SELECT "USE " + ( @databasename ) + ";" + " exec sp_change_users_login 'AUTO_FIX','" + NAME + "'"

      SELECT NAME
      FROM   sys.sysusers
      WHERE  issqluser = 1
             AND NAME NOT IN ( 'dbo', 'guest', 'INFORMATION_SCHEMA', 'sys' )

      OPEN curSQL

      FETCH curSQL INTO @sqlcommand

      WHILE @@FETCH_STATUS = 0
        BEGIN
            PRINT @sqlcommand
            EXEC (@sqlcommand)
            FETCH curSQL INTO @sqlcommand
        END

      CLOSE curSQL
      DEALLOCATE curSQL

      FETCH NEXT FROM db_cursor INTO @databasename
  END

CLOSE db_cursor

DEALLOCATE db_cursor 
4

2 に答える 2

0

または、カーソルなしで実行できます。

DECLARE @Output NVARCHAR(MAX)
SET @Output = ''

SELECT @Output = @Output +
'--Fixing Logins For ' + name + CHAR(10) + 
'USE ' + name + CHAR(10) + 
'EXEC sp_change_users_login ''AUTO_FIX'','''+
(
    SELECT  b.name 
    FROM   sys.sysusers as b
    WHERE  issqluser = 1
    AND b.name NOT IN ( 'dbo', 'guest', 'INFORMATION_SCHEMA', 'sys' )
)
+''''+CHAR(10)+CHAR(10)

FROM  master.dbo.sysdatabases
WHERE  NAME NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'DBATools' )
PRINT @Output
于 2014-10-29T18:02:02.640 に答える
0

手順の主な点は、PHP とは異なり、TSQL では一重引用符と二重引用符を同じ意味で使用できないことです。それで、動的 SQL 文字列を修正しました。

もう1つの小さなことは、カーソル宣言からの切り離されたクエリのようです-あなたのものでは、2番目の宣言にselect句を付けて、from句を伴わずに続けます。そのカーソル。それで、私もそれを修正しました。

DECLARE @databasename SYSNAME, @sqlcommand nvarchar(max)
DECLARE db_cursor CURSOR FOR
    SELECT NAME
    FROM   master.dbo.sysdatabases
    WHERE  NAME NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'DBATools' ) -- don't include the databases
OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @databasename

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT 'Fixing Logins for '
    + Cast(@databasename AS VARCHAR)

    DECLARE curSQL CURSOR FOR
        SELECT 'USE ' + @databasename + ';' + ' exec sp_change_users_login ''AUTO_FIX'',''' + NAME + ''';'
        FROM   sys.database_principals
        WHERE  Type='S'
            AND NAME NOT IN ( 'dbo', 'guest', 'INFORMATION_SCHEMA', 'sys' )

    OPEN curSQL

    FETCH curSQL INTO @sqlcommand

    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT @sqlcommand
        --EXEC (@sqlcommand)
        FETCH curSQL INTO @sqlcommand
    END

    CLOSE curSQL
    DEALLOCATE curSQL

    FETCH NEXT FROM db_cursor INTO @databasename
END

CLOSE db_cursor

DEALLOCATE db_cursor 

編集: コメントごとにテーブルを sys.sysusers ではなく database_principals に切り替えました。

于 2014-10-29T17:13:58.643 に答える