2013-10-21 38 views
0

有沒有辦法在SQL Server上的數據庫中找到特定的用戶帳戶?在SQL Server數據庫中查找用戶帳戶?

通常情況下,您可以將帳戶添加到SQL Server,此時您還可以將用戶映射到該服務器上的多個數據庫。只要沒有人做壞事,您可以返回到服務器上的帳戶屬性,查看帳戶映射到的數據庫。

但是,如果帳戶存在於數據庫中,則此連接可能很容易中斷,但它不會在服務器級別顯示爲映射到該數據庫。此外,如果服務器上已存在一個帳戶,則無法在其中一個數據庫中創建帳戶,這是我處於的情況。

有100個數據庫,我需要找到該用戶帳戶的數據庫據我所知,sys.database_principals我們每個數據庫都是唯一的。是否可以爲一個帳戶進行跨數據庫搜索並返回它存在的數據庫?

回答

0

以下是一些幫助查詢。

聲明@returnValue詮釋 EXEC @returnValue =的sp_change_users_login 'Update_One', 'SXAUtil', 'SXAUtil' 打印 '/ @的returnValue /' 打印@returnValue 打印 ''

select * from master..syslogins where name='MyUser001' 


select * from [MyDatabase001]..sysusers where name='MyUser001' 


select 1 as 'Match??' , mastSysLogin.sid as mastSysLogin_Sid, localSysLogin.sid as localSysLogin_Sid, mastSysLogin.name as mastSysLogin_Name , localSysLogin.name as localSysLogin_Name from master..syslogins mastSysLogin join [MyDatabase001]..sysusers localSysLogin on mastSysLogin.sid = localSysLogin.sid 
where mastSysLogin.name='MyUser001' 
go 

此過程我認爲不贊成,但研究它會顯示一些「缺失的鏈接」信息。

Use MyDatabase001 
GO 

declare @returnValue int 
EXEC @returnValue = sp_change_users_login 'Update_One', 'MyUser001', 'MyUser001' 
print '/@returnValue/' 
print @returnValue 
print '' 

下面是我寫的腳本,用於將用戶添加到登錄名和dbusers並映射到某些角色。

它使用SQLCMD模式。但是,隨着我試圖編寫代碼來創建用戶,這是一個「多年」的努力,如果用戶已經添加,它不會引發錯誤。

/* 

--SqlCmd Notes: 

--Remove comments and space between ":" and "setvar" to run in sqlcmd mode. 

--!!! Checked in code MUST *recomment out* the setvars below !!! (Putting a space between the ":" and the "setvar" is sufficient) 
--  (This is not preferred behavior, the issue has been reported at http://connect.microsoft.com/SQLServer/feedback/details/382007/in-sqlcmd-scripts-setvar-should-have-a-lower-precedence-than-command-line-variable-assignments) 


: setvar ErrorOutputFileFromCommandLine "c:\wuwutemp\sqlcommmanderrorfile.txt" 
: setvar DBNAME "MyDatabaseName" 
: setvar DBUSERNAME "MyDomain\someDomainUserThatExists" 

*/ 




Use [$(DBNAME)] 
GO 

:Error $(ErrorOutputFileFromCommandLine) 





declare @databaseName varchar(64) 
select @databaseName = db_name() 


print '/@databaseName/' 
print @databaseName 
print '' 

set nocount on 


declare @CONST_DB_DATAREADER_ROLE varchar(64) 
select @CONST_DB_DATAREADER_ROLE = 'db_datareader' 

declare @CONST_DB_BACKUPOPERATOR_ROLE varchar(64) 
select @CONST_DB_BACKUPOPERATOR_ROLE = 'db_backupoperator' 


declare @UserNameHolder table (IdentityID int identity(101,1) , DatabaseName varchar(128) , LoginName varchar(256) , MassagedLoginName varchar(264) , RoleName varchar(64) not null , AlreadyProcessed bit default 0 not null) 

INSERT INTO @UserNameHolder (DatabaseName , LoginName , RoleName) values ('$(DBNAME)' , '$(DBUSERNAME)' , @CONST_DB_DATAREADER_ROLE) 
--INSERT INTO @UserNameHolder (DatabaseName , LoginName , RoleName) values ('$(DBNAME)' , '$(DBUSERNAME)' , @CONST_DB_BACKUPOPERATOR_ROLE) 





/* Below this line is "common logic code" */ 








Update @UserNameHolder Set MassagedLoginName = LoginName 

    /* 
     sp_grantlogin does NOT like brackets around a domain/user 
     example : EXEC sp_grantlogin @loginame = N'[MyDomain\MyUser]' 
     The "massaging" below is a work around to this issue 
    */ 

