Showing posts with label SQL Server 2008R2. Show all posts
Showing posts with label SQL Server 2008R2. Show all posts

5/23/12

SQL - Calculate Business Hours Minus Holidays


Calculating Business Hours 


I was recently tasked with generating SSRS reports against a Microsoft System Center Service Manager data warehouse. The reports require that only business hours be used to extract things like how long a service management ticket was worked etc. In my case the service desk is open M-F from 7:30 to 4:30 and no weekends or Federal Holidays. I expected to find a number of good examples with a few searches but nothing came up that fit my needs exactly.

Here's a quick rundown of how I was able to satisfy the reporting requirements.

First - create a new table to store the work week hours including Saturday and Sunday, this table will be used whenever a query is generated to determine how many hours fall within the "open" hours of the service desk.

I started the process with some examples I gathered here - http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=74645 I then extended the examples to include Holidays and fix the queries when the start date and end date were on the same day.

Open SQL Management Studio and attach to the database you wish to add this new table to, paste the following SQL code into the query and execute.

CREATE TABLE [dbo].[ttr_calendar] (
[day_number] [varchar] (50) NOT NULL ,
[day_name] [varchar] (50) NULL ,
[begin_time] [datetime] NULL ,
[end_time] [datetime] NULL ,
[duration] [real] NULL 
) ON [PRIMARY]

Next I'll populate the table with the hours of the service desk. Execute the following statement

insert into ttr_calendar
select 1,             'Monday',      '7:30:00 AM',    '4:30:00 PM',   32400 union all
select 2,             'Tuesday',     '7:30:00 AM',    '4:30:00 PM',   32400 union all
select 3,             'Wednesday',   '7:30:00 AM',    '4:30:00 PM',   32400 union all
select 4,             'Thursday',    '7:30:00 AM',    '4:30:00 PM',   32400 union all
select 5,             'Friday',      '7:30:00 AM',    '4:30:00 PM',   32400 union all
select 6,             'Saturday',    '7:30:00 AM',    '4:30:00 PM',   0 union all
select 7,             'Sunday',      '7:30:00 AM',    '4:30:00 PM',   0

For brevity I'll just link the F_Table_Date function that I used in conjunction with the other tables, this code will need to be copied and executed on our SQL instance, this will generate a function that is used in the query.


Function F_TABLE_DATE is a multistatement table-valued function that returns a table containing a variety of attributes of all dates from @FIRST_DATE through @LAST_DATE. In short, it’s a calendar table function.

Next I need to create a table to store the Holiday information - Note: This table will have to be manually populated with your holiday information, simply add a title i.e. Christmas, New Years, etc. and the date in the following format 12/25/2012.


USE [DWDataMart] /* <--Your Database Name */
GO

