2011 | SansSQL

Monday, December 5, 2011

Granting Read-Only and administrative access to Central Management Server (CMS)

In one of my previous post, I had discussed about the Central Management Server and how to Register it.
In this post, I will be telling how to give read-only access and a Administrative access to an existing CMS.

Grating the Read-Only and Administrative access to CMS is very simply and the activity includes adding the right database users to right groups in msdb database.

Granting Read-Only access:
USE [msdb]
GO
CREATE USER [DBUserName] FOR LOGIN [LoginName]
GO
EXEC sp_addrolemember N'ServerGroupReaderRole', N'DBUserName'
GO

Granting Administrator access:
This access is usually give to the DBA's
USE [msdb]
GO
CREATE USER [DBAUserName] FOR LOGIN [DBALoginName]
GO
EXEC sp_addrolemember N'ServerGroupAdministratorRole', N'DBAUserName'
GO

Sunday, December 4, 2011

Give access to a non sysadmin user to run Profiler

Sometimes as a DBA, you come across a situation where you need to give access to a non sysadmin user to run profiler on a particular SQL server.
If you try to run the profiler using the user who does not have sysadmin access then you will get the below error.

Here is the solution how to grant access to a non sysadmin user to run profiler.
Using Query: 
-- To Grant access to a Windows Login
USE master;
GRANT ALTER TRACE TO [Domain\WindowsLogin]

-- To Grant access to a SQL Login
USE master;
GRANT ALTER TRACE TO [SQL User]

Using SSMS:

  1. Expand the Server in object Explorer
  2. Expand "Security" folder and then "logins"
  3. Right-Click on the login to which you need to give access and then go to "Properties" of that login
  4. Go to "Securables" Tab
  5. Select the server you want to add the permission
  6. In the "Permission for <Server Name>" block, click on "Grant" check box for "Alter Trace" and click "OK"
  7. Once this is completed, the permission should appear in the "Effective" Tab

Note: The Granter should be a sysadmin user.  

Friday, November 25, 2011

Convert Rows to Column using COALESCE() function

Using the below query we can convert the rows to column sperated by a delimiter.
In the query I am using ';' as the delimiter and you can change the delimiter of your choice by replacing ';'.
Data from Table:
Query:
Use AdventureWorks2008R2
GO
DECLARE @eMailList nvarchar(max) 

SELECT @eMailList = COALESCE(@eMailList + ';', '') + 
   CAST(eMail AS nvarchar(max))
FROM Employees

Select @eMailList as eMailList

Output of the above Query:

Friday, November 18, 2011

Microsoft SQL Server 2012 Release Candidate 0 (RC0) - Available for Download

Microsoft SQL Server 2012 RC0 enables a cloud-ready information platform that will help organizations unlock breakthrough insights across the organization as well as quickly build solutions and extend data across on-premises and public cloud backed by capabilities for mission critical confidence.
To read more and download Microsoft SQL Server 2012 RC0 click here.

Tuesday, September 27, 2011

Backup Database to multiple locations simultaneously - Mirror Backups

Database backup is one the regular activity a DBA would perform. Some times you might come across a situation where in you need to backup the database to different location. When I say backup database to different locations, it means that a copy of backup file needs to be placed on a different location as well and this is different from the Split Backups.
This is can be achieved by different methods,
  1. Take backup and then copy to multiple location
  2. Take backup of the same database multiple times pointing to different locations
  3. Use "MIRROR TO" Option in the Backup command 
Using the option "MIRROR TO" is very simple, you just need to mention "MIRROR TO" and "WITH FORMAT" options in the normal BACKUP DATABASE Statement and you are done. The backup database statement with these two options will take the backup of the same database to multiple locations at the same time.
This option "MIRROR TO" is introduced in SQL Server 2005 and this works only in SQL Server 2005 Enterprise Edition and later versions.
This can be used for all backup types and the Maximum number of "MIRROR TO" clauses that you can specify is three.
Example
BACKUP DATABASE AdventureWorks
TO DISK = 'C:\Backup\AdventureWorks_Full.bak'
MIRROR TO DISK = 'C:\Mirror\AdventureWorks_Full.bak'
WITH STATS=10, FORMAT