Update @UserNameHolder Set MassagedLoginName = RIGHT(MassagedLoginName , LEN(MassagedLoginName) -1) where LEN(MassagedLoginName)>0 AND LEFT(MassagedLoginName,1)='[' 
Update @UserNameHolder Set MassagedLoginName = LEFT(MassagedLoginName , LEN(MassagedLoginName) -1) where LEN(MassagedLoginName)>0 AND RIGHT(MassagedLoginName,1)=']' 

/* Use a iffy rule to figure out NT Names */ 
--Update @UserNameHolder Set IsNTName = 1 where LEN(LoginName)>0 AND LEFT(LoginName,1)='[' AND RIGHT(LoginName,1)=']' 

-- public is built in, do not process it 
Update @UserNameHolder Set AlreadyProcessed = 1 where UPPER(LoginName) = UPPER('public') 


select * from @UserNameHolder 



declare @CurrentIdentityID int 
declare @CurrentLoginName varchar(256) 
declare @CurrentMassagedLoginName varchar(256) 
declare @CurrentDatabaseName varchar(64) 
--declare @CurrentIsNTName bit 
declare @CurrentRoleName varchar(64) 

declare @sp_grantdbaccess_return_value_total int 
select @sp_grantdbaccess_return_value_total = 0 



declare @sp_addrolemember_return_value_total int 
select @sp_addrolemember_return_value_total = 0 


