Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在跨服务器备份/恢复后维护SQL Server 2008数据库的登录功能?_Sql_Database_Sql Server 2008_Database Backups_Database Administration - Fatal编程技术网

如何在跨服务器备份/恢复后维护SQL Server 2008数据库的登录功能?

如何在跨服务器备份/恢复后维护SQL Server 2008数据库的登录功能?,sql,database,sql-server-2008,database-backups,database-administration,Sql,Database,Sql Server 2008,Database Backups,Database Administration,我需要经常使用备份/恢复过程在服务器之间传输数据库。我遇到了一个问题,在恢复时没有维护登录信息,我希望防止这种情况发生 详情如下: 共有3台服务器,每台服务器运行一个SQL Server 2008 Express实例 我在这3台服务器之间传输数据库内容 我通过使用源数据库上的“备份”选项和目标数据库上的“还原”选项来传输数据库内容 恢复时,我使用选项覆盖现有数据库(替换) 每个服务器上的数据库名称都可以相同(尽管当前其中一个服务器上的名称略有不同。它们分别命名为xxx.mydatabase和l

我需要经常使用备份/恢复过程在服务器之间传输数据库。我遇到了一个问题,在恢复时没有维护登录信息,我希望防止这种情况发生

详情如下:

  • 共有3台服务器,每台服务器运行一个SQL Server 2008 Express实例
  • 我在这3台服务器之间传输数据库内容
  • 我通过使用源数据库上的“备份”选项和目标数据库上的“还原”选项来传输数据库内容
  • 恢复时,我使用选项覆盖现有数据库(替换)
  • 每个服务器上的数据库名称都可以相同(尽管当前其中一个服务器上的名称略有不同。它们分别命名为xxx.mydatabase和local.mydatabase)
  • SQL Express的每个实例都有一个安全登录名“MyDatabaseUser”
  • 每个数据库都有一个名为“MyDatabaseUser”的用户
使用此方法移动数据库后,正确的用户名仍会显示在预期位置,但与安全登录相关联的用户映射已被删除。服务器的安全登录和数据库的用户不再连接,应用程序在尝试登录时失败

通过从数据库中删除用户并将用户映射重新添加到安全登录,手动解决此问题非常容易。但是,如果经常这样做,则会非常烦人。除了烦人之外,需要手动重新映射此信息还会导致短暂的停机时间。我可以很快完成,但必须有更好的方法,可以进一步减少这一点

我想使用备份/还原选项并保留用户映射。我不熟悉所有备份/恢复选项及其功能。我可以使用哪些设置来完成此操作

我可以完全访问服务器和登录,如果需要的话,我可以进行更改。虽然我最希望使用备份/恢复选项,但我也愿意运行包、查询、脚本、创建/使用和外部程序,或者任何可以完成此任务的操作。主要目标是将数据库传输过程中所需的步骤和出错的可能性降至最低。

将所有SQL用户(我是指登录名)置于sysadmin角色。
或者,您需要将登录重新映射到用户

EXEC sp_change_users_login 'Auto_Fix', 'user'
其中语法如下:

EXEC sp_change_users_login 'UserName', 'LoginName'
我是这样做的:

        public override void RemapDbUserLogins(string DbName)
        {
            string strSQL = @"
USE " + EscapeDbName(DbName) + @";

DECLARE @__DatabasePrincipal sysname --nvarchar(128) 
DECLARE @__ServerPrincipal sysname --nvarchar(128) 

DECLARE @__CurPrincipals CURSOR

SET @__CurPrincipals = CURSOR FOR
(
    -- sysname: nvarchar(128)
    -- Get Login for user 
    SELECT 
         dp.name AS user_name 
        --,sp.name AS login_name 

        ,
        CASE 
            WHEN sp.name IS NULL 
                THEN
                    CASE 
                        WHEN 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = dp.name COLLATE Latin1_General_CI_AS)
                            THEN dp.name 
                        WHEN dp.name LIKE '%[_]DE' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 3) COLLATE Latin1_General_CI_AS)
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 3) 
                        WHEN dp.name LIKE '%DE' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 2) COLLATE Latin1_General_CI_AS)
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 2) 

                        WHEN dp.name LIKE '%[_]EN' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 3) COLLATE Latin1_General_CI_AS)
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 3) 
                        WHEN dp.name LIKE '%EN' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 2) COLLATE Latin1_General_CI_AS) 
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 2) 

                        WHEN dp.name LIKE '%[_]FR' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 3) COLLATE Latin1_General_CI_AS)
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 3) 
                        WHEN dp.name LIKE '%FR' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 2) COLLATE Latin1_General_CI_AS) 
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 2) 

                        WHEN dp.name LIKE '%[_]IT' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 3) COLLATE Latin1_General_CI_AS)
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 3) 
                        WHEN dp.name LIKE '%IT' AND 1 = (SELECT COUNT(*) FROM sys.server_principals  AS spSubSel WHERE spSubSel.name = SUBSTRING(dp.name, 1, LEN(dp.name) - 2) COLLATE Latin1_General_CI_AS) 
                            THEN SUBSTRING(dp.name, 1, LEN(dp.name) - 2) 

                        --ELSE 'foo' + SUBSTRING(dp.name, 1, LEN(dp.name) - 3)
                        --ELSE N'ApertureWebServices' 
                        ELSE NULL --COLLATE Latin1_General_CI_AS
                    END 
            ELSE sp.name COLLATE Latin1_General_CI_AS
        END AS CorrespondingUser 

    FROM sys.database_principals AS dp 

    LEFT JOIN sys.server_principals  AS sp 
        ON sp.sid = dp.sid 

    WHERE dp.type_desc = 'SQL_USER' 
    AND dp.sid IS NOT NULL 
    AND dp.sid != 0 

    AND sp.name IS NULL -- WHERE sids don't match 

)
OPEN @__CurPrincipals
    FETCH NEXT FROM @__CurPrincipals INTO @__DatabasePrincipal, @__ServerPrincipal 
    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT @__DatabasePrincipal + N' = ' + @__ServerPrincipal 

        --EXEC sp_helptext 'sp_change_users_login' 

        DECLARE @Action varchar(10) -- REPORT / UPDATE_ONE / AUTO_FIX 
        DECLARE @UserNamePattern sysname  = NULL 
        DECLARE @LoginName sysname  = NULL 
        DECLARE @Password sysname  = NULL 


        SET @Action = 'Update_One' 
        SET @UserNamePattern = @__DatabasePrincipal -- N'ApertureWebServicesDE' 
        SET @LoginName = @__ServerPrincipal -- N'ApertureWebServices' 

        IF @LoginName IS NOT NULL
        BEGIN
            PRINT 'EXECUTE sp_change_users_login @Action = ''' + @Action + N''', @UserNamePattern = ''' + @UserNamePattern + N''', @LoginName = ''' + @LoginName + N''', @Password = ' + ISNULL(N'''' + @Password + N'''', N'NULL') 
            EXECUTE sp_change_users_login @Action, @UserNamePattern, @LoginName, @Password 
        END
        ELSE 
        BEGIN 
            PRINT N'Ignored user ' + @UserNamePattern
        END 
    FETCH NEXT FROM @__CurPrincipals INTO @__DatabasePrincipal, @__ServerPrincipal 
    END
CLOSE @__CurPrincipals
DEALLOCATE @__CurPrincipals
";

            ExecuteWithoutTransaction(strSQL);
        } // End Sub RemapDbUserLogins

很好的答案和一些好的SQL。我做了测试,这些都很好。我很感激。我对您回答的第一行“将所有SQL用户放入sysadmin角色”有一个问题。这是否意味着我可以通过将断开连接的用户设置为系统管理员角色来防止连接断开?@RacerNerd:是的,这正是它的意思,但也意味着该用户将拥有系统管理员权限。