Use Dynamic Query into a fetch cycle - sql-server

I have a many customer databases. I need to execute different type of SELECT queries on each customerDb: each SELECT will extract just one value.
Then I want to put each SELECT result for each CustomerDB in a #tempTable and finally collect all resultset in one-shot for all CustomerDBs in a table like this:
customerDB
value1
value2
value3
customerA
10000
1234
456
customerB
5000
1000
999
customerC
5555
1432
765
I've tried to use the EXEC(#query) to redirect the result into a variable and then use the variabile into an INSERT command but it doesn't work.
Any help???
Here is my script:
DECLARE c_db_names CURSOR FOR SELECT name FROM sys.databases WHERE name NOT IN('master', 'model','msdb','tempdb')
DECLARE #db_name NVARCHAR (150)
DECLARE #ServerName nvarchar(50) = ##SERVERNAME
CREATE TABLE #temp_tb( [serverName] [varchar](50) NULL, [tenantCode] [varchar](10) NULL, [value1] [varchar](10) NULL, [value2] [varchar](10) NULL )
OPEN c_db_names
FETCH c_db_names INTO #db_name
WHILE ##Fetch_Status = 0
BEGIN
DECLARE #firtsQuery NVARCHAR(MAX)
DECLARE #secondQuery NVARCHAR(MAX)
DECLARE #firtsResult NVARCHAR(10)
DECLARE #secondResult NVARCHAR(10)
SELECT #firtsQuery = 'select count(*) FROM [' + #db_name + '].[dbo].table1 where ...'
SELECT #secondQuery = 'select count(*) FROM [' + #db_name + '].[dbo].table2 where ...'
exec #firstResult = (#firtsQuery)
exec #secondResult = (#secondQuery)
INSERT INTO #temp_tb (serverName,tenantCode,value1,value2) VALUES (#ServerName, #db_name, #firstResult, #secondResult)
FETCH c_db_names INTO #db_name
END
CLOSE c_db_names
DEALLOCATE c_db_names
SELECT * FROM #TEMP_TB
DROP TABLE #TEMP_TB

You may want to have a play with something like the below, this goes through each database excluding the ones in the NOT IN.
This example goes through each database making sure we have the right users added.
EXEC sp_MSforeachdb N'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'')
BEGIN
USE [?]
IF USER_ID(''NT AUTHORITY\NETWORK SERVICE'') IS NULL
BEGIN
PRINT ''Using Database '' + DB_NAME()
PRINT ''Creating database user NT AUTHORITY\NETWORK SERVICE''
CREATE USER [NT AUTHORITY\NETWORK SERVICE] FOR LOGIN [NT AUTHORITY\NETWORK SERVICE]
PRINT ''Granting db_owner permission NT AUTHORITY\NETWORK SERVICE''
EXEC sp_addrolemember N''db_owner'', N''NT AUTHORITY\NETWORK SERVICE''
END
END';

Related

Searching for records in Microsoft SQL Server