/****** Object:  Table [dbo].[ttr_Holiday]    Script Date: 05/22/2012 14:37:53 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[ttr_Holiday](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Date] [date] NOT NULL,
 CONSTRAINT [PK_ttr_Holiday] PRIMARY KEY CLUSTERED 
(
[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

Now that all the pieces are in place I can generate the actual query that will return my business hours minus Holidays.

declare @start_date datetime,
@end_date datetime,
@temp int

select @start_date = '24 May 2012 07:30:00 AM',
@end_date = '29 May 2012 04:30:00 PM'
Select @temp = COUNT(ttr_holiday.date)*9 from ttr_holiday where ttr_holiday.date Between @start_date and @end_date 
select @temp, total_hours = sum(case
when dateadd(day, datediff(day, 0, @start_date), 0) = dateadd(day, datediff(day, 0, @end_date), 0) then
CASE
WHEN CONVERT(VARCHAR(8),@start_date,108) < '07:30:00 AM' and CONVERT(VARCHAR(8),@end_date,108) > '16:30:00'
THEN  
datediff(second, [DATE] + begin_time, [DATE] + end_time)
WHEN CONVERT(VARCHAR(8),@start_date,108) < '07:30:00 AM' and CONVERT(VARCHAR(8),@end_date,108) < '16:30:00'
THEN  
datediff(second, [DATE] + begin_time, @end_date)
WHEN CONVERT(VARCHAR(8),@start_date,108) > '07:30:00 AM' and CONVERT(VARCHAR(8),@end_date,108) < '16:30:00'
THEN  
datediff(second, @start_date, @end_date)
WHEN CONVERT(VARCHAR(8),@start_date,108) > '07:30:00 AM' and CONVERT(VARCHAR(8),@end_date,108) > '16:30:00'
THEN  
datediff(second, @start_date, [DATE] + end_time)
END
when [DATE] = dateadd(day, datediff(day, 0, @start_date), 0) then
case
when @start_date > [DATE] + begin_time then datediff(second, @start_date, [DATE] + end_time)
else duration
end
when [DATE] = dateadd(day, datediff(day, 0, @end_date), 0) then
case
when @end_date <  [DATE] + end_time then datediff(second, [DATE] + begin_time, @end_date)
else duration
end
else duration
end
 ) 
 
/ 60.0 / 60.0 - @temp
from F_TABLE_DATE(@start_date, @end_date) d inner join ttr_calendar c
on d.WEEKDAY_NAME_LONG = c.day_name

This query will also take into account the start date and end date being on the same day, in several examples that I looked at this part would not return the correct results.

I hope this post helps with calculating business hours.



11/30/11

Microsoft Sysprep - Which Servers/Roles/Applications include support



This might not be big news to anyone reading this article but I just found out that Microsoft does not support using Sysprep on several of its own products.

I learned this while digging through the Lync 2010 documentation for a project that I'm currently working on. This got me thinking about other things that might not be supported when using Sysprep, until now I thought that as long as you used Sysprep you would not be compromising Microsoft support.

In this article I will try and list the details of what is and isn't supported by Microsoft when it comes to Sysprep. 

Microsoft does not support using Sysprep with Lync 2010, SQL Server 2008 Express and several other products, what does this mean? It means that you can use Sysprep to clone the Windows Operating system as long as you verify that no non-supported roles are enabled prior to cloning (see table below). It means do not have any of the non-supported application's components installed/configured prior to making the clone.

For Server 2008R2 only certain roles of the operating system support using Sysprep, in other words if you are going to clone a 2008 R2 machine, make sure none of the roles listed below that say no are enabled.
Server Role
Sysprep Support
Active Directory Certificate Server (AD CS)
No
Active Directory Domain Services (AD DS)
No
Active Directory Federation Services (AD FS)
No
Active Directory Lightweight Directory Services (AD LDS)
No
Active Directory Rights Management Server (AD RMS)
No
Application Server
Yes
DHCP Server
Yes
DNS Server
No
Fax Server
No
File Services
No
Network Policy and Access Services
No
Network Policy Routing and Remote Access Services
Yes
Print Services
No
Terminal Services
Yes
Not supported in scenarios where the master Windows image is joined to a domain.
UDDI Services
No
Web Server (Internet Information Services)
Yes
Does not support Sysprep with encrypted credentials in applicationhost.config.
Windows Deployment Services
No

Sharepoint 2010 - A Sysprep'd machine can be created with Sharepoint 2010 installed but must be prior to the configuration wizard being run.


SQL Server 2008R2 - There is an MSDN article explaining how to install SQL on a Sysprep'd image - Here

Microsoft Exchange Server - You cannot Sysprep an Exchange machine because of its integration with Active Directory. Recommended method would be to Sysprep the operating system and automate the installation.

Domain ControllersYou cannot deploy preconfigured domain controllers by using image-based installation with Sysprep. However, you can configure a domain controller by first deploying a member server and then automatically running a script that runs Dcpromo.exe, the Active Directory Installation Wizard.

Limited server configuration - According to Microsoft some server components must be installed and configured after an image-based installation with Sysprep is complete. These components include Certificate Services, Cluster service, and any software that is dependent on the Active Directory directory service. They also include any application or service that stores the computer name or the computer SID and cannot recover if the computer name or SID changes.


Security SettingsYou cannot use image-based installation with Sysprep to deploy computers that contain any files that are encrypted by using Encrypting File System (EFS). In addition, you cannot use image-based installation to deploy systems that have already been configured with NTFS security settings, such as file and folder permissions, unless the disk-imaging program supports the NTFS file system. However, you can use a script to configure these settings after the image-based installation is complete.

I usually opt to build fresh virtual machines and not Sysprep because of these kind of incompatibilities and to rule out strange behavior potentially caused by cloning machines.

I'll continue to update this post if I find any other incompatibilities, please feel free to respond if you know of any other incompatible software.