DBA Diaries

Thoughts and experiences of a DBA working with SQL Server and MySQL

Using sp_change_users_login to fix SQL Server orphaned users

Posted on September 19, 2012 Written by Andy Hayes 17 Comments

In this post, I’m going to be looking at sp_change_users_login in order to fix SQL Server orphaned users as a continuation to a previous article. There I looked at a couple of ways to transfer logins from one SQL Server to another and touched upon the issue of the orphaned “security identifier” (SID).

A typical scenario that arises is when the DBA quickly realises that the logins on the SQL Server cannot access the database. They try and add the login to the database as a user and are presented with the error:

Error 15023: User already exists in current database.

The root cause of this problem can be when a login is deleted or the database has been moved or restored to another server but the login transported in the database does not exist on the destination server.

Through SQL Server Management Studio, the database user properties will show the User type: as SQL user without login

sql user without login

sp_change_users_login to the rescue!

I first saw this error a number of years ago and due to my complete lack of experience at the time, one of my first thoughts was that I would have to remove the database users, re-add them all for each login requiring access and then proceed to add the permissions back in for user.

I quickly realised that this would be a massive waste of my time and that there had to a better way and so I proceeded to consult the search engines for a resolution. Unsurprisingly I quickly found many other people who had been in the same situation as me and that sp_change_users_login had been the cure to all their woes.

And here I am writing a post about it 🙂 Well I never would have imagined that but it was a long time ago and only clever people could put a website together back in those days when blogging platforms were a twinkle in some programmers eye.

How to use sp_change_users_login to fix SQL Server orphaned users

The best thing to do is run the following code against each database you are checking. Run this against each database. It will help you to find all the orphaned logins in your database.

USE DatabaseName
EXEC sp_change_users_login 'Report';

You will see output like the screenshot attached if there are any sql orphaned users. In this example, user “db_login1” is showing up as an orphaned user.

sp_change_users_login report

If you already have a login which you want to map your database user to, you could run the following (note that the first instance of ‘db_login1’ is the user in the database, the second instance is the login to be mapped to) :

EXEC sp_change_users_login 'update_one', 'db_login1', 'db_login1';

If you don’t already have a login to map to, you can have sp_change_users_login create one for you and with a password. The following code does this and creates a login with the same name and a password of ‘aaZZww77’ as an example.

EXEC sp_change_users_login 'Auto_Fix', 'db_login1', NULL, 'aaZZww77';

sp_change_users_login auto_fix

UPDATE – 3rd Apr 2018

An alternate way to detect orphaned users in SQL Server or PDW is by running this code for each database:


SELECT dp.type_desc, dp.SID, dp.name AS user_name
FROM sys.database_principals AS dp
LEFT JOIN sys.server_principals AS sp ON dp.SID = sp.SID
WHERE sp.SID IS NULL AND authentication_type_desc = 'INSTANCE';


This is an example output:

detecting orphaned users in sql server using sp_change_users_login

For identifying orphaned users in Azure SQL Database and SQL Data Warehouse run this code in the master database:

SELECT sid FROM sys.sql_logins WHERE type = 'S';

Now run this code in each database:

SELECT name, sid, principal_id
FROM sys.database_principals
WHERE type = 'S'
AND name NOT IN ('guest', 'INFORMATION_SCHEMA', 'sys')
AND authentication_type_desc = 'INSTANCE';

Compare the two lists to see if there are user SID’s in sys.database_principals which are not found in sys.sql_logins

Fix SQL Orphaned Users Using CREATE LOGIN

You can take the SID’s identified in the previous section and use them as part of the CREATE LOGIN statement, example:

CREATE LOGIN db_login_1
WITH PASSWORD = 'use_a_strong_password_here',
SID = 0xB171D3B5A352A846847342C5E46620BA;

If you’re mapping an orphaned user to a login which already exists in master, run this:

ALTER USER <user_name> WITH Login = <login_name>;

For more info on how to fix orphaned users, click this sp_change_users_login link  and this one on troubleshooting orphaned users to view the documentation from Microsoft.

Filed Under: All Articles, SQL Server Administration, SQL Server Security Tagged With: security, sql server

How to Transfer Logins to Another SQL Server or Instance

Posted on September 15, 2012 Written by Andy Hayes 9 Comments

With any server migration, ideally you want things to run smoothly and re-creating SQL Server logins and passwords from scratch is not something you really want to or should be doing.

I am currently involved in a complete server replacement for one of our SQL Server clusters. In this environment, mixed authentication is enabled.

Back in the day when I was learning about transferring databases from one server, I quickly discovered that restoring a database from one server to another was not as straightforward as I had anticipated. I came across a hurdle which I needed to overcome in the form of the SID’s.

So first I’ll talk about the ways in which you can transfer logins from one SQL Server to another and explain about the SID’s further down the post.

Ways to transfer SQL logins and passwords between instances of SQL Server

Now you can do this the easy way or the hard way! 🙂

