Stored procedure to generate a random password in SQL

For those of you who want to generate a random password here is a procedure you can use. The code is a little excessive but it has configurable parameters for length, numbers, caps/lower, etc.

Enjoy!


----------------------------------------------------------------------------
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

create procedure [dbo].[generate_password] 
  @length int = 10             -- the desired length of the password int <= 30
, @numbers varchar(1) = 'Y'    -- use numbers
, @specials varchar(1) = 'Y'   -- use special characters
, @caps varchar(1) = 'Y'       -- use caps and lower case
, @includeconfusingletters varchar(1) = 'N'  -- include letters that resemble numbers when typed out
as

--****************************************************************************************************************************************
-- Procedure: [dbo].[generate_password]
-- Description: This procedure is used to generate a random password
--****************************************************************************************************************************************

	declare @int int, @letter int, @cap int, @letter_or_number int, @number int, @special int;
	declare @cap_used varchar(1), @lower_used varchar(1), @number_used varchar(1), @special_used varchar(1);
	declare @var varchar(30)
	select @lower_used = 'N', @var = '', @int = 1; --@length = 10, 
	

    if upper(@numbers) not in ('Y', 'N') set @numbers = 'Y';
    if upper(@specials) not in ('Y', 'N') set @specials = 'Y';
    if upper(@caps) not in ('Y', 'N') set @caps = 'Y';
    
    set @numbers = upper(@numbers);
    set @specials = upper(@specials);
    set @caps = upper(@caps);

	if @numbers = 'N' set @number_used = 'Y' else set @number_used = 'N';
	if @specials = 'N' set @special_used = 'Y' else set @special_used = 'N';
    if @caps = 'N' set @cap_used = 'Y' else set @cap_used = 'N';
    if @numbers = 'N' set @includeconfusingletters = 'Y';

	if @length < 4
	begin
	   print 'Minimum password length is 4 characters... setting password length to 4 characters';
	   set @length = 4
	end
	if @length > 30
	begin
	   print 'Maximum password length is 30 characters... setting password length to 30 characters';
	   set @length = 30
	end

	while @int <= (@length) or (@cap_used = 'N' or @lower_used = 'N' or @number_used = 'N' or @special_used = 'N')
	begin
	   select @letter = ceiling(rand() * 26)
	   select @cap = round((rand() * 1),0)
	   select @letter_or_number = floor(rand() * 3)
	   select @number = floor(rand() * 10)
	   select @special = ceiling(rand() * 10)


	   if @numbers = 'Y' and @specials = 'Y'
	   begin
          select @letter_or_number = floor(rand() * 3)
	   end
	   else
	   begin
          if @numbers = 'Y' and @specials = 'N'
          begin
             select @letter_or_number = floor(rand() * 2)
          end
          else
          begin
             if @numbers = 'N' and @specials = 'Y'
             begin
                while @letter_or_number is null or @letter_or_number = 1
                begin
                   select @letter_or_number = floor(rand() * 3)
                end
             end
             else
             begin
                if @numbers = 'N' and @specials = 'N'
                begin
                   select @letter_or_number = 0
                end
             end
          end
	   end
       
       if @caps = 'N' set @cap = 0;
	   
	   if @int = @length - 3 and @lower_used = 'N'
	   begin
		  select @letter_or_number = 0, @cap = 0;
	   end
	   if @int = @length - 2 and @cap_used = 'N'
	   begin
		  select @letter_or_number = 0, @cap = 1;
	   end
	   if @int = @length - 1 and @number_used = 'N'
	   begin
		  select @letter_or_number = 1;   
	   end
	   if @int = @length and @special_used = 'N'
	   begin
		  select @letter_or_number = 2;   
	   end
	   
	   if @int = 1
	   begin
		  select @letter_or_number = 0;   
	   end

	   set @var = @var + case when @letter_or_number = 0 then
		    case when @cap = 0 then
			  case when @letter = 1 then 'a'
				when @letter = 2 then 'b'
				when @letter = 3 then 'c'
				when @letter = 4 then 'd'
				when @letter = 5 then 'e'
				when @letter = 6 then 'f'
				when @letter = 7 then 'g'
				when @letter = 8 then 'h'
				when @letter = 9 then 'i'
				when @letter = 10 then 'j'
				when @letter = 11 then 'k'
				when @letter = 12 then case when @includeconfusingletters = 'N' then 'k' else 'l' end
				when @letter = 13 then 'm'
				when @letter = 14 then 'n'
				when @letter = 15 then 'o'
				when @letter = 16 then 'p'
				when @letter = 17 then 'q'
				when @letter = 18 then 'r'
				when @letter = 19 then 's'
				when @letter = 20 then 't'
				when @letter = 21 then 'u'
				when @letter = 22 then 'v'
				when @letter = 23 then 'w'
				when @letter = 24 then 'x'
				when @letter = 25 then 'y'
				when @letter = 26 then 'z'
				end
			 else
			  upper(case when @letter = 1 then 'a'
				when @letter = 2 then 'b'
				when @letter = 3 then 'c'
				when @letter = 4 then 'd'
				when @letter = 5 then 'e'
				when @letter = 6 then 'f'
				when @letter = 7 then 'g'
				when @letter = 8 then 'h'
				when @letter = 9 then 'i'
				when @letter = 10 then 'j'
				when @letter = 11 then 'k'
				when @letter = 12 then 'l'
				when @letter = 13 then 'm'
				when @letter = 14 then 'n'
				when @letter = 15 then case when @includeconfusingletters = 'N' then 'n' else 'o' end
				when @letter = 16 then 'p'
				when @letter = 17 then 'q'
				when @letter = 18 then 'r'
				when @letter = 19 then 's'
				when @letter = 20 then 't'
				when @letter = 21 then 'u'
				when @letter = 22 then 'v'
				when @letter = 23 then 'w'
				when @letter = 24 then 'x'
				when @letter = 25 then 'y'
				when @letter = 26 then 'z'
				end)
			  end
			when @letter_or_number = 1 then rtrim(convert(varchar(2), @number))
			else 
			   case ceiling(rand() * 14) 
			        when 1 then '!'
			        when 2 then '@'
			        when 3 then '#'
			        when 4 then '$'
			        when 5 then '%'
			        when 6 then '^'
			        when 7 then '&'
			        when 8 then '*'
			        when 9 then '('
			        when 10 then ')'
			        when 11 then '+'
			        when 12 then '<'
			        when 13 then '>'
			        when 14 then '~'
			        else '!'
			    end
			end
	        
	   if @letter_or_number = 0 and @cap = 0
	   begin
		  set @lower_used = 'Y';
	   end        
	   if @letter_or_number = 0 and @cap <> 0
	   begin
		  set @cap_used = 'Y';
	   end        
	   if @letter_or_number = 1
	   begin
		  set @number_used = 'Y';
	   end
	   if @letter_or_number = 2
	   begin
		  set @special_used = 'Y';
	   end
	       
	   set @int = @int + 1;
	end

	select @var as [password];