while exists (select null from @UserNameHolder where AlreadyProcessed = 0) 
begin 
     select @CurrentIdentityID = (select top 1 IdentityID from @UserNameHolder where AlreadyProcessed = 0) 

     print '@CurrentIdentityID' 
     print @CurrentIdentityID 
     print '' 

     select @CurrentLoginName = (select top 1 LoginName from @UserNameHolder where IdentityID = @CurrentIdentityID) 
     select @CurrentMassagedLoginName = (select top 1 MassagedLoginName from @UserNameHolder where IdentityID = @CurrentIdentityID) 
     select @CurrentDatabaseName = (select top 1 DatabaseName from @UserNameHolder where IdentityID = @CurrentIdentityID) 
     --select @CurrentIsNTName = (select top 1 IsNTName from @UserNameHolder where IdentityID = @CurrentIdentityID)  
     select @CurrentRoleName = (select top 1 RoleName from @UserNameHolder where IdentityID = @CurrentIdentityID)  




     print '@CurrentLoginName' 
     print @CurrentLoginName 
     print '' 
     print '@CurrentMassagedLoginName' 
     print @CurrentMassagedLoginName 
     print '' 
     print '@CurrentDatabaseName' 
     print @CurrentDatabaseName 
     print ''  
     --print '@CurrentIsNTName' 
     --print @CurrentIsNTName 
     --print '' 
     print '@CurrentRoleName' 
     print @CurrentRoleName 
     print ''    


     if(1=1) /* 1=1 is helpful while debugging, set to 1=2 to exclude */ 
     begin   

      -- select name, loginname from master.dbo.syslogins where loginname = @currentLoginName and isntname = 1) 
      if not exists (select null from master.dbo.syslogins where UPPER(loginname) = UPPER(@CurrentLoginName)) -- and isntname = 1) 
      begin 
       print 'About to execute sp_grantlogin for user:' 
       print @CurrentMassagedLoginName 
       EXEC sp_grantlogin @loginame = @CurrentMassagedLoginName 
       print '' 
       print '' 
       print 'About to execute sp_defaultdb for user:' 
       print @CurrentMassagedLoginName 
       EXEC sp_defaultdb @loginame = @CurrentMassagedLoginName , @defdb = @CurrentDatabaseName 
       print '' 
       print '' 
      end 
      else 
      begin 
       print 'NOT EXECUTED : sp_grantlogin' 
       print 'NOT EXECUTED : sp_defaultdb'    
      end 

     end 

      ---------------------------------------- 



      declare @sp_grantdbaccess_return_value int 
      declare @sp_change_users_login_return_value int 

      declare @needToRunThisIteration bit 
      select @needToRunThisIteration = 0 


      -- declare @currentLoginName varchar(64) 

      if(1=1) /* 1=1 is helpful while debugging, set to 1=2 to exclude */ 
      begin 
       if not exists 
        (
         select * from master.dbo.syslogins ml inner join dbo.sysusers 
         su on ml.sid = su.sid where 
          su.uid < 6382 
          and 
          UPPER(ml.name) = UPPER(@CurrentMassagedLoginName) 

        ) 

        begin 
          if not exists 
           (
            /* NOTE, this database name variable must be updated if copying/pasting 'common logic code' between database deployments (NEED_TO_REPLACE_A_VALUE) */ 
            select * from master.dbo.syslogins ml Where 
             UPPER(ml.name) = UPPER(@CurrentMassagedLoginName) 
             and UPPER(ml.dbname) = UPPER('$(DBNAME)') 

           ) 

           begin 
             select @needToRunThisIteration = 1 
           end 
        end 


        if not exists 
         (
          /* NOTE, this database name variable must be updated if copying/pasting 'common logic code' between database deployments (NEED_TO_REPLACE_A_VALUE) */ 
          select * FROM [$(DBNAME)]..sysusers su Where 
           UPPER(su.name) = UPPER(@CurrentMassagedLoginName) 
         ) 

         begin 
           select @needToRunThisIteration = 1 
         end     


         /* 
           Debug 

           select dbname , loginname , * from master.dbo.syslogins ml where dbname != 'master' order by 1 , 2 

           select * FROM TPA2Report..sysusers su 



         */     

       declare @stringNameMatchesButNotSid bit 
       select @stringNameMatchesButNotSid = 0 

       IF EXISTS (
           SELECT dbUsers.name as NameToFix , * 
           FROM sys.sysusers dbUsers 
           join sys.syslogins sqlServerLogins on UPPER(dbUsers.name) = UPPER(sqlServerLogins.name) 
           WHERE dbUsers.sid != sqlServerLogins.sid 
           and UPPER(dbUsers.name) = UPPER(@CurrentMassagedLoginName) 
          ) 
        begin 
          select @stringNameMatchesButNotSid = 1 
        end 



       if (@needToRunThisIteration!=0) 

        begin 

         if @stringNameMatchesButNotSid = 0 
          begin 

            print 'About to execute sp_grantdbaccess for user:' 
            print @CurrentMassagedLoginName 
            exec @sp_grantdbaccess_return_value = sp_grantdbaccess @CurrentMassagedLoginName 
            print '' 
            print '@sp_grantdbaccess_return_value' 
            print @sp_grantdbaccess_return_value 
            print ''     

            select @sp_grantdbaccess_return_value_total = @sp_grantdbaccess_return_value_total + @sp_grantdbaccess_return_value 
          end 
         else 
          begin 
            /* There is a mismatched "sid" issue, but with the same names. This will address the issue. */         

            print 'About to execute sp_change_users_login for user:' 
            print @CurrentMassagedLoginName 
            EXEC @sp_change_users_login_return_value = sp_change_users_login @Action='update_one', @[email protected],@[email protected];      
            print '' 
            print '@sp_change_users_login_return_value' 
            print @sp_change_users_login_return_value 
            print ''           

          end 
        end 
      end 



      -------------------------------------------------------      


      declare @sp_addrolemember_return_value int 

      if(1=1) /* 1=1 is helpful while debugging, set to 1=2 to exclude */ 
      begin 

       if not exists 
       (
       SELECT null --, role_principal_id, member_principal_id, princ1.name AS 
       role_name, princ2.name As member_name 
       FROM sys.database_role_members AS S LEFT JOIN sys.database_principals AS 
       princ1 ON S.role_principal_id = princ1.principal_id AND princ1.type = 'R' 
       LEFT JOIN sys.database_principals AS princ2 ON S.member_principal_id = 
       princ2.principal_id AND princ2.type IN ('S', 'U') 
       WHERE princ1.name = @CurrentRoleName and UPPER(princ2.name) = UPPER(@CurrentMassagedLoginName) 
       ) 
       begin 


        print 'About to execute sp_grantdbaccess for user:' 
        print @CurrentMassagedLoginName 
        print 'For the role:' 
        print @CurrentRoleName 
        exec @sp_addrolemember_return_value = sp_addrolemember @CurrentRoleName, @CurrentMassagedLoginName 
        print '' 
        print '@sp_addrolemember_return_value' 
        print @sp_addrolemember_return_value 
        print '' 

        select @sp_addrolemember_return_value_total = @sp_addrolemember_return_value_total + @sp_addrolemember_return_value 

       end 

      end 



     Update @UserNameHolder Set AlreadyProcessed = 1 Where IdentityID = @CurrentIdentityID 
end 




print '/@sp_grantdbaccess_return_value_total/' 
print @sp_grantdbaccess_return_value_total 

print '/@sp_addrolemember_return_value_total/' 
print @sp_addrolemember_return_value_total 




GO