Is it possible to search for records in Microsoft SQL Server manager?
I mean something like in VS pressing Ctrl-F and searching by word?
There is no way in searching for objects in SQL Server management studio. There are views and tables that can be used to search for objects like:
SELECT * FROM sys.tables WHERE name LIKE '%...%'
To search for tables.
If you mean, searching for data within a table, I need to learn T-SQL.
There are non-free 3rd party tools (ex. Redgate's SQL Search), but I use the proc below. You have to create the proc in every [master] database so it's available server-wide, but you can pass in a search term and an optional database name (otherwise it searches through object definitions in all databases):
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_FindTextOnServer] Script Date: 10/6/2017 3:39:19 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*-----------------------------------------------------------
This procedure will search all or a specified database objects
for the supplied text and return a table with the values
Examples:
EXEC sp_FindTextOnServer 'Billing', 'fcsCore'
EXEC sp_FindTextOnServer 'vJurisdiction'
-----------------------------------------------------------*/
ALTER PROCEDURE [dbo].[sp_FindTextOnServer]
#text VARCHAR(40),
#searchDB VARCHAR(100) = NULL
AS
DECLARE #DisplayText VARCHAR(100),
#sSql VARCHAR(1000),
#line VARCHAR(300),
#char CHAR,
#lineNo INTEGER,
#counter INTEGER,
#AddedRecord BIT,
#dbObjectType VARCHAR(100),
#dbObject VARCHAR(100),
#ObjectBody VARCHAR(7000),
#dbName VARCHAR(100)
SET #DisplayText = #Text
SET #text = '%' + #text + '%'
SET #AddedRecord = 0
CREATE TABLE #SearchResults
(
DBName VARCHAR(100) NOT NULL,
ObjectType VARCHAR(100) NOT NULL,
ObjectName VARCHAR(100) NOT NULL,
Line INT NOT NULL,
Reference VARCHAR(7000) NOT NULL
)
CREATE TABLE #tempSysComments
(
DBName VARCHAR(100),
DBObjectType VARCHAR(100),
DBObject VARCHAR(100),
TextString text
)
--Populate a table with the search results from all databases on the server that include the searched text
SET #sSql = 'USE [?]
SELECT
''?'' AS DBName,
LOWER(REPLACE(o.type_desc, ''_'', '' '')) + '' ('' + RTRIM(type) + '')'' AS DBObjectType,
OBJECT_NAME(sm.object_id) AS DBObject,
CAST(sm.definition AS VARCHAR(7000)) AS TextString
FROM sys.sql_modules AS sm
JOIN sys.objects AS o
ON sm.object_id = o.object_id
WHERE CAST(sm.definition AS VARCHAR(7000)) LIKE ''' + #text + '''
ORDER BY o.type_desc, OBJECT_NAME(sm.object_id)'
IF (#searchDB IS NULL)
BEGIN
INSERT INTO #tempSysComments
EXEC sp_MSFOREachDB #sSql
END
ELSE
BEGIN
SET #sSql = REPLACE(#sSql, '?', #searchDB)
INSERT INTO #tempSysComments
EXEC (#sSql)
END
DECLARE codeCursor CURSOR
FOR
SELECT DBName, DBObjectType, DBObject, TextString
FROM #tempSysComments
WHERE DBName IS NOT NULL
OPEN codeCursor
FETCH NEXT FROM codeCursor INTO #dbName, #dbObjectType, #dbObject, #ObjectBody
IF ##FETCH_STATUS <> 0
BEGIN
PRINT 'Text ''' + #DisplayText + ''' was not found in objects on server ' + ##SERVERNAME
-- Close and release code cursor.
CLOSE codeCursor
DEALLOCATE codeCursor
RETURN
END
-- Search each object within code cursor.
WHILE ##FETCH_STATUS = 0
BEGIN
SET #lineNo = 0
SET #counter = 1
-- Process each line.
WHILE (#counter <> Len(#ObjectBody))
BEGIN
SET #char = SUBSTRING(#ObjectBody, #counter,1)
-- Check for line breaks.
IF (#char = CHAR(13))
BEGIN
SET #lineNo = #lineNo + 1
-- Check if we found the specified text.
IF (PATINDEX(#text, #line) <> 0)
BEGIN
SET #AddedRecord = 1
INSERT #SearchResults
SELECT #dbName, #dbObjectType, #dbObject, #lineNo, LEFT(RTRIM(LTRIM(#line)), 7000)
END
SET #line = ''
END
SET #line = #line + #char
SET #counter = #counter + 1
END
IF (#AddedRecord = 0)
INSERT #SearchResults
SELECT #dbName, #dbObjectType, #dbObject, 0, SUBSTRING(#ObjectBody, 1, 7000)
SET #AddedRecord = 0
FETCH NEXT FROM codeCursor INTO #dbName, #dbObjectType, #dbObject, #ObjectBody
END
-- Close and release cursor.
CLOSE codeCursor
DEALLOCATE codeCursor
-- Return the info.
SELECT DISTINCT DBName, ObjectType, ObjectName, Line, RTRIM(LTRIM(REPLACE(REPLACE(Reference, CHAR(9), ' '), CHAR(13)+CHAR(10), ' '))) AS Reference
FROM #SearchResults
ORDER BY DBName, ObjectType, ObjectName, Line
-- Cleanup.
DROP TABLE #SearchResults
DROP TABLE #tempSysComments
RETURN

SQL Server: executing part of a stored procedure that is in one database against all other databases

I am trying to run this procedure in order to select a bunch of results from multiple tables in another databases and put everything into one temp table. I can only use this one stored procedure and can't put it into another database
I tried using this here, but it didn't work and gave me the error
'Must declare the scalar variable "#lcsqlcmd"'. #lcsqlcmd
I already declared though any help?
EXEC master..sp_MSforeachdb
IF DB_ID(''?'') > 4
BEGIN
INSERT INTO #TempTable
EXECUTE (#lcsqlcmd)
END
The easiest way is to build the actual T-SQL string you want to run on each database and execute that. The other databases have no knowledge of the stored procedure you are trying to run.
The proper syntax in your case would be something like this.
CREATE TABLE #TempTable( [DBID] INT, DBName SYSNAME )
DECLARE #ForEachCommand VARCHAR( MAX ), #lcsqlcmd VARCHAR( MAX )
SET #lcsqlcmd = 'USE [?]; SELECT DB_ID() AS [DBID], DB_NAME( DB_ID()) AS DBName'
SET #ForEachCommand =
'IF DB_ID(''?'') > 4
BEGIN
insert into #TempTable
EXEC sp_executesql N''' + #lcsqlcmd + '''
end'
print #ForEachCommand
EXECUTE master.sys.sp_MSforeachdb #ForEachCommand
SELECT * FROM #TempTable
See: http://weblogs.sqlteam.com/joew/archive/2008/08/27/60700.aspx
Note: generally it is not a good idea to build your code around undocumented procedures.
The code that does not use undocumented procedure is below:
SELECT database_id, name AS DBName
INTO #Databases
FROM sys.databases WHERE database_id > 4
CREATE TABLE #TempTable( [DBID] INT, DBName SYSNAME )
DECLARE #lcsqlcmd NVARCHAR( MAX ), #Command NVARCHAR( MAX )
SET #lcsqlcmd = 'USE [?]; SELECT DB_ID() AS [DBID], DB_NAME( DB_ID()) AS DBName'
DECLARE #DBName SYSNAME
SET #DBName = ( SELECT TOP 1 DBName FROM #Databases ORDER BY DBName )
WHILE NOT #DBName IS NULL
BEGIN
SET #Command = REPLACE( #lcsqlcmd, '?', #DBName )
insert into #TempTable
EXEC sp_executesql #Command
SET #DBName = ( SELECT TOP 1 DBName FROM #Databases WHERE DBName > #DBName ORDER BY DBName )
END
SELECT * FROM #TempTable
DROP TABLE #Databases

how Do I list all table names in SQL Server using T-SQL?

SELECT name FROM sys.databases -- this can list all database name in the server
user database
SELECT * FROM INFORMATION_SCHEMA.TABLES
-- these two line can list the table for one particular database
But how can I output the results like below?
Database Table
--------- -------------
db1 t1
db1 t2
db2 t1
... ...
sp_msforeachdb 'select "?" AS db, * from [?].sys.tables'
Here is a stored procedure I use constantly to list all my tables ordered by the space used by them in the database.
GO
/****** Object: StoredProcedure [dbo].[dba_SpaceUsed] Script Date: 03/16/2010 15:09:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[dba_SpaceUsed]
#SourceDB varchar ( 128 ) = null -- Optional database name
-- If omitted, the current database is reported.
, #SortBy char(1) = 'S' -- N for name, S for Size
-- T for table name
AS
SET NOCOUNT ON
DECLARE #sql nvarchar (4000)
IF #SourceDB IS NULL BEGIN
SET #SourceDB = DB_NAME () -- The current DB
END
--------------------------------------------------------
-- Create and fill a list of the tables in the database.
CREATE TABLE #Tables ( [schema] sysname
, TabName sysname )
SELECT #sql = 'insert #tables ([schema], [TabName])
select TABLE_SCHEMA, TABLE_NAME
from ['+ #SourceDB +'].INFORMATION_SCHEMA.TABLES
where TABLE_TYPE = ''BASE TABLE'''
EXEC (#sql)
---------------------------------------------------------------
-- #TabSpaceTxt Holds the results of sp_spaceused.
-- It Doesn't have Schema Info!
CREATE TABLE #TabSpaceTxt (
TabName sysname
, [Rows] varchar (11)
, Reserved varchar (18)
, Data varchar (18)
, Index_Size varchar ( 18 )
, Unused varchar ( 18 )
)
---------------------------------------------------------------
-- The result table, with numeric results and Schema name.
CREATE TABLE #TabSpace ( [Schema] sysname
, TabName sysname
, [Rows] bigint
, ReservedMB numeric(18,3)
, DataMB numeric(18,3)
, Index_SizeMB numeric(18,3)
, UnusedMB numeric(18,3)
)
DECLARE #Tab sysname -- table name
, #Sch sysname -- owner,schema
DECLARE TableCursor CURSOR FOR
SELECT [SCHEMA], TabNAME
FROM #tables
OPEN TableCursor;
FETCH TableCursor into #Sch, #Tab;
WHILE ##FETCH_STATUS = 0 BEGIN
SELECT #sql = 'exec [' + #SourceDB
+ ']..sp_executesql N''insert #TabSpaceTxt exec sp_spaceused '
+ '''''[' + #Sch + '].[' + #Tab + ']' + '''''''';
Delete from #TabSpaceTxt; -- Stores 1 result at a time
EXEC (#sql);
INSERT INTO #TabSpace
SELECT #Sch
, [TabName]
, convert(bigint, rows)
, convert(numeric(18,3), convert(numeric(18,3),
left(reserved, len(reserved)-3)) / 1024.0)
ReservedMB
, convert(numeric(18,3), convert(numeric(18,3),
left(data, len(data)-3)) / 1024.0) DataMB
, convert(numeric(18,3), convert(numeric(18,3),
left(index_size, len(index_size)-3)) / 1024.0)
Index_SizeMB
, convert(numeric(18,3), convert(numeric(18,3),
left(unused, len([Unused])-3)) / 1024.0)
[UnusedMB]
FROM #TabSpaceTxt;
FETCH TableCursor into #Sch, #Tab;
END;
CLOSE TableCursor;
DEALLOCATE TableCursor;
-----------------------------------------------------
-- Caller specifies sort, Default is size
IF #SortBy = 'N' -- Use Schema then Table Name
SELECT * FROM #TabSpace
ORDER BY [Schema] asc, [TabName] asc
ELSE IF #SortBy = 'T' -- Table name, then schema
SELECT * FROM #TabSpace
ORDER BY [TabName] asc, [Schema] asc
ELSE -- S, NULL, or whatever get's the default
SELECT * FROM #TabSpace
ORDER BY ReservedMB desc
;
DROP TABLE #Tables
DROP TABLE #TabSpaceTxt
DROP TABLE #TabSpace
--Thanks to Andrew Novick
if you need one result set, try this:
DECLARE #AllTables table (DatabaseName sysname, TableName sysname)
DECLARE #Current sysname
,#SQL1 varchar(500)
,#SQL2 varchar(500)
,#SQL3 varchar(500)
,#SQL varchar(1500)
SELECT TOP 1 #Current=Name FROM sys.databases Order By Name
SET #SQL1='select db.name, t.TABLE_NAME from '
SET #SQL2='.sys.databases db inner join '
SET #SQL3='.INFORMATION_SCHEMA.TABLES t on db.name = t.TABLE_CATALOG'
WHILE #Current IS NOT NULL
BEGIN
SET #SQL=#SQL1+#Current+#SQL2+#Current+#SQL3
INSERT INTO #AllTables
EXEC (#SQL)
SELECT TOP 1 #Current=Name FROM sys.databases WHERE Name>#Current Order By Name
IF ##ROWCOUNT=0 BREAK
END
SELECT * FROM #AllTables ORDER BY DatabaseName,TableName
If you're lucky enough to still be using sql2000:
CREATE TABLE #AllTables (DatabaseName sysname, TableName sysname)
DECLARE #Current sysname
,#SQL1 varchar(500)
,#SQL2 varchar(500)
,#SQL3 varchar(500)
,#SQL varchar(1500)
SELECT TOP 1 #Current=Name FROM sysdatabases Order By Name
SET #SQL1='select db.name, t.TABLE_NAME from '
SET #SQL2='sysdatabases db inner join '
SET #SQL3='.INFORMATION_SCHEMA.TABLES t on db.name = t.TABLE_CATALOG'
WHILE #Current IS NOT NULL
BEGIN
SET #SQL=#SQL1+#SQL2+#Current+#SQL3
--PRINT #SQL
SET NOCOUNT ON
INSERT INTO #AllTables
EXEC (#SQL)
SET NOCOUNT OFF
SELECT TOP 1 #Current=Name FROM sysdatabases WHERE Name>#Current Order By Name
IF ##ROWCOUNT=0 BREAK
END
SELECT * FROM #AllTables
--where TableName = 'at_errorlog'
ORDER BY DatabaseName,TableName
DROP TABLE #AllTables
select table_name from user_tables;

How to get database and tablenames along

How to get all the database names and corresponding table names together ?
CREATE TABLE #dbs ( DatabaseName VARCHAR(256), TableName VARCHAR(256) )
EXEC sp_msforeachdb 'INSERT INTO #dbs
SELECT ''?'', [name] FROM dbo.SysObjects WHERE XType = ''U'''
SELECT * FROM #dbs
DROP TABLE #dbs
You will have to write a store procedure.
First get the database name
SELECT Name FROM master.sys.databases
For each database
SELECT %DatabaseName%, Name FROM %DatabaseName%.SysObjects WHERE type = 'U'
Edit here's the store procedure
CREATE PROCEDURE sp_GetDatabasesTables
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
CREATE TABLE #schema ( DatabaseName VarChar(50), TableName VarChar(50) );
DECLARE #DatabaseName varchar(50);
DECLARE cursorDatabase CURSOR FOR
SELECT Name FROM master.sys.databases WHERE Name NOT IN ('tempdb'); -- add any table you want to filter here
OPEN cursorDatabase;
-- Perform the first fetch.
FETCH NEXT FROM cursorDatabase INTO #DatabaseName;
-- Check ##FETCH_STATUS to see if there are any more rows to fetch.
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC ('INSERT INTO #schema (DatabaseName, TableName) SELECT ''' + #DatabaseName + ''' AS DatabaseName, Name As TableName FROM ' + #DatabaseName + '.sys.SysObjects WHERE type = ''U'';');
FETCH NEXT FROM cursorDatabase INTO #DatabaseName;
END
CLOSE cursorDatabase;
DEALLOCATE cursorDatabase;
SELECT * FROM #schema
END

Linking ALL Users to Login after restoring a SQL Server 2005 database

(Note this question asks about linking ALL Users, unlike the possible duplicate that asks about linking a single user)
I wish to move a database between two servers, I have backed the database up from the first server and done a database restore on the 2nd server, so far so good.
However our application makes use of a lot of database users that are defined in the database. These have to be linked to logins that are defined in the master database. The server I have restored the database to has all the logins defined, however they have different sids.
I am not a T-SQL expert….
I think sp_change_users_login is part of the solution, but I can't find out how to get it to automatically link all users in the restored database to the login of the same name.
The database creation scripts we use for our application create the users and logins, however it does not specify the SID when creating the login, hence this problem. Now if I had a time machine...
(When I Google I get lots of hits, however they are mostly sites that won't let you see the answer without having to register on the site first.)
Yes, you can do that by executing:
EXEC sp_change_users_login 'Auto_Fix' , 'TheUserName';
However if your question was can I fix all users automatically then this won't do that.
I came up with the following. It works great because it shows you:
All the current orphaned users.
Which ones were fixed.
Which ones couldn't be fixed.
Other solutions require you to know the orphaned user name before hand in order to fix.
The following code could run in a sproc that is called after restoring a database to another server.
Script:
EXEC sp_change_users_login 'report'--See all orphaned users in the database.
DECLARE #OrphanedUsers TABLE
(
IndexKey Int IDENTITY(1,1) PRIMARY KEY,
UserName SysName,--nVarChar(128)
UserSID VarBinary(85)
)
INSERT INTO #OrphanedUsers
EXEC sp_change_users_login 'report'
DECLARE #CRLF as nVarChar
SET #CRLF = CHAR(10) + '&' + CHAR(13)--NOTE: Carriage-Return/Line-Feed will only appear in PRINT statements, not SELECT statements.
DECLARE #Sql as nVarChar(MAX)
SET #Sql = N''
DECLARE #IndexKey as Int
SET #IndexKey = 1
DECLARE #MaxIndexKey as Int
SET #MaxIndexKey = (SELECT COUNT(*) FROM #OrphanedUsers)
DECLARE #Count as Int
SET #Count = 0
DECLARE #UsersFixed as nVarChar(MAX)
SET #UsersFixed = N''
DECLARE #UserName as SysName--This is an orphaned Database user.
WHILE (#IndexKey <= #MaxIndexKey)
BEGIN
SET #UserName = (SELECT UserName FROM #OrphanedUsers WHERE IndexKey = #IndexKey)
IF 1 = (SELECT COUNT(*) FROM sys.server_principals WHERE Name = #UserName)--Look for a match in the Server Logins.
BEGIN
SET #Sql = #Sql + 'EXEC sp_change_users_login ''update_one'', [' + #UserName + '], [' + #UserName + ']' + #CRLF
SET #UsersFixed = #UsersFixed + #UserName + ', '
SET #Count = #Count + 1
END
SET #IndexKey = #IndexKey + 1
END
PRINT #Sql
EXEC sp_executesql #Sql
PRINT 'Total fixed: ' + CAST(#Count as VarChar) + '. Users Fixed: ' + #UsersFixed
SELECT ('Total fixed: ' + CAST(#Count as VarChar) + '. Users Fixed: ' + #UsersFixed)[Fixed]
EXEC sp_change_users_login 'report'--See all orphaned users still in the database.
Result:
*Note: The 4 that were not fixed (in my example screenshot above) did not have a corresponding User in the destination Server that the database was restored to.
If:
EXEC sp_change_users_login 'Auto_Fix' , 'TheUserName';
Doest't work, try this:
EXEC sp_change_users_login 'Auto_Fix', 'Username', NULL, 'p#ssword123'
I found it here:
http://dbadiaries.com/using-sp_change_users_login-to-fix-sql-server-orphaned-users
I found the following script from Microsoft KB918992 - run it on the original server and it will create a stored procedure called 'sp_help_revlogin' which generates another script to run on the destination server, creating all user accounts with the same passwords and sids. Worked wonders for our upgrade from SQL2000 to 2008.
USE master
GO
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
DROP PROCEDURE sp_hexadecimal
GO
CREATE PROCEDURE sp_hexadecimal
#binvalue varbinary(256),
#hexvalue varchar(256) OUTPUT
AS
DECLARE #charvalue varchar(256)
DECLARE #i int
DECLARE #length int
DECLARE #hexstring char(16)
SELECT #charvalue = '0x'
SELECT #i = 1
SELECT #length = DATALENGTH (#binvalue)
SELECT #hexstring = '0123456789ABCDEF'
WHILE (#i <= #length)
BEGIN
DECLARE #tempint int
DECLARE #firstint int
DECLARE #secondint int
SELECT #tempint = CONVERT(int, SUBSTRING(#binvalue,#i,1))
SELECT #firstint = FLOOR(#tempint/16)
SELECT #secondint = #tempint - (#firstint*16)
SELECT #charvalue = #charvalue +
SUBSTRING(#hexstring, #firstint+1, 1) +
SUBSTRING(#hexstring, #secondint+1, 1)
SELECT #i = #i + 1
END
SELECT #hexvalue = #charvalue
GO
IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
DROP PROCEDURE sp_help_revlogin
GO
CREATE PROCEDURE sp_help_revlogin #login_name sysname = NULL AS
DECLARE #name sysname
DECLARE #xstatus int
DECLARE #binpwd varbinary (256)
DECLARE #txtpwd sysname
DECLARE #tmpstr varchar (256)
DECLARE #SID_varbinary varbinary(85)
DECLARE #SID_string varchar(256)
IF (#login_name IS NULL)
DECLARE login_curs CURSOR FOR
SELECT sid, name, xstatus, password FROM master..sysxlogins
WHERE srvid IS NULL AND name <> 'sa'
ELSE
DECLARE login_curs CURSOR FOR
SELECT sid, name, xstatus, password FROM master..sysxlogins
WHERE srvid IS NULL AND name = #login_name
OPEN login_curs
FETCH NEXT FROM login_curs INTO #SID_varbinary, #name, #xstatus, #binpwd
IF (##fetch_status = -1)
BEGIN
PRINT 'No login(s) found.'
CLOSE login_curs
DEALLOCATE login_curs
RETURN -1
END
SET #tmpstr = '/* sp_help_revlogin script '
PRINT #tmpstr
SET #tmpstr = '** Generated '
+ CONVERT (varchar, GETDATE()) + ' on ' + ##SERVERNAME + ' */'
PRINT #tmpstr
PRINT ''
PRINT 'DECLARE #pwd sysname'
WHILE (##fetch_status <> -1)
BEGIN
IF (##fetch_status <> -2)
BEGIN
PRINT ''
SET #tmpstr = '-- Login: ' + #name
PRINT #tmpstr
IF (#xstatus & 4) = 4
BEGIN -- NT authenticated account/group
IF (#xstatus & 1) = 1
BEGIN -- NT login is denied access
SET #tmpstr = 'EXEC master..sp_denylogin ''' + #name + ''''
PRINT #tmpstr
END
ELSE BEGIN -- NT login has access
SET #tmpstr = 'EXEC master..sp_grantlogin ''' + #name + ''''
PRINT #tmpstr
END
END
ELSE BEGIN -- SQL Server authentication
IF (#binpwd IS NOT NULL)
BEGIN -- Non-null password
EXEC sp_hexadecimal #binpwd, #txtpwd OUT
IF (#xstatus & 2048) = 2048
SET #tmpstr = 'SET #pwd = CONVERT (varchar(256), ' + #txtpwd + ')'
ELSE
SET #tmpstr = 'SET #pwd = CONVERT (varbinary(256), ' + #txtpwd + ')'
PRINT #tmpstr
EXEC sp_hexadecimal #SID_varbinary,#SID_string OUT
SET #tmpstr = 'EXEC master..sp_addlogin ''' + #name
+ ''', #pwd, #sid = ' + #SID_string + ', #encryptopt = '
END
ELSE BEGIN
-- Null password
EXEC sp_hexadecimal #SID_varbinary,#SID_string OUT
SET #tmpstr = 'EXEC master..sp_addlogin ''' + #name
+ ''', NULL, #sid = ' + #SID_string + ', #encryptopt = '
END
IF (#xstatus & 2048) = 2048
-- login upgraded from 6.5
SET #tmpstr = #tmpstr + '''skip_encryption_old'''
ELSE
SET #tmpstr = #tmpstr + '''skip_encryption'''
PRINT #tmpstr
END
END
FETCH NEXT FROM login_curs INTO #SID_varbinary, #name, #xstatus, #binpwd
END
CLOSE login_curs
DEALLOCATE login_curs
RETURN 0
GO
List of all orphan user details with corresponding DB name
Simple step
EXEC master.sys.sp_MSforeachdb ' USE [?]
Select ''?''
EXEC ?.dbo.sp_change_users_login ''report'' '
I have a nice script that you can use to create logins from database users,which I came across after searching for this issue this script is using a stored procedure. you can find some other useful scripts here also at this url
http://www.sqlserveroptimizer.com/2011/08/how-to-script-logins-from-user-database-in-sql-server-20052008-r2/
USE MyDatabaseName
DECLARE #login nvarchar(50)
DECLARE logins_cursor CURSOR FOR SELECT l.name FROM sys.database_principals u INNER JOIN sys.server_principals l ON u.sid=l.sid
OPEN logins_cursor FETCH NEXT FROM logins_cursor INTO #login
WHILE ##FETCH_STATUS = 0 BEGIN EXEC sp_help_revlogin #login FETCH NEXT FROM logins_cursor INTO #login END
CLOSE logins_cursor DEALLOCATE logins_cursor GO

Resources