---------------------------------------------------------------------

SQL command to change the database owner

To change the database owner using a sql command you can use the ALTER AUTHORIZATION command.

---------------------------------------------
alter authorization on database::[database_name] to new_owner;
---------------------------------------------

If you wanted to change the database owner on all the user databases on the sql server at the same time you could do something like this:

---------------------------------------------
declare @dbname varchar(128), @sql varchar(max), @owner varchar(3);
set @owner = 'sa' --- the intended databse owner
declare cursor1 cursor for 
select rtrim(name) from sys.databases 
   where databasepropertyex(name, 'Status') = 'ONLINE' 
   and name not in ('master', 'model', 'tempdb', 'msdb', 'distribution');

open cursor1;
fetch next from cursor1 into @dbname;

while @@fetch_status = 0
begin
   set @sql = 'alter authorization on database::' + quotename(@dbname) + ' to ' + @owner + ';';
   exec(@sql);

   fetch next from cursor1 into @dbname;
end
close cursor1;
deallocate cursor1;
---------------------------------------------

SQL script to set database compatability level

To set the database compatability level of a database using a t-sql commmand you will use the ALTER DATABASE command.

---------------------------------------
ALTER DATABASE [database_name] SET COMPATIBILITY_LEVEL = 90 | 100 | 110
---------------------------------------

SQL Server 2000 = compatability level 80
SQL Server 2005 = compatability level 90
SQL Server 2008 = compatability level 100
SQL Server 2012 = compatability level 110

Here is a quick and dirty script to set the compatability level of all the databases on the server:

---------------------------------------
declare @dbname varchar(128), @sql varchar(max), @level varchar(3);
set @level = '110' --- 90 | 100 | 110
declare cursor1 cursor for 
select rtrim(name) from sys.databases 
   where databasepropertyex(name, 'Status') = 'ONLINE' 
   and name not in ('master', 'model', 'tempdb', 'msdb', 'distribution');

open cursor1;
fetch next from cursor1 into @dbname;

while @@fetch_status = 0
begin
   set @sql = 'ALTER DATABASE ' + quotename(@dbname) + ' SET COMPATIBILITY_LEVEL = ' + @level + ';';
   exec(@sql);

   fetch next from cursor1 into @dbname;
end
close cursor1;
deallocate cursor1;
---------------------------------------

T-SQL script to find domain name

There are a few ways that I know to find the server’s domain name using a SQL script. I listed them below:

First: You can read the registry

----------------------------------------------------------------------------------------
DECLARE @domain_name varchar(128), @key varchar(128);

SET @key = 'SYSTEM\ControlSet001\Services\Tcpip\Parameters\';
EXEC master..xp_regread @rootkey='HKEY_LOCAL_MACHINE', @key=@key,@value_name='Domain',@value=@domain_name OUTPUT;
SELECT 'Server Name: '+@@servername + ' Domain Name:'+convert(varchar(100),@domain_name)
----------------------------------------------------------------------------------------

Another way is to issue this SQL command:

---------------------------------------------------------------------
SELECT DEFAULT_DOMAIN()
---------------------------------------------------------------------

In SQL Server 2000 you can run the following SQL script:

---------------------------------------------------------------------
EXEC master.dbo.xp_logininfo 'Default Domain' 
---------------------------------------------------------------------

A SQL script to find all of the tables in a database that have a certain column

Have you ever needed to find all of the tables in a database that contain a field called _____ (insert field name here). It’s actually pretty easy to do. Microsoft was kind enough to provide us with a number of system catalog views that give us a plethora of useful information. One of these views is “sys.columns”. You can use sys.columns to figure out every table that has a column with a specific name.

For example. Let’s say you had a column called ‘ApplicationId’ on a specific table and you wanted to change the length of that column from varchar(10) to varchar(15). Chances are your application may use this field on several different tables. If this is the case then obviously you would want to make sure that you changed this field on every table that uses this field to prevent your application from errors if it attempts to insert a 15 character value into this field in any given table. You know of a few tables that have this ‘ApplicationId’ field, but you’re getting older and your memory just isn’t what it used to be. So to make sure that you get all of them you can use sys.columns like this:

-----------------------------------------------------------------------
select object_name([object_id]), * from sys.columns 
where name = 'ApplicationId'
order by object_name([object_id])
-----------------------------------------------------------------------

Notice that I used the system function “object_name()” to get the table name. Using the object_name() function gives me the table name without having to join to the sys.objects or sys.tables system catalog views to get the name. Of course if you needed more information about that table you could make this join on object_id like this:

-------------------------------------------------------------------------------------------
select a.name, b.name, b.[type], b.type_desc, b.[schema_id], schema_name(b.[schema_id])
from sys.columns as [a], sys.objects as [b]
where a.name = 'ApplicationId' and b.[object_id] = a.[object_id]
order by b.name
-------------------------------------------------------------------------------------------

This alows me to gather a little more information about the table that the field resides on such as: “is it a view instead of an actual table”.

How do I write a SQL script that will return the current database name in SQL Server?

Question: How do I write a SQL script that will return the current database name in SQL Server?

Answer: Easy – select db_name();

The system function db_name() can be used to return this information.

The syntax for this command is: “DB_NAME ( [ database_id ] )” where database_id is the database id from sys.databases. If do not pass a value to the database_id parameter the DB_NAME function will return the name of the database that the script is currently executing in.

The following example returns the name of the current database.

---------------------------------------
select db_name() as [Current Database];
go
---------------------------------------

The following example returns the value “AdventureWorks” which is the name of the current database.

---------------------------------------
use AdventureWorks;
go
select db_name() as [Current Database];
go
---------------------------------------

If you have any given database id and want to know the corresponding database name all you have to do is pass the database id to the db_name() system function. On my sql server the AdventureWorks database has the dababase id ’13’ (This can be found by selecting from the sys.databases system catalog view or by using the db_id() system function).

The following example returns the name of the database with the database id of ’13’. Since the AdventureWorks database on my particular SQL server has database id ’13’ the following example will return ‘AdventureWorks’ regardless of which database I am in when I execute the query.

--------------------------------------
select db_name(13) as [Database Name];
go
--------------------------------------

A SQL script to find all of the SQL server roles that a SQL Server user is in

Have you ever wanted to know all of the SQL roles that a given login resides in within any database on a SQL server?  While gathering this information have you ever made the determination that using the graphical interface provided in SSMS to gather this information is cumbersome?

Well… I have.  Because of that I threw this script together.  The below script will return all of the database roles that a given login resides in within any database on the SQL server.  it’s actually a pretty simple little script. It uses a variable called @login which you populate with the login name that you want to search for.  By using a cursor it will move through each database on the server matching the database user with the sid from sys.server_principals and checking the roles to see where the login is hanging out.  It inserts the information into a temp table and then returns the temp table at the end.

System dmv used by this script:

** In SQL Server 2005 and later versions, the visibility of the metadata in catalog views is limited to securables that a user either owns or on which the user has been granted some permission.

 

use master;
go
set nocount on;
go

if (select object_id('tempdb..#temptable')) is not null
begin
  drop table #temptable;
end;
create table #temptable(
  [dbname] varchar(128) not null
, [member_name] varchar(128) not null
, [role_name] varchar(128) not null
);

declare @dbname varchar(128), @sql varchar(max), @login varchar(128), @sid varbinary(85), @server_principal_id int;
set @login = 'testlogin'

select @sid = [sid] from sys.server_principals where name = @login;

declare cursor1 cursor for
select rtrim(name) from sys.databases where state = 0;
open cursor1;
fetch next from cursor1 into @dbname;
while @@fetch_status = 0
begin
   set @sql = 'select ''' + @dbname + ''' as [dbname], a.name as [member_name], c.name as [role_name]
   from [' + @dbname + '].[sys].[database_principals] as [a], [' + @dbname + '].[sys].[database_role_members] as [b], [' + @dbname + '].[sys].[database_principals] as [c]
   where a.[sid] = ' + sys.fn_varbintohexstr(@sid) + ' and b.member_principal_id = a.principal_id and c.principal_id = b.role_principal_id'
   insert into #temptable exec(@sql);

   fetch next from cursor1 into @dbname;
end
close cursor1;
deallocate cursor1;

select * from #temptable order by dbname;