BACKUP DATABASE AdventureWorks
TO DISK = 'C:\Backup\AdventureWorks_Differential.bak'
MIRROR TO DISK = 'C:\Mirror\AdventureWorks_Differential.bak'
WITH STATS=10, DIFFERENTIAL, FORMAT

BACKUP LOG AdventureWorks
TO DISK = 'C:\Backup\AdventureWorks_log.trn'
MIRROR TO DISK = 'C:\Mirror\AdventureWorks_log.trn'
WITH STATS=10, FORMAT



When it comes to restoring the database, we can use either of the backup copies to restore or recover the database.

Friday, September 16, 2011

Hide an Instance of SQL Server Database Engine

In one of my previous post "List of SQL Server instances currently installed in your network", I explained how to get the list of SQL server instances installed in your network.
Sometimes you might require an SQL Server instance to be not exposed to others due to some security reason. This can be done by using the "Hide" option available for an SQL Server instance.
Before Hiding an Instance:

Steps to Hide an Instance of SQL Server Database Engine
  1. Go to "SQL Server Configuration Manager"
  2. In the Left Pane Expand "SQL Server Network Configuration"
  3. Now Right Click on "Protocols for <ServerName>" and go to Properties for the server you need to hide.
  4. In the "Flags" Tab, change the option to "Yes" for "Hide Instance"
  5. Click on "Apply" and "OK"
  6. Now re-start the SQL Server Service for this Instance and you are done. This instance from now will be hidden.
After Hiding an Instance:

Friday, September 2, 2011

Get last backup details of all databases in a server

This stored procedure give you the information about latest backups happened on all databases in a server.
This SP works for SQL server 2005 and up.
Create Proc sp_BackupDetails
AS
DECLARE @BackupDetails table
([Server Name] nvarchar(500),
[Database Name] nvarchar(500),
[Last Full Backup] nvarchar(500),
[Last Differential Backup] nvarchar(500),
[Last Log Backup] nvarchar(500),
[Last File or filegroup Backup] nvarchar(500),
[Last Differential file Backup] nvarchar(500),
[Last Partial Backup] nvarchar(500),
[Last Differential Partial Backup] nvarchar(500)
)

DECLARE @DBName nvarchar(500)
Declare DBName Cursor for
Select name from sys.databases
Open DBName
Fetch Next from DBName into @DBName
While @@fetch_status = 0
BEGIN
Insert into @BackupDetails
select @@ServerName as [Server Name]
       ,SDB.name AS [Database Name]
       ,(select COALESCE(Convert(nvarchar(20), MAX(backup_finish_date), 100),'NA') from msdb..backupset where database_name=@DBName and type='D') AS [Last Full Backup]
       ,(Select COALESCE(Convert(nvarchar(20), MAX(backup_finish_date), 100),'NA') from msdb..backupset where database_name=@DBName and type='I') AS [Last Differential Backup]
       ,(Select COALESCE(Convert(nvarchar(20), MAX(backup_finish_date), 100),'NA') from msdb..backupset where database_name=@DBName and type='L') AS [Last Log Backup]
       ,(Select COALESCE(Convert(nvarchar(20), MAX(backup_finish_date), 100),'NA') from msdb..backupset where database_name=@DBName and type='F') AS [Last File or filegroup Backup]
       ,(Select COALESCE(Convert(nvarchar(20), MAX(backup_finish_date), 100),'NA') from msdb..backupset where database_name=@DBName and type='G') AS [Last Differential file Backup]
       ,(Select COALESCE(Convert(nvarchar(20), MAX(backup_finish_date), 100),'NA') from msdb..backupset where database_name=@DBName and type='P') AS [Last Partial Backup]
       ,(Select COALESCE(Convert(nvarchar(20), MAX(backup_finish_date), 100),'NA') from msdb..backupset where database_name=@DBName and type='Q') AS [Last Differential Partial Backup]
from sys.databases SDB
where SDB.name =@DBName
Fetch Next from DBName into @DBName
END
Close DBName
DEALLOCATE DBName

Select * from @BackupDetails
GO