You can manually set up copies of your logins on your new server with passwords (if you know them) or you can automate this task with the help of either a T-SQL script or SSIS.

I don’t know about you but I don’t like manual and I would recommend that you automate this each time.

Using T-SQL to transfer logins and passwords between SQL Server instances

You can obtain a script from Microsoft here. You run the script, it creates a stored procedure called sp_help_revlogin on your SQL Server. When you run the stored procedure, it outputs CREATE LOGIN statements for all your server logins including their passwords and “sids”.

You can then take that script, run it on your new SQL Server to set up the server logins there. Obviously taking care to look over it before you execute it to make sure that it has captured everything and to ensure that you are not copying over anything that you do not need on your new instance.

The script will set up the logins on your new server in using the default language configured for that server so make sure that is configured correctly first.

Using the transfer logins task in SSIS to copy logins and passwords between SQL Server instances

There is a transfer logins task within SSIS which will also do the job. In the screenshot attached, I am using the new version of SSIS which ships with SQL Server 2012. The transfer logins task falls under “other tasks” in the the SSIS toolbox and is available in older versions of SSIS.

transfer logins between sql server servers or instances

So hopefully you can see from the screenshot that the transfer logins task is fairly self explanatory. The great thing about SSIS is that it holds your hand in many ways and makes things as easy as possible.

You can create connections from this task, enter the login details for your source and destination, choose which logins to copy and you can configure the task to behave in different ways when the login exists.

As you can see I have circled “CopySids” so now is a good time to write about them in more detail.

So what is a SID?

SID is short for “security identifier” A SID is an internal id which gets assigned to a server login when the login is created.

The SID can be viewed by querying the sys.server_principals system view or you can also view it by looking at sys.syslogins

SELECT principal_id, sid, name
FROM sys.server_principals
SELECT sid, name
FROM sys.syslogins

Each server login, be that a SQL login, Windows login or one which was created using a certificate or asymmetric key, gets assigned a SID. So lets imagine an example scenario where a new login is created and it happens to be a SQL Server login, that login gets named “server_login1”.

You then create a database login inside the AdventureWorks2012 database using the server login just created. Lets call that “db_login1”.

Now view the SID’s in sys.server_principals and sys.database_principals from AdventureWorks2012 and the SID will be of the same value.

SELECT sid
FROM sys.server_principals
WHERE name = 'server_login1'

USE AdventureWorks2012
GO
SELECT sid
FROM sys.database_principals
WHERE name = 'db_login1'

Unless you create your logins on your new server using a method such as the sp_help_revlogin or the SSIS transfer logins task with “CopySids” enabled, your logins will be created with new SIDs.

I am not sure whether it is possible that your new server will ever assign the same SID but I do know that it is very unlikely. Perhaps you have more chance of winning the lottery jackpot 🙂

So what problems does this cause?

As the SIDs are different, when you come to copy across/restore your databases from your old server, the database logins simply won’t work as they will be orphaned from their original SID.

You may encounter this error for example if you try and add a server login to a database which you have just copied across.

Error 15023: User already exists in current database

This will then need to be corrected.

There is a procedure that you can run in order to do this and it basically takes the server login and database login and marries them up by name with the same SID.

This procedure is called sp_change_users_login and I’m going to talk about that in this post.

Filed Under: All Articles, SQL Server Administration, SQL Server Security Tagged With: security, sql server

How to Determine SQL Server Version Number In Various Ways

Posted on September 1, 2012 Written by Andy Hayes 1 Comment

determine sql server versionIt’s important to be able to determine SQL Server version number. DBA’s need to know what SQL Server version numbers they are supporting so that during patching windows, they can source and apply the correct patches or service packs.

This information is useful as a reference to what issues may be contained in a certain build that could affect production. The DBA can quickly reference the latest build list with their current SQL Server version number and work out where their build falls on the list and which patches to apply.

Here is the latest SQL Server 2012 build list which also contains a link to lists for previous versions. Please note that you have to register on SQL Server Central if you are not already a member to view this. (I’d recommend that you do register as it is a brilliant forum 🙂 )

Ways to determine SQL Server version number

All of these methods are straightforward so lets take a look.

Method 1 – “SELECT @@VERSION”

Simply open up a new query and run the following:

SELECT @@VERSION

The output will look something like:

Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 
	Feb 10 2012 19:39:15 
	Copyright (c) Microsoft Corporation
	Express Edition (64-bit) on Windows NT 6.1  (Build 7601: Service Pack 1)

Method 2 – “xp_msver”

I like this one as it provides quite a lot of useful information about your SQL Server installation and server configuration

EXEC xp_msver

Sample output from my SQL Server 2012 install…
determine sql server version number

Method 3 – “SELECT SERVERPROPERTY”

You run SELECT SERVERPROPERTY against your server and pass in some parameters to get back the information you want.

SELECT
SERVERPROPERTY('productversion') AS ProductVersion
, SERVERPROPERTY ('productlevel') AS ProductLevel
, SERVERPROPERTY ('edition') AS ProductEdition

