Cannot access reporting services (Denali CTP3)

This is a problem I’ve encountered many times. I do a fresh install of SQL Server, and when accessing Reporting Manager I get the error message:

“User ‘Domain\User’ does not have required permissions. Verify that sufficient permissions have been granted and Windows User Account Control (UAC) restrictions have been addressed.”

This is caused by the UAC, and is usually fixed by running IE as an administrator. However, this didn’t work for me today on my fresh install of SQL Server Denali CTP3.

What DID work, was adding another user to the amdinistrators-group, and then running IE as administrator. The weird thing is that I didn’t need to run it in the context of the new user, and my user was a member of the administrators-group the whole time.

SQL Server Denali CTP3 is out

Get it here:

https://www.microsoft.com/betaexperience/pd/SQLDCTP3CTA/enus/default.aspx

Tech Ed 2011

Here’s a great collection of MSBI related videos from Tech Ed 2011 in North America:

http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011?sort=sequential&direction=desc&term=&t=database%2B-and-%2Bbusiness%2Bintelligence

Diagrams in Management Studio

When I create new databases in SQL Server and try to make database diagrams, I always get the following error:

Database diagram support objects cannot be installed because this database does not have a valid owner. To continue, first use the Files page of the Database Properties dialog box or the ALTER AUTHORIZATION statement to set the database owner to a valid login, then add the database diagram support objects.

The solution is to set the owner of the database to “sa” or the service account for SQL Server. You can do this by the “ALTER AUTHORIZATION” statement as mentioned in the error message, or through “Properties”->”Files” on the database.

The default owner when I create new databases is my login, and after some googling around, I found that it is a good idea to always use sa as the owner, and also that it’s not possible to change the default owner on new databases.

User defined function (T-SQL) for finding work days and holidays – Norwegian Edition

In my last blog post I published a handy stored procedure for populating a time dimension in SQL Server 2008. The stored procedure makes use of a UDF called dbo.fIsWorkDay(@Date). This function returns a boolean value saying if the date parameter is a work day or not. The following two functions are specific for Norwegian holidays:

T-SQL procedure for finding easter sunday (Found here: http://www.mssqltips.com/tip.asp?tip=1537):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
IF OBJECT_ID('fEasterByYear',N'FN') IS NOT NULL DROP FUNCTION fEasterByYear
 
GO
 
CREATE FUNCTION [dbo].[fEasterByYear] (@Year SMALLINT) RETURNS DATE AS
BEGIN 
	DECLARE
		@c INT,
		@n INT,
		@k INT, 
		@i INT, 
		@j INT, 
		@l INT, 
		@m INT, 
		@d INT, 
		@Easter DATE 
 
	SET @c = (@Year / 100) 
	SET @n = @Year - 19 * (@Year / 19) 
	SET @k = (@c - 17) / 25 
	SET @i = @c - @c / 4 - ( @c - @k) / 3 + 19 * @n + 15 
	SET @i = @i - 30 * ( @i / 30 ) 
	SET @i = @i - (@i / 28) * (1 - (@i / 28) * (29 / (@i + 1)) * ((21 - @n) / 11)) 
	SET @j = @Year + @Year / 4 + @i + 2 - @c + @c / 4 
	SET @j = @j - 7 * (@j / 7) 
	SET @l = @i - @j 
	SET @m = 3 + (@l + 40) / 44 
	SET @d = @l + 28 - 31 * ( @m / 4 ) 
 
	SET @Easter = CAST((SELECT CONVERT(CHAR(4),@Year) + '-' + RIGHT('0' + CONVERT(VARCHAR(2),@m),2) + '-' + RIGHT('0' + CONVERT(VARCHAR(2),@d),2) + 'T00:00:00') AS DATE)
 
	RETURN @Easter 
END

Calculating work day:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
IF OBJECT_ID('fIsWorkday',N'FN') IS NOT NULL DROP FUNCTION fIsWorkDay
 
GO
 
CREATE FUNCTION [dbo].[fIsWorkDay] (@Date DATE) RETURNS BIT AS
BEGIN
	DECLARE @IsWorkDay BIT = 1
 
	SELECT @IsWorkDay = 
	CASE
		--Exclude Saturday and Sunday (Datefirst-independent)
		WHEN ((@@DATEFIRST + DATEPART(dw,@Date)) % 7) IN (0,1) THEN 0 
		--Exclude National Day
		WHEN MONTH(@Date)=5 AND DAY(@Date)=17 THEN 0
		--Exclude Workers' Day
		WHEN MONTH(@Date)=5 AND DAY(@Date)=1 THEN 0
		--Exclude Christmas
		WHEN MONTH(@Date)=12 AND DAY(@Date) IN (25,26) THEN 0
		--Exclude New Years
		WHEN MONTH(@Date)=1 AND DAY(@Date)=1 THEN 0
		--Exclude Easter, Pentecost and Ascension of Jesus
		WHEN @Date IN (
			DATEADD(DAY,-3,dbo.fEasterByYear(YEAR(@Date))),
			DATEADD(DAY,-2,dbo.fEasterByYear(YEAR(@Date))),
			DATEADD(DAY,1,dbo.fEasterByYear(YEAR(@Date))),
			DATEADD(DAY,39,dbo.fEasterByYear(YEAR(@Date))),
			DATEADD(DAY,50,dbo.fEasterByYear(YEAR(@Date)))
			) THEN 0
		ELSE 1
	END
 
	RETURN @IsWorkDay
END

Stored procedure for generating and populating a time dimension in SQL Server

There are many was to generate time dimensions (calendar) for use in a multi dimensional data warehouse. Kimball suggests writing the dates in an Excel workbook and load that into the data warehouse. I prefer to populate the time dimension using a stored procedure contained in the DWH.

Regarding primary key for the time dimension, I usually use an 4 byte integer with the format YYYYMMDD. I prefer this over using a 3 byte date column, as I then have the possibility to use negative primary keys with special meanings.

Creating the table:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
IF OBJECT_ID('DimCalendar',N'U') IS NOT NULL DROP TABLE DimCalendar
 
CREATE TABLE [DimCalendar] (
	[DateKey] [INT] NOT NULL PRIMARY KEY,
	[Date] [DATE] NOT NULL,
	[Day] [TINYINT] NOT NULL,
	[Week] [TINYINT] NOT NULL,
	[Month] [TINYINT] NOT NULL,
	[Year] [SMALLINT] NOT NULL,
	[WeekYear] [SMALLINT] NOT NULL,
	[WeekdayName] [VARCHAR](10) NOT NULL,
	[WeekdayNameShort] [VARCHAR](3) NOT NULL,
	[MonthName] [VARCHAR](20) NOT NULL,
	[MonthNameShort] [VARCHAR](3) NOT NULL,
	[Quarter] [TINYINT] NOT NULL,
	[Workday] [BIT] NOT NULL,
	[WorkHours] [DECIMAL](6,2) NOT NULL
)

Populating the table:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
IF OBJECT_ID('sPopulateDimCalendar',N'P') IS NOT NULL DROP PROCEDURE sPopulateDimCalendar
 
GO
 
CREATE PROCEDURE sPopulateDimCalendar
 
@FromDate DATE = '1990-01-01',
@ToDate DATE = '2020-12-31'
 
AS
 
BEGIN
 
--Setting language
SET LANGUAGE English
 
--Populating Dimension
WHILE @FromDate <= @ToDate
	BEGIN
		INSERT INTO DimCalendar(
			[DateKey], 
			[Date], 
			[Day], 
			[Week], 
			[Month], 
			[Year], 
			[WeekYear], 
			[WeekdayName], 
			[WeekdayNameShort], 
			[MonthName], 
			[MonthNameShort], 
			[Quarter],
			[WorkDay],
			[WorkHours]
            )
            SELECT 
                YEAR(@FromDate)*10000 + MONTH(@FromDate) * 100 + DAY(@FromDate) AS DateKey, 
		@FromDate AS [Date],
                DAY(@FromDate) AS [Day],
		DATEPART(ISO_WEEK, @FromDate) AS [Week],
                MONTH(@FromDate) AS [Month],
                YEAR(@FromDate) AS [Year],
		CASE 
			WHEN DATEPART(ISO_WEEK, @FromDate) = 53 AND MONTH(@FromDate) = 1 THEN YEAR(@FromDate) - 1 
			WHEN DATEPART(ISO_WEEK, @FromDate) = 1 AND MONTH(@FromDate) = 12 THEN YEAR(@FromDate) + 1
			ELSE YEAR(@FromDate) 
		END AS [WeekYear],
                DATENAME(WEEKDAY,@FromDate) AS WeekDayName,
                LEFT(DATENAME(WEEKDAY,@FromDate), 3) AS WeekDayNameShort,
                DATENAME(MONTH, @FromDate) AS MonthName,
                LEFT(DATENAME(MONTH, @FromDate), 3) AS MonthNameShort,
                DATENAME(QUARTER,@FromDate) AS [Quarter],
                dbo.fIsWorkDay(@FromDate) AS WorkDay,
                CASE WHEN dbo.fIsWorkDay(@FromDate) = 1 THEN 8 ELSE 0 END AS WorkHours
 
      SET @FromDate = DATEADD(DAY, 1, @FromDate)
END
 
END

The function dbo.fIsWorkDay(@Date) is obviously different depending on which country you are in.

Dateserial in T-SQL

If you ever have the need to use Dateserial() in T-SQL, you can use the following function:

1
2
3
4
5
SET @ReturnDate = 
CAST((SELECT 
CONVERT(CHAR(4),@Year) + '-' + 
RIGHT('0' + CONVERT(VARCHAR(2),@Month),2) + '-' + 
RIGHT('0' + CONVERT(VARCHAR(2),@Day),2) + 'T00:00:00') AS DATETIME)

This should be independent of language and dateformat settings.

Generic SSRS 2008 report to display job history of SQL Server Agent jobs

I have made a generic report in Reporting Services 2008 to browse and display the job history of SQL Server Agent. This is very useful if you want to see what jobs fail the most, when do jobs overlap, is execution time increasing for a specific job etc. If you have many jobs, it can be quite useful to set up a subscription on this report, so you can see every day the status of alle the SQL Server Agent jobs. I use this report on all SQL Server Instances i control. I also recommend increasing the number of log entries stored in the log table on msdb to increase the usefulness of the report.  The report is made in Reporting Services 2008, but the query against log data works against 2005 and up.

The user account accessing the SQL Server database needs read-acces to msdb, and the report has two parameters:

  • Search – For entering search strings. Useful if your project for example as prefixed job names with the project name
  • Include Subscriptions – This parameter is useful if SQL Server has many reporting services subscriptions running. SSRS Subscriptions has a GUID as the name of the SQL Server Agent job, so they are quite easy to filter out.

Download here: http://www.sqldisco.com/files/Jobstatus.zip

Let me know if you find it useful, or if you have any recommended improvements I can implement.

Search sql server metadata quickly

Just figured out a neat way to quickly search metadata easily when working with SQL. If you use SQL Prompt from Red Gate, I suggest adding the following as a new snippet (I use FF):

1
2
3
SELECT RTRIM(so.name) + '.' + RTRIM(sc.name) AS DBObjectName 
FROM SYSOBJECTS so INNER JOIN syscolumns sc ON so.id = sc.id
WHERE so.type = 'U' AND (sc.name+' '+so.name) LIKE '%

Very handy to always have search ready at your fingertips, especially when working with data extraction from unfamiliar databases.

MCTS 70-448

Yesterday I passed the certification exam
MCTS: Microsoft SQL Server 2008, Business Intelligence Development and Maintenance. Next up: MCTS: Microsoft SQL Server 2008, Database Development