Usage:
Exec sp_BackupDetails
go

Results:

Thursday, September 1, 2011

Denali CTP 3 - Show\Hide Results Pane keyboard shortcut not working - Ctrl+R not working

Recently I installed Denali CTP 3 version and was writing a code which is coming next in this blog. During that time I attempted to hide the results pane using the keyboard shortcut Ctrl+R and was surprised that the keyboard shortcut Ctrl+R was not working. When I investigated further I found that that the keyboard shortcut was not assigned to the command "Hide Results Pane".
To fix this issue or to assign the keyboard shortcut to the command "Hide Results Pane", follow the below steps.
  1. In a SSMS window, go to "Tools" menu and choose "Options".
  2. In the left pane of "Options" window, expand "Environment" and then click on "Keyboard".
  3. In the right pane, Search for the command "Window.ShowResultsPane" Under "Show Commands Containing:" section and select that command
  4. Now, Under "Shortcuts for selected command:" section choose "SQL Query Editor" from the dropdown list of "Use new shortcut in:" sub-section.
  5. In the "Press shortcut keys:" sub-section place the cursor and press the keys "Ctrl" followed by "R" 
  6. Click on "Assign" button and click "OK" to exit the "Options" menu and start using the keyboard shortcut "Ctrl+R" to Hide\Show Results Pane. 


Sunday, August 14, 2011

Looping through SQL Servers using SSIS or Dynamically build connection to multiple SQL Servers

Consider you are giver a task of gathering information from multiple servers. What are the different ways you can automate this?
  1. Create linked servers in each server pointing to your central repository
  2. Create Separate SSIS package in each servers which loads data to your central repository
  3. Create one SSIS package with multiple data sources and duplicate the tasks for each data source.
  4. Create one SSIS package which dynamically builds connection to each server and does the data loading tasks.
If you choose an option between 1 and 3 , then  you will have to do some extra work for gathering the server information when there are new servers added to your environment.
If you choose the 4th option then also you will have some extra work but it is very small and easy when compared to the first 3 options. Here you need to just add the new Server Names to the table and that is all and everything else will be taken care by the SSIS package.
In this post I am going to explain how to create a SSIS package which loops through multiple SQL server and gathers information  by building the connection to those servers dynamically.
  1. Open “Microsoft Visual Studio”
  2. Create a new “Integration Services Project”
  3. Create a SSIS Package
  4. Create 2 Connection Managers, 1 for the source (which will be set dynamically for each iteration of the loop)  and the other for destination (which will remain constant, in other terms your Central Repository)
  5. Store All your Server Names in a table preferably in the Central Repository (Destination Connection)
  6. Add 2 variables
  7.     a. Name: ConnectionVariable (A name of your choice)
            Scope: Package
            Type: Object
            Value: System.Object
        b. Name: ServerName  (A name of your choice)
            Scope: Package
            Type: String
            Value: A Valid Server Name

  8. Add an "Execute SQL Task" with SQL Statement like "select FullName from dba..tbl_ListOfServers".
  9. Set the result set to Full Result Set.
  10. On the Result Set page, Add a Result 
  11. Set Result Name "0" and assign it to your Object variable (In our case it is “ConnectionVariable”).
  12. Now add a “Foreach Loop Container” 
  13. Connect it from the “Execute SQL Task”
  14. Inside the “Foreach Loop Container” , add the required “Data Flow Task”
  15. Now Right-Click on the “Foreach Loop Container” and click on “Edit”
  16. Now Go to “Collection” page and Set “Enumerator” to “Foreach ADO Enumerator” and “Enumerator Configuration ” to the Object Variable(In Our Case “ConnectionVariable”) and Set “Enumeration Mode” to “Rows in the First Table”
  17. Now go to the “Variable Mapping” page and Choose the “String Variable” (In our case it is “ServerName”) and set the Index=0
  18. Now, in the “Data Flow Task” add a “OLE DB Source” (Dynamic Connection) and connect it down to a “OLE DB Destination” (which will be your Central Repository).
  19. Now Select the Source Connection Manager (In Our Case it is “Source”) and Right-Click on this Source and choose “Properties”.
  20. Expand the “Expressions” Option and click on the browse button (…)
  21. Now in the “Property Expression Editor”, Choose the property “ServerName” and click on browse button (…). Now choose the String Variable (in our case “ServerName”) and Drag and Drop this variable into the “Expression” box and click “OK” and “OK”.