Which produces the following output…

ProductVersion       ProductLevel         ProductEdition
-------------------- -------------------- ------------------------------
11.0.2100.60         RTM                  Express Edition (64-bit)

(1 row(s) affected)

Method 4 – Use Management Studio (Client Tools)

You can access the Help menu in Management Studio and goto “About” to ascertain which SQL Server versions of the client tools you have installed on your workstation or SQL Server.

Summary – How to determine SQL Server version

So there are some ways to find out which versions of your client tools and server engine you are running. There may be others and if you know of them, please do leave a comment.

Filed Under: All Articles, SQL Server Administration Tagged With: sql, sql server

Querying INFORMATION_SCHEMA

Posted on July 14, 2012 Written by Andy Hayes 2 Comments

querying information_schema

This post applies to both MySQL and Microsoft SQL Server as both these products allow you to query something called INFORMATION_SCHEMA.

What is INFORMATION_SCHEMA?

It is database metadata. In MySQL, there is a complete virtual database dedicated to it called “information_schema” and in Microsoft SQL Server, there are views which you can query, all prefixed with INFORMATION_SCHEMA in each database.

You can find a full list of the views by opening up the “System Views” node in Management Studio.

In MySQL, you would run the following to get information on tables in a database:

SELECT * FROM information_schema.tables
WHERE table_schema = 'YourDatabaseName';

In SQL Server, the same would be:

USE YourDatabaseName
SELECT * FROM INFORMATION_SCHEMA.tables;

The metadata is automatically updated by the database engine and it is not possible to update the data within but direct user initiated queries

Why use INFORMATION_SCHEMA?

Some of the things I would use it for would include:

  • Finding out how many rows per table you have in your databases
  • Finding out how large your tables and indexes are
  • Finding out when a stored procedure was last updated
  • Assessing index fragmentation (applies to MySQL, you would use a DMV in SQL Server called sys.dm_db_index_physical_stats or legacy DBCC SHOWCONTIG)
  • Finding out which stored procedures contained certain queries (see below example)

A question I get asked as a DBA sometimes is how can I find a stored procedure containing a certain query. I point the developer at INFORMATION_SCHEMA.ROUTINES and to look in the “routine_definition” field for specific keywords, for example I would use this against SQL Server:

USE YourDatabaseName
SELECT * FROM INFORMATION_SCHEMA.ROUTINES
WHERE routine_definition LIKE '{3a76cbff1b5ce5ace3bd34bbdd68f71285d81fb9af60114c7a6db80d3a8688de}keyword{3a76cbff1b5ce5ace3bd34bbdd68f71285d81fb9af60114c7a6db80d3a8688de}';

In MySQL you can get this information too but it is not part of INFORMATION_SCHEMA and instead you have to query the mysql.proc table.

There are other ways to get this information, for example in SQL Server, you can load up the Object Explorer in Management Studio to view information on row counts, space used for data and indexes per table but I prefer writing queries to do this.

I think in part because it is a guilty pleasure of mine to query the server using T-SQL or command line tools in MySQL 🙂 and most importantly because there is more information to be had via this method.

For more information, simply start querying it and you will find a wealth of useful stuff inside. Or you can check out these links for both MySQL information_schema and SQL Server information_schema

Filed Under: All Articles, MySQL Administration Tagged With: mysql, sql server

  • « Previous Page
  • 1
  • …
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • Next Page »

Categories

  • All Articles (82)
  • Career Development (8)
  • MySQL Administration (18)
  • MySQL Performance (2)
  • SQL Server Administration (24)
  • SQL Server News (3)
  • SQL Server Performance (14)
  • SQL Server Security (3)
  • SQL Tips and Tricks (19)

Top 10 Popular Posts

  • Using sp_change_users_login to fix SQL Server orphaned users
  • How to shrink tempdb
  • MySQL SHOW USERS? – How to List All MySQL Users and Privileges
  • How to Transfer Logins to Another SQL Server or Instance
  • How to Delete Millions of Rows using T-SQL with Reduced Impact
  • T-SQL – How to Select Top N Rows for Each Group Using ROW_NUMBER()
  • New T-SQL features in SQL Server 2012 – OFFSET and FETCH
  • How to Kill All MySQL Processes For a Specific User
  • Using exec sp_who2 to help with SQL Server troubleshooting
  • How to move tempdb

Recent Posts

  • How to Setup MySQL Master Master Replication
  • How To Use SQL to Convert a STRING to an INT
  • How to set up MySQL Replication Tutorial
  • How to Use SQL CASE for Conditional Logic in Your SQL Queries
  • Using ISNULL in SQL Server to Replace NULL Values

Search

Connect

  • Twitter
  • Facebook
  • Google+
  • RSS

About

  • Cookie Policy
  • Disclaimer
  • About
Copyright © ‘2021’ DBA Diaries built on the Genesis Framework

This site uses cookies. We assume you are happy with cookies but click the link if you are not. Close