Wednesday, 27 December 2017

SQL SERVER CLR Error

Error:
Msg 6263, Level 16, State 1, Line 721
Execution of user code in the .NET Framework is disabled. Enable "clr enabled" configuration option.


Solution ; We need to enable the CLR in the SQL Server configuration.

sp_configure 'show advanced options',1
go
sp_configure 'clr enabled',1
go
reconfigure
go


Error:
Msg 10314, Level 16, State 11, Line 2
An error occurred in the Microsoft .NET Framework while trying to load assembly id 65536. The server may be running out of resources, or the assembly may not be trusted with PERMISSION_SET = EXTERNAL_ACCESS or UNSAFE. Run the query again, or check documentation to see how to solve the assembly trust issues. For more information about this error:


Solution 1 : When the databases is restored\attached from the different instance this error might occurred as the CLR objects will be looking for the same owner SID which was created at the source. Changing the databases owner to the same as source and giving the required permission would fix the issue.

Alternatively we can use db owner as ‘sa’ also.

USE <DatabaseName>
GO
EXEC sp_changedbowner 'sa'


Solution 2 : The quickfix would be to set the database to trustworthy: 

ALTER DATABASE <DatabaseName> SET TRUSTWORTHY ON

Solution 3 : You can also navigate to Assemblies of a respective databases and change the Assembly property.  Set the permission to ‘External Access or unrestricted’







Monday, 27 November 2017

Error 945 : Database cannot be opened due to inaccessible files or insufficient memory or disk space. See the SQL Server error log for details

This is one of the common issue which I have seen. Today I received a ticker from QA team saying one of the database is not accessible. I checked with the team on what exactly they are doing on the database. I came to know the team was processing the data which increased the many databases sizes which lead to Disk space issue. 

Due to there was no free space on the disk for the database to grow further, one of the database went to shutdown mode. You can check the database status from below query. 

use master
select databaseproperty('DBName', 'isShutdown')

Fix/Solution/WorkAround:

1. Took the database offline and brought back online. Query for the same 

use master
alter database DBName set offline


use master
alter database DBName set online



2.  If possible add more hard drive space either by removing of unnecessary files from hard drive or add new hard drive with larger size.
3.  Check if the database is set to Autogrow on.
4. Check if the account which is trying to access the database has enough permission to perform operation.
5. Make sure that .mdf and .ldf file are not marked as read only on operating system file system level.

Wednesday, 7 June 2017

How to restore TDE eanabled database


Create a database master key and certificate in the master database.

USE master;
CREATE MASTER KEY
ENCRYPTION BY PASSWORD = 'j3uwgq#)hqI*2';
GO
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'j3uwgq#)hqI*2';

 USE master;
CREATE CERTIFICATE TDECert
WITH SUBJECT = 'TDE Certificate'
GO

Create a backup of the server certificate in the master database. 

BACKUP MASTER KEY TO FILE = 'c:\temp\exportedmasterkey'
 ENCRYPTION BY PASSWORD = 'j3uwgq#)hqI*2';
   
Enable the TDE on user Database

use dbname
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TDECert
GO

ALTER DATABASE skyProduction
SET ENCRYPTION ON
GO
SELECT [name], is_encrypted FROM sys.databases
GO

Backup the Encryption key

USE master
GO
BACKUP CERTIFICATE TDECert
TO FILE = 'C:\temp\dbcert.cer'
WITH PRIVATE KEY (FILE = 'C:\dbcert_Key.pvk' ,
ENCRYPTION BY PASSWORD = 'j3tt4IL!2' )
GO


-- Use to check status
USE master
GO

SELECT * FROM sys.certificates

-- encryption_state = 3 is encrypted
SELECT * FROM sys.dm_database_encryption_keys
  WHERE encryption_state = 3;
 
  SELECT *
FROM sys.dm_database_encryption_keys;

SELECT * FROM sys.databases


--- Restore database on other machine (Decrypt the Database)

--1. Create the Master Key on Target server (Password need not be same)

USE master
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'j3uwgq#)hqI*2'


--2. After a master key has been created, create a certificate by importing the certificate we created earlier (Take the Backup of the certificate).
--Here the ‘Decryption By Password’ parameter is same as that of source server.

CREATE CERTIFICATE TDECert
FROM FILE = 'E:\Backup\Production Server keys\dbCerts\dbcert.cer'    
WITH PRIVATE KEY (FILE = 'E:\Backup\Production Server keys\dbCerts\dbcert_Key.pvk',
DECRYPTION BY PASSWORD = 'j3uwgq#)hqI*2')

--3. Restore the database as regular.


Using SQL Server Management Studio
  1. Create a database master key and certificate in the master database. For more information, see Using Transact-SQL below.
  2. Create a backup of the server certificate in the master database. For more information, see Using Transact-SQL below.
  3. In Object Explorer, right-click the Databases folder and select New Database.
  4. In the New Database dialog box, in the Database name box, enter the name of the new database.
  5. In the Owner box, enter the name of the new database's owner. Alternately, click the ellipsis (…) to open the Select Database Owner dialog box. For more information on creating a new database, see Create a Database.
  6. In Object Explorer, click the plus sign to expand the Databases folder.
  7. Right-click the database you created, point to Tasks, and select Manage Database Encryption.
    The following options are available on the Manage Database Encryption dialog box.
    Encryption Algorithm
    Displays or sets the algorithm to use for database encryption. AES128 is the default algorithm. This field cannot be blank. For more information on encryption algorithms, see Choose an Encryption Algorithm.
    Use server certificate
    Sets the encryption to be secured by a certificate. Select one from the list. If you do not have the VIEW DEFINITION permission on server certificates, this list will be empty. If a certificate method of encryption is selected, this value cannot be empty. For more information about certificates, see SQL Server Certificates and Asymmetric Keys.
    Use server asymmetric key
    Sets the encryption to be secured by an asymmetric key. Only available asymmetric keys are displayed. Only an asymmetric key protected by an EKM module can encrypt a database using TDE.
    Set Database Encryption On
    Alters the database to turn on (checked) or turn off (unchecked) TDE.
  8. When finished, click OK.

Database Mail Issue with .Net Framework 3

We all know how to configure the database mail on SQL server and troubleshoot for any error. Below are some of the common issues and trouble shoot methods.


Install .NET Framework 3 to make the Database engine to work. 

One of the rarest issue faced with SQL server database Mail is, problem with .Net Framework 3. If server is not installed with .Net Framework 3, database mail may not work at all. 


Troubleshooting Database Mail: General steps


Troubleshooting Database Mail involves checking the following general areas of the Database Mail system. These procedures are presented in a logical order, but can be evaluated in any order.

To determine if Database Mail is enabled

  1. In SQL Server Management Studio, connect to an instance of SQL Server by using a query editor window, and then execute the following code:
    sp_configure 'show advanced', 1; 
    GO
    RECONFIGURE;
    GO
    sp_configure;
    GO
    
    In the results pane, confirm that the run_value for Database Mail XPs is set to 1.
    If the run_value is not 1, Database Mail is not enabled. Database Mail is not automatically enabled to reduce the number of features available for attack by a malicious user. For more information, see Understanding Surface Area Configuration.
  2. If you decide that it is appropriate to enable Database Mail, execute the following code:
    sp_configure 'Database Mail XPs', 1; 
    GO
    RECONFIGURE;
    GO
    
  3. To restore the sp_configure procedure to its default state, which does not show advanced options, execute the following code:
    sp_configure 'show advanced', 0; 
    GO
    RECONFIGURE;
    GO
    

To determine if users are properly configured to send Database Mail

  1. To send Database Mail, users must be a member of the DatabaseMailUserRole. Members of the sysadmin fixed server role and msdbdb_owner role are automatically members of the DatabaseMailUserRole role. To list all other members of the DatabaseMailUserRole execute the following statement:
    EXEC msdb.sys.sp_helprolemember 'DatabaseMailUserRole';
    
  2. To add users to the DatabaseMailUserRole role, use the following statement:
    sp_addrolemember @rolename = 'DatabaseMailUserRole'
       ,@membername = '<database user>';
    
  3. To send Database Mail, users must have access to at least one Database Mail profile. To list the users (principals) and the profiles to which they have access, execute the following statement.
    EXEC msdb.dbo.sysmail_help_principalprofile_sp;
    
  4. Use the Database Mail Configuration Wizard to create profiles and grant access to profiles to users.

To confirm that the Database Mail is started

  1. The Database Mail External Program is activated when there are e-mail messages to be processed. When there have been no messages to send for the specified time-out period, the program exits. To confirm the Database Mail activation is started, execute the following statement.
    EXEC msdb.dbo.sysmail_help_status_sp;
    
  2. If the Database Mail activation is not started, execute the following statement to start it:
    EXEC msdb.dbo.sysmail_start_sp;
    
  3. If the Database Mail external program is started, check the status of the mail queue with the following statement:
    EXEC msdb.dbo.sysmail_help_queue_sp @queue_type = 'mail';
    
    The mail queue should have the state of RECEIVES_OCCURRING. The status queue may vary from moment to moment. If the mail queue state is not RECEIVES_OCCURRING, try stopping the queue using sysmail_stop_sp and then starting the queue using sysmail_start_sp.
NoteNote
Use the length column in the result set of sysmail_help_queue_sp to determine the number of e-mails in the Mail queue.

To determine if problems with Database Mail affect all accounts in a profile or only some accounts

  1. If you have determined that some but not all profiles can send mail, then you may have problems with the Database Mail accounts used by the problem profiles. To determine which accounts are successful in sending mail, execute the following statement:
    SELECT sent_account_id, sent_date FROM msdb.dbo.sysmail_sentitems;
    
  2. If a profile which is not working does not use any of the accounts listed, then it is possible that all the accounts available to the profile are not working properly. To test individual accounts, use the Database Mail Configuration Wizard to create a new profile with a single account, and then use the Send Test E-Mail dialog box to send mail using the new account.
  3. To view the error messages returned by Database Mail, execute the following statement:
    SELECT * FROM msdb.dbo.sysmail_event_log;
    
NoteNote
Database Mail considers mail to be sent, when it is successfully delivered to a SMTP mail server. Subsequent errors, such as an invalid recipient e-mail address, can still prevent mail from being delivered, but will not be contained in the Database Mail log.

To configure Database Mail to retry mail delivery

  1. If you have determined that the Database Mail is failing because the SMTP server cannot be reliably reached, you may be able to increase your successful mail delivery rate by increasing the number of times Database Mail attempts to send each message. Start the Database Mail Configuration Wizard, and select the View or change system parameters option. Alternatively, you can associate more accounts to the profile so upon failover from the primary account, Database Mail will use the failover account to send e-mails.
  2. On the Configure System Parameters page, the default values of 5 times for the Account Retry Attempts and 60 seconds for the Account Retry Delay means that message delivery will fail if the SMTP server cannot be reached in 5 minutes. Increase these parameters to lengthen the amount of time before message deliver fails.


A Myth - Truncate and Drop operation can't be rolled Back

We all know Delete is a DML command and it can be rolled back bu using it in the transaction.
But always we have heard, read, practiced and believed to be a MYTH that Truncate and Drop operation can't be rolled Back. But in reality these two operations can also be rolled back and yes it is against to the RDBMS concept itself.

Follow the below steps to witness this.

1. Create a table

 Use AdventureWorks2012

GO 

CREATE TABLE [dbo].[Drop_test](
[id] [int]  NOT NULL,
[name] [varchar](100) NULL
) ON [PRIMARY]

GO


2. Insert a dummy data

Insert into [dbo].[Drop_test]
values (1, 'a') 



3. Check the row count

select * from [dbo].[Drop_test]

4. Truncate the table by using it within a transaction.

begin tran 

truncate table [dbo].[Drop_test]

--commit tran 

Check the row count

select * from [dbo].[Drop_test]

6. Roll Back the transaction and you can get back all the data which was deleted.

Rollback tran 

7. Same steps can be used to verify the Drop Table operation.

begin tran 

drop table  [dbo].[Drop_test]

ROllback tran 










SQL Install Setup disappear when installing SQL Server

We might come across a situation where SQL installation setup will disappear during the installation process. This might be because of many reasons, one such I faced is incomplete uninstall of prevision SQL Server on the machine.  

I encountered an error in the middle of the fresh installation of SQL Server 2012 version, which was asking to reboot the machine. Later continued till the end and error out without installing the SQL Database engine. It is always a good practice to clean up previous SQL files before installing the new one and I did it. But during the next installation started facing the issue. After the acceptance of License and agreement, Setup was disappearing without any error message. I checked the installation logs in Bootstrap folder and Temp folder. couldn't find any proper information about the strange behavior of SQL server. Later I found the below solution in google. 

Here’s what you need to do:
  1. Click on start->run and type %temp% and press enter (basically, go to the temp folder)
  2. Here, look for SQLSetup.log and SQLSetup_1.log. Open the SQLSetup_1.log file. In there, check for the following messages:04/16/2012 17:16:47.950 Error: Failed to launch process
    04/16/2012 17:16:47.952 Error: Failed to launch local setup100.exe: 0x80070003
Typically, you get this error only in SQL 2008, SQL 2008 R2, SQL 2012 and SQL 2014. The steps are slightly different for all 4, and I’ve tried to outline them here.
Warning: These steps involve modification of the windows registry, a highly sensitive component of the Operating System. Before proceeding, please ensure you take a complete backup of the registry.
SQL Server 2008
1. Save the following in a text file, change the extension to .reg, double-click on the file, and on the prompt that appears, select yes to populate the registry:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SQL Server100Bootstrap]
“BootstrapDir”=”C:\\Program Files\\Microsoft SQL Server\\100\\Setup Bootstrap\\”
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\Bootstrap\Setup]
“PatchLevel”=”10.0.1600.22”
2. Next, copy the following files and folders from the media to the specified destinations:
File/Folder in mediaDestination
X64/X86 (depending on what architecture you want to install)C:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\Release
Setup.exeC:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\Release
Setup.rllC:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\Release\Resources\1033
Next, re-run the setup, and it should proceed beyond the point of error this time.
SQL Server 2008 R2
1. Save the following in a text file, change the extension to .reg, double-click on the file, and on the prompt that appears, select yes to populate the registry:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\Bootstrap]
“BootstrapDir”=”C:\\Program Files\\Microsoft SQL Server\\100\\Setup Bootstrap\\”
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\Bootstrap\Setup]
“PatchLevel”=”10.50.1600.00”
2. Next, copy the following files and folders from the media to the specified destinations:
File/Folder in mediaDestination
X64/X86 folder (depending on what architecture you want to install)C:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\SQLServer2008R2
Setup.exeC:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\SQLServer2008R2
Resources folderC:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\SQLServer2008R2
Next, re-run the setup, and it should proceed beyond the point of error this time.
SQL Server 2012
1. Save the following in a text file, change the extension to .reg, double-click on the file, and on the prompt that appears, select yes to populate the registry:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\110\Bootstrap]
“BootstrapDir”=”C:\\Program Files\\Microsoft SQL Server\\110\\Setup Bootstrap\\”
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\110\Bootstrap\Setup]
“PatchLevel”=”11.00.2100.60”
2. Next, copy the following files and folders from the media to the specified destinations:
File/Folder in mediaDestination
X64/X86 folder (depending on what architecture you want to install)C:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\SQLServer2012
Setup.exeC:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\SQLServer2012
Resources folderC:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\SQLServer2012
Next, re-run the setup, and it should proceed beyond the point of error this time.
SQL Server 2014
1. Save the following in a text file, change the extension to .reg, double-click on the file, and on the prompt that appears, select yes to populate the registry:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\110\Bootstrap]
“BootstrapDir”=”C:\\Program Files\\Microsoft SQL Server\\120\\Setup Bootstrap\\”
[HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SQL Server120BootstrapSetup]
“PatchLevel”=”12.00.2000.80”
2. Next, copy the following files and folders from the media to the specified destinations:
File/Folder in mediaDestination
X64/X86 folder (depending on what architecture you want to install)C:\Program Files\Microsoft SQL Server\120\Setup Bootstrap\SQLServer2014
Setup.exeC:\Program Files\Microsoft SQL Server\120\Setup Bootstrap\SQLServer2014
Resources folderC:\Program Files\Microsoft SQL Server\120\Setup Bootstrap\SQLServer2014
Next, re-run the setup, and it should proceed beyond the point of error this time.


Friday, 27 January 2017

SQL SERVER – SPID status is KILLED/ROLLBACK state. Unable to kill the process.

he first question which would come to mind would be “what is killed/rollback command?” The answer is very simple – sometimes, DBA/Developer use “KILL” command to end processes that appear in a hung state. Once that happen, if SQL knows how to rollback that work, it would start “real” rollback process and would undo the work done. There are situations where SQL doesn’t know and has no control of work done of the work done and it has no control to roll back the work. These are the cases where its stays in KILLED/ROLLBACK state forever.
How would you decide which action to take? It completely depends on the action done by the SPID which was killed. There are only a few things, which you can do:
  1. Have patience and wait for rollback to finish. Some large operations may take a long time to rollback. Such SPID should show a change in CPU, Memory and IO column in size. sys.sysprocesses DMV (query in the next step).
  2. If the SPID is not showing any change in CPU, Memory and IO column then it is doing nothing. Here is the query which can tell us more about the SPID and from where the connection might have originated.
                                  SELECT spid , kpid, login_time, last_batch, status, hostname
                                  ,nt_username, loginame, hostprocess, cpu, memusage, physical_io
                                    FROM sys.sysprocesses WHERE cmd = 'KILLED/ROLLBACK' 
If the process is originated from different machine, then using task manager and doing end process on that machine might help. This decision has to be taken very carefully as it might be a process of a 3rd party application.
After figuring out the SPID we can run the DBCC INPUTBUFFER (<SPID>) to know what is the batch running under this session. 
  1. Restart SQL Service if it was killed and doing nothing.


Wednesday, 11 January 2017

'SetEndOfFile' error during Backup

Below is the error.

Message
Executed as user:. Date and time: 2016-12-11 04:10:11  Server:  Version: 11.0.6537.0  Edition: Enterprise Edition: Core-based  Procedure: [master].[dbo].[Database]  Parameters: @Databases = 'DB_Name', @Directory = 'Backup path1', @BackupType = 'FULL', @Verify = 'N', @CleanupTime = 240, @CleanupMode = 'AFTER_BACKUP', @Compress = 'Y', @CopyOnly = 'N', @ChangeBackupType = 'Y', @BackupSoftware = NULL, @CheckSum = 'Y', @BlockSize = NULL, @BufferCount = 256, @MaxTransferSize = 2097152, @NumberOfFiles = 4, @CompressionLevel = NULL, @Description = NULL, @Threads = NULL, @Throttle = NULL, @Encrypt = 'N', @EncryptionAlgorithm = NULL, @ServerCertificate = NULL, @ServerAsymmetricKey = NULL, @EncryptionKey = NULL, @ReadWriteFileGroups = 'N', @OverrideBackupPreference = 'N', @NoRecovery = 'N', @URL = NULL, @Credential = NULL, @MirrorDirectory = NULL, @MirrorCleanupTime = NULL, @MirrorCleanupMode = 'AFTER_BACKUP', @LogToTable = 'Y', @Execute = 'Y'  Source: https://ola.hallengren.com [SQLSTATE 01000] (Message 50000)  Date and time: 2016-12-11 04:10:11  Database: []  Status: ONLINE  Standby: No  Updateability: READ_WRITE  User access: MULTI_USER  Is accessible: Yes  Recovery model: FULL  Differential base LSN: 151862000023530400068  Last log backup LSN: 151862000025621600001 [SQLSTATE 01000] (Message 50000)  Date and time: 2016-12-11 04:10:11  Command: DECLARE @ReturnCode int EXECUTE @ReturnCode = [master].dbo.xp_create_subdir N'\\' IF @ReturnCode <> 0 RAISERROR('Error creating directory.', 16, 1) [SQLSTATE 01000] (Message 50000)  Outcome: Succeeded  Duration: 00:00:00  Date and time: 2016-12-11 04:10:11 [SQLSTATE 01000] (Message 50000)  Date and time: 2016-12-11 04:10:11  Command: BACKUP DATABASE [EDDS2623458] TO DISK =  WITH CHECKSUM, OMPRESSION, BUFFERCOUNT = 256, MAXTRANSFERSIZE = 2097152 [SQLSTATE 01000] (Message 50000)  Processed 388889392 pages for database '', file '' on file 1. [SQLSTATE 01000] (Message 4035)  Processed 56314928 pages for database '', file '' on file 1. [SQLSTATE 01000] (Message 4035)  Processed 2 pages for database '', file '' on file 1. [SQLSTATE 01000] (Message 4035)  The operating system returned the error '1359(An internal error occurred.)' while attempting 'SetEndOfFile' on ''. [SQLSTATE 42000] (Error 3634)  BACKUP DATABASE is terminating abnormally. [SQLSTATE 42000] (Error 3013)  Outcome: Failed  Duration: 01:45:31  Date and time: 2016-12-11 05:55:42 [SQLSTATE 01000] (Message 50000)  Date and time: 2016-12-11 05:55:42 [SQLSTATE 01000] (Message 50000).  The step failed.


When performing a backup dump using compression we may get an error like this.

It doesn’t always happen every backup. The problem appears to be related to the way that SQL server creates the backup file. When using compression, the SQL server pre-allocates space for the backup file and the data is then written into it. Since the data is compressed the backup takes less space than was allocated and SQL server instructs the filesystem to truncate the file (set the end of the file). On local disk this can happen quickly but over a network to a share it can take longer.


When the backup file is written to a SMB share the truncation can take longer than expected, especially if the amount of data to be truncated is quite large (i.e. it was compressed quite alot) and the request can timeout.


Resolution :

We can tweak the timeout by adding the following registry entry:

1. Click Start, click Run, type regedit.exe, and then click OK.
2. In Registry Editor, locate and then right-click the following registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters
3. On the Edit menu, point to New, and then click DWORD Value.
4. Type SessTimeout, and then press ENTER.
5. On the Edit menu, click Modify.
6. In the Edit DWORD Value dialog box, click Decimal under Base, type 300 under Value data, and then click OK.

The default SessTimeout setting is 50 seconds. This changes it to 300 seconds (5 minutes).

For more information check out:

The function used to truncate the file is SetEndOfFile :

Tuesday, 3 January 2017

Check the Active Cluster Node

 SELECT srvname as InstanceName , (CONVERT(varchar(200), (SERVERPROPERTY('ComputerNamePhysicalNetBIOS')))) ActiveNode , GETDATE ( ) CurrentDate from sys.sysservers where srvid=0 

Monday, 2 January 2017

Send an alert email whenever SQL Cluster Fail over happens

Pre requisites :

1. Database Mail should be configured
2. Need to have a valid SMTP server to send the mail

Steps as below.

1. Configure the Database Mail

      Refer Below Link

2. Create a Procedure

3. Create Table

3. Create a Job
         Step 1. Execute procedure to update the Table
         Step 2. EXEC msdb.dbo.sp_send_dbmail.


Concept :

                 One should get an alert email, whenever SQL Cluster fail over to other Node.
I have created a Table and hard coded the existing Instance Name and Active Cluster Node information in a table. There is an additional column with value as 1 for all the Active node instance and rest with value zero. So, whenever fail over happens Zero value for the respective Active node will get value as 1 and existing 1 as zero. While sending a mail, all active node instances will be selected.


Table is created on a centralized Server. All other servers will update data on the same. 

USE [DBA_Admin]
GO

/****** Object:  Table [dbo].[Current_AcitveCluster_Node]    Script Date: 1/2/2017 7:11:46 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Current_AcitveCluster_Node](
[ActiveNode] [char](30) NULL,
[InstanceName] [char](30) NULL,
[Status] [bit] NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

Procedure is created on all individual instance. 

USE [DBA_Admin]
GO
/****** Object:  StoredProcedure [dbo].[usp_CheckActiveNode]    Script Date: 1/2/2017 7:14:52 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_CheckActiveNode]
AS
BEGIN


SELECT srvname InstanceName
, (CONVERT(varchar(200), (SERVERPROPERTY('ComputerNamePhysicalNetBIOS'))))            NewNodeName
,  GETDATE ( )  CurrentDate
into #NewData
from sys.sysservers
where srvid=0

update [LinkedServer].DBA_Admin.dbo.Current_AcitveCluster_Node
set status = 0
where instancename = (select InstanceName from #NewData)
and status = 1

update [LinkedServer].DBA_Admin.dbo.Current_AcitveCluster_Node
set status = 1
from [LinkedServer].DBA_Admin.dbo.Current_AcitveCluster_Node O
join #NewData N
on N.InstanceName = O.InstanceName
and O.activeNode = N.NewNodeName


if object_id('tempdb..#NewData') is not null
drop table #NewData

END




Job is created on all individual instance. 


USE [msdb]
GO

/****** Object:  Job [SQL Alert for Cluster Failover]    Script Date: 1/2/2017 7:16:40 AM ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object:  JobCategory [[Uncategorized (Local)]]    Script Date: 1/2/2017 7:16:40 AM ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)
EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'SQL Alert for Cluster Failover',
@enabled=1,
@notify_level_eventlog=3,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'Send an alert mail whenever Failover happen on the SQL Cluster.',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [Update the Table]    Script Date: 1/2/2017 7:16:40 AM ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Update the Table',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=3,
@on_success_step_id=0,
@on_fail_action=3,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXEC  [dbo].[usp_CheckActiveNode]',
@database_name=N'DBA_Admin',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [Send an alert mail]    Script Date: 1/2/2017 7:16:40 AM ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Send an alert mail',
@step_id=2,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXEC msdb.dbo.sp_send_dbmail
@profile_name = ''SQLProfile'',
@recipients=''DBTeam@XYZ.com'',
@query = ''set nocount on select InstanceName, ActiveNode from [LinkedServer].[DBA_Admin].[dbo].Current_AcitveCluster_Node_backup where status=1'',
@Body=''SQL Server Failed over to other Node. Find the Cluster Node details below.'',
@from_address= ''DBTeam@XYZ.com'',
@subject=''SQL Cluster Failover Alert'',
@execute_query_database = ''DBA_Admin''',
@database_name=N'DBA_Admin',
@flags=16
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'Starts when SQL Server Agent starts on Passive Node',
@enabled=1,
@freq_type=64,
@freq_interval=0,
@freq_subday_type=0,
@freq_subday_interval=0,
@freq_relative_interval=0,
@freq_recurrence_factor=0,
@active_start_date=20161223,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959,
@schedule_uid=N'6dbda10f-3d49-4da7-9bcc-1d44a7eef1a6'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:

GO