Now when the package runs, the “Execute SQL Task” will read the list of servers and stored in the table you specified and the “Foreach loop” will iterate over each record in that table, running the “Data Flow Task” each time while each time, the ServerName property of the Source Connection in the data flow will get a new value.

This article is also available in pdf format for downloading.
Please Click here to get your copy.

Sunday, August 7, 2011

Finding space usage of database files

DBA's are required to watch the space usage of database files in order to take preventive measures of future failures with respect to database full issues.
This will be usually required when there is a bulk activity happening on a database.
To do this make use of the below stored procedure.
Create this SP in a database and execute it in regular intervals to get the latest status of the database files.
This can be used to view the space usage of all the database files or for a particular threshold value.
Use master
GO
Create proc sp_SpaceUsageReport (@Threshold int=80)
as

CREATE TABLE tempdb..SpaceUsage (
  DatabaseName nvarchar(100)
 ,LogicalFileName nvarchar(500)
 ,FileType nvarchar(10)
 ,PhysicalFileLocation nvarchar(500)
 ,[FileSize (MB)] float
 ,[SpaceUsed (MB)] float
 ,[FreeSpace (MB)] float
 ,[% Used] AS 100-(([FileSize (MB)]-[SpaceUsed (MB)])/[FileSize (MB)])*(100)
 ,[% Free]  AS (([FileSize (MB)]-[SpaceUsed (MB)])/[FileSize (MB)])*(100) )

If (SELECT Convert(varchar(1),(SERVERPROPERTY('ProductVersion')))) = 8
BEGIN
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO tempdb..SpaceUsage(DatabaseName
           ,LogicalFileName
           ,FileType
           ,PhysicalFileLocation   
           ,[FileSize (MB)]
           ,[SpaceUsed (MB)]
           ,[FreeSpace (MB)])
SELECT DB_NAME() AS DatabaseName
       ,name AS LogicalFileName
       ,FileType = CASE WHEN FILEPROPERTY(name,''IsLogFile'')=0 THEN ''Data File'' WHEN FILEPROPERTY(name,''IsLogFile'')=1 THEN ''Log File'' END
       ,filename AS PhysicalFileLocation
       ,CONVERT(float,ROUND(size/128.000,2)) AS [FileSize (MB)]
       ,CONVERT(float,ROUND(FILEPROPERTY(name,''SpaceUsed'')/128.000,2)) AS [SpaceUsed (MB)]
       ,CONVERT(float,ROUND((size-FILEPROPERTY(name,''SpaceUsed''))/128.000,2)) AS [FreeSpace (MB)]
FROM dbo.sysfiles
ORDER BY FileType '
END

If (SELECT Convert(varchar(1),(SERVERPROPERTY('ProductVersion'))))<> 8
BEGIN
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO tempdb..SpaceUsage(DatabaseName
           ,LogicalFileName
           ,FileType
           ,PhysicalFileLocation
           ,[FileSize (MB)]
           ,[SpaceUsed (MB)]
           ,[FreeSpace (MB)])
SELECT DB_NAME() AS DatabaseName
            ,name AS LogicalFileName
            ,FileType = CASE WHEN type_desc =''Rows'' THEN ''Data File'' WHEN type_desc =''LOG'' THEN ''Log File'' END
            ,physical_name AS PhysicalFileLocation
            ,CONVERT(float,ROUND(size/128.000,2)) AS [FileSize (MB)]
            ,CONVERT(float,ROUND(FILEPROPERTY(name,''SpaceUsed'')/128.000,2)) AS [SpaceUsed (MB)]
            ,CONVERT(float,ROUND((size-FILEPROPERTY(name,''SpaceUsed''))/128.000,2)) AS [FreeSpace (MB)]
FROM sys.database_files
ORDER BY FileType'
END

if (Select COUNT(*) from tempdb..SpaceUsage where [% Used]>@Threshold)>0
Begin
/* -- Enable this Content if you want to send email.

DECLARE @table  NVARCHAR(MAX),@Subject Nvarchar(500) ;
Set @Subject='[SQLAlert] Database Files Space Threshold exceeded Report from ' + CAST(@@SERVERNAME as nvarchar)
SET @table =
    N'<H1>Threshold Value for this Report is '+CAST(@Threshold AS nvarchar)+' Percentage. </H1>' +
    N'<table border="1">' +
    N'<tr><th>DatabaseName</th><th>FileType</th><th>PhysicalFileLocation</th><th>FileSize (MB)</th><th>% Used</th></tr> ' +
    CAST ( ( Select td=DatabaseName, '',td=FileType, '',td=PhysicalFileLocation,'',td=CAST([FileSize (MB)] as nvarchar),'',td=CAST([% Used] AS nvarchar) from tempdb..SpaceUsage where [% Used]>@Threshold
              FOR XML PATH('tr'), TYPE
    ) AS NVARCHAR(MAX) )    +
    N'</table>' ;

EXEC msdb.dbo.sp_send_dbmail @profile_name='DatabaseMail', --Change to your Profile Name
      @recipients='sandeshsegu@SansSQL.com', --Put the email address of those who want to receive the e-mail
    @subject = @Subject,
    @body = @table,
    @body_format = 'HTML' ;  
*/   

select * from  tempdb..SpaceUsage where [% Used]>@Threshold                                 
End

DROP TABLE tempdb..SpaceUsage

To send an email of this report you need to
  1. Configure Database Mail option. To configure Database mail option, follow this post.
  2. Uncomment the below content in the SP.
/* -- Enable this Content if you want to send email.

DECLARE @table  NVARCHAR(MAX),@Subject Nvarchar(500) ;
Set @Subject='[SQLAlert] Database Files Space Threshold exceeded Report from ' + CAST(@@SERVERNAME as nvarchar)
SET @table =
    N'<H1>Threshold Value for this Report is '+CAST(@Threshold AS nvarchar)+' Percentage. </H1>' +
    N'<table border="1">' +
    N'<tr><th>DatabaseName</th><th>FileType</th><th>PhysicalFileLocation</th><th>FileSize (MB)</th><th>% Used</th></tr> ' +
    CAST ( ( Select td=DatabaseName, '',td=FileType, '',td=PhysicalFileLocation,'',td=CAST([FileSize (MB)] as nvarchar),'',td=CAST([% Used] AS nvarchar) from tempdb..SpaceUsage where [% Used]>@Threshold
              FOR XML PATH('tr'), TYPE
    ) AS NVARCHAR(MAX) )    +
    N'</table>' ;

EXEC msdb.dbo.sp_send_dbmail @profile_name='DatabaseMail', --Change to your Profile Name
      @recipients='sandeshsegu@SansSQL.com', --Put the email address of those who want to receive the e-mail
    @subject = @Subject,
    @body = @table,
    @body_format = 'HTML' ;  
*/    

Usage of this SP:
This SP expects a parameter called @Threshold
If you specify the @Threshold=0 then, this SP will give space usage details of all the database files.
Exec sp_SpaceUsageReport @Threshold=0

If you specify the @Threshold=80 then, this SP will give space usage details of those database files which exceeds the threshold 80 percent.
Exec sp_SpaceUsageReport @Threshold=80

Sunday, July 24, 2011

T-SQL Query to find the list of Indexed Views in a Database

Here is the query which can be used for getting the list of Indexed views in a Database.
USE <DatabaseName>
GO
SELECT * FROM sys.objects
WHERE type='V'
and OBJECTPROPERTY(object_id,'IsIndexed')=1

Thursday, June 9, 2011

SQL Server Migration Checklist

Are you migrating your SQL Servers?
Here is a quick checklist for your SQL Server Migration.
  1. Build your New Server, Install SQL Server and required updates and keep the server ready for migration
  2. Stop Application Service(s).
    This is to ensure that the no applications are connected to the Databases during the migration process.
  3. Change the Properties of the databases that are part of Migration to "Read-only".
    This is to ensure that the data modification is not happening by any other sources.
  4.  Take a FULL backup of all the User databases that are involved in the Migration Process. 
  5. Move the backups to the destination server or a Shared location, then restore them to the appropriate drives on the destination.
  6. Change the compatibility level of the databases (Optional)
    Do this if the applications connecting to these databases are independent of the database compatibility level.
  7. Transfer logins using SSIS (Transfer Logins Task) or using "sp_help_revlogin"
    More information about sp_help_revlogin is at http://support.microsoft.com/kb/246133
  8. Check for Orphaned Users in the databases and Fix them (if Any)
  9. Update Usage on the migrated Databases
  10. Update Stats on the migrated Databases
  11. Re-Index or Re-Organize Indexes on the migrated Databases
  12. Transfer Jobs using SSIS or manually create them
  13. Build Maintenance plans (if Any)
  14. Recompile database objects if required
  15. Move or rebuild SSIS or DTS packages (if Any)
  16. Create Alerts and Operators (if Any)
  17. Setup High Availability Options (if Any Like Replication, LogShipping, Mirroring)
  18. Test the High Availability options that were setup in the previous step
  19. Point the Application(s) to new Server and start the Application Service(s)
  20. Test the Application(s)

Tuesday, June 7, 2011

SQL Server 2008 Service fails to start after Service Pack Installation

Some times you may find that the SQL Server Service is not starting after applying a service pack and when you check in the Event Viewer you find the below message.

Script level upgrade for database 'master' failed because upgrade step 'sqlagent100_msdb_upgrade.sql' encountered error 598, state 1, severity 25. This is a serious error condition which might interfere with regular operation and the database will be taken offline. If the error happened during upgrade of the 'master' database, it will prevent the entire SQL Server instance from starting. Examine the previous errorlog entries for errors, take the appropriate corrective actions and re-start the database so that the script upgrade steps run to completion.

SQL Server Setup creates a database with the data file name temp_MS_AgentSigningCertificate_Database.mdf during the installation process and if the SQL Server setup is not able to create that database in the default data path then the above error is returned as it is not able to find the path.

To fix this issue.
  1. Go to Registry editor, To open this, go to "Run" and type "regedit" and click "ok"
  2. First go to this path and make sure that the path in the key SQLDataRoot exists. If not then give a valid path to this key.
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.<instance name>\Setup
  3. Then go to this path and make sure that the path in the keys "BackupDirectory", "DefaultData" and "DefaultLog" exists. If not then give a valid path to these keys.
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.<instance name>\MSSQLServer
  4. Now you should be able to start the SQL Server Service without any issues.
Once the Service is started, verify the SQL Server, databases and others to make sure everything is fine.
Also verify if the Service pack or the CU is installed correctly.

Wednesday, June 1, 2011

Unable to start mail session (reason: No mail profile defined) - Message in Error Log

There will be many different messages that will be logged in the Error Log of SQL Server. Among them you might also find the below message some times.
Date 6/1/2011 8:18:27 AM
Log SQL Server Agent (Archive #2 - 6/1/2011 8:18:00 AM)

Message
[098] SQLServerAgent terminated (normally)
This is the most common message that will be logged when there is no "Mail Session" defined for the SQL Server Agent Alert System.

To Fix this or to make this message disappear in the Error Log, you have to enable "Mail Session" and re-start the SQL Server Agent.
To Do this,
  1. Connect to the Server
  2. Right Click on the "SQL Server Agent" and go to "Properties"  
  3. Then Go to "Alert System" Tab
  4. Make sure the check box "Enable Mail Profile" is checked 
  5. Click OK to exit
  6. Re-start the SQL Server Agent Service


Now if you again look into the Error Log you will not find this message anymore after re-starting the Agent Service.  

Tuesday, April 19, 2011

SQL Server 2011 - Zoom Query Window and Results pane - New Feature

SQL Server 2011 comes with lots of new features and here is one such new feature.
SQL Server 2011 has introduced zooming of Query window and results pane.
Query Window - Normal

Query Window - Zoomed

Results Pane - Normal

Results Pane - Zoomed

Ads