SQL Server From Squirrel’s View
Lockergnome
Home

Visibility into SQL Server 2005 SSAS

Monday, February 4th, 2008

Today I was working with SQL Server 2005 SSAS (SQL Server Analysis Services) and I needed to look into the server to see if there were any issues. My users were telling me that the pivot tables in their Excel spreadsheets were taking longer than usual. Microsoft does not allow you to run like an sp_who in Analysis Services like in the database engine. So Microsoft has come out with a standalone application called Activity Viewer. This is a GUI application that displays users, connections and processes in an instance of Analysis Services for SQL Server 2005. Within the Activity Viewer application it allows you to kill a process just like in the database engine.

The application is written in .NET and you will need to make minor modifications to the application to get it work for your specific environment. Here is the link to download the Activity Viewer application and to get more information:

http://technet.microsoft.com/en-us/library/ms160921.aspx

If you have any problems please post here and I will be happy to assist!

Using SQL Server Reserved Words

Tuesday, January 22nd, 2008

Hello again… I hope you had a good holiday weekend for those of you who had the holiday off. Last night I came across a stored procedure that used SQL Server reserved words in the SELECT and INSERT statements. Since I am using SQL Server 2005, the words that came up as “reserved” were:
status
views
subject
user_id

If you must use SQL Server reserved words put brackets [] around them. Putting reserved words in brackets [] is a “tuning” technique that DBAs use to “optimize” T-SQL code. If you do NOT put brackets [] around the reserved words then SQL Server will need to take the time to “resolve” the word and decide if it is being used as a reserved word or if it corresponds to a column in a user table or a literal in a result set. This will take SQL Server longer to execute the T-SQL script. If the reserved words do in fact have brackets [] then SQL Server knows that it corresponds to a column name or as a literal if you use it as a column heading in a result set and will not have to do a compare.

I hope this helps you out… if you have any other way to tune or optimize please comment!

Locating The Server Port In SQL Server 2005

Wednesday, January 16th, 2008

Hello and welcome back to my blog… today I was needing to change the port number on one of my production SQL Server 2005 boxes. Wouldn’t you know it… I had to look for it because it has been awhile since I have had to change the port number on the server. So I thought today I would share where you will find the server port number in SQL Server 2005.

From the Start button click on All Programs, then click on Microsoft SQL Server 2005. From there navigate to Configuration Tools and click on SQL Server Configuration Manager. Once the Configuration Manager opens up, expand the SQL Server 2005 Network Configuration. Underneath this you will see Protocols for <your server name> … click on that. This will display the information for this server on the right hand side of the Configuration Manager. On the right side, double-click on TCP/IP. After double-clicking this the TCP/IP Properties dialog box opens up. Click on the tab that reads “IP Addresses” and this will display all of the IP addresses that are assigned to this server. If you have multiple IP addresses assigned (depends upon how many nic cards you have in the server) to this server then scroll to the bottom to where it reads “IPAll“. Underneath this you will see where it reads “TCP Dynamic Ports“… this is where the Server Port number is located and this where you make the change.

I hope this helps and you can use this a reference each time you need to find the server port. :)

Detecting A CPU Bottleneck

Tuesday, January 15th, 2008

In SQL Server 2005 there several ways to detect a CPU bottlneck.  The first way to detect a bottleneck is by looking at the System Monitor counter Processor: % Processor Time.  If the value of this counter  is greater than 80% for  15 to 20 minutes in duration, then it is a good indication that you have a bottleneck.

You can also monitor System: Processor Queue Length.  A value of 2 or higher for a length of time also indicates a CPU bottleneck.  Another way to detect a CPU bottleneck is to utilize the new DMVs (Dynamic Management Views) in SQL Server 2005.  Execute the  following query in the master database and the query will return the count of number of worker threads in the runnable state:

Select Count(*) AS workers_waiting_for_cpu, s.scheduler_id
From sys.dm_os_workers as o
Inner Join sys.dm_os_schedulers as s
On o.scheduler_address = s.scheduler_address
And s.scheduler_id < 255
Where o.state = ‘Runnable’
Group By s.scheduler_id

I hope this helps… if you have another way to detect a CPU bottleneck post here and let us know!

Reporting Services On A Cluster

Wednesday, January 2nd, 2008

Welcome back and happy new year! Today I wanted to share with you my experience with SQL Server 2005 Reporting Services on a 4 node cluster.

The other day we had failed over one of the nodes to test functionality to see if the Reporting Services databases failed over as well. After the fail-over the Reporting Services databases did fail-over however, Reporting Services could not be found. After researching, we discovered that the databases for Reporting Services for SQL Server 2005 are cluster aware just not the service itself. In order for Reporting Services to work properly in a clustered environment… the Reporting Services needs to be installed on every node in the cluster. So when a fail-over occurs the Reporting Services can be found on the new node and connect to the databases. So I like to call this a “poor mans” cluster aware service.

If you have any experience with this please post and share your experience!

Scripting SQL Server 2005 Logins

Thursday, December 6th, 2007

I thought today I would share with you a great way to move SQL Server logins from one SQL Server 2005 server (source) to another SQL Server 2005 server (destination).  In the past I have tried to use DTS to move logins (passwords and SIDs) from one server to another but without much success.  As I was surfing the Internet, I came across 2 stored procedures from Microsoft that you create in the master database.  Once compiled, run the primary stored procedure and the result set produces the CREATE LOGIN statements with the correct passwords and SIDs for every login in the source server.  Once this script has been created, you can then copy it and execute the script in a query window on the destination server.  Once you restore the user databases from the source server to the destination server the SIDs found in the user database will then be sync’d to the logins in the master database. 

You will find both stored procedures below in one script.  The primary stored procedure you execute to generate the CREATE LOGIN script is the stored procedure:  sp_help_revlogin   Here is the correct syntax to run the procedure for ALL logins.  exec sp_help_revlogin

Here is the script with the 2 stored procedures:

USE master
GO

IF OBJECT_ID (’sp_hexadecimal’) IS NOT NULL
DROP PROCEDURE sp_hexadecimal
GO

CREATE PROCEDURE sp_hexadecimal
@binvalue VARBINARY(256),
@hexvalue VARCHAR(514) OUTPUT

AS

/*
**********************************************************************
**
** Object Name: sp_hexadecimal
** Object Type: Stored Procedure
** File Name: sp_hexadecimal.sql
** Database Name: master
** Author: < Name of the person who wrote the T-SQL
** script >
** Creation Date: 07.10.08 - use ANSI format
** Description: This procedure is involved in scripting out
** logins, passwords and SIDs in SQL Server 2005.
** Special Note: This script is also available from the
** Microsoft website.
** Modified Tables: None
** Called Procedures: None
** Called Jobs: None
** Called UDFs: None
** Calling Procedures: sp_help_revlogin
** Calling Jobs: None
** Calling UDFs: None
** Return Statuses: @hexvalue as OUTPUT
**
**********************************************************************
*/

– Declaration section
DECLARE @charvalue VARCHAR(514)
DECLARE @i INT
DECLARE @length INT
DECLARE @hexstring CHAR(16)

– Initialization section
SELECT @charvalue = ‘0x’
SELECT @i = 1
SELECT @length = DATALENGTH(@binvalue)
SELECT @hexstring = ‘0123456789ABCDEF’

WHILE (@i <= @length)
BEGIN
– Declaration section
DECLARE @tempint INT
DECLARE @firstint INT
DECLARE @secondint INT

– Initialization section
SELECT @tempint = CONVERT(INT, SUBSTRING(@binvalue,@i,1))
SELECT @firstint = FLOOR(@tempint/16)
SELECT @secondint = @tempint - (@firstint*16)
SELECT @charvalue = @charvalue +

SUBSTRING(@hexstring, @firstint+1, 1) + SUBSTRING(@hexstring, @secondint+1, 1)

SELECT @i = @i + 1
END
SELECT @hexvalue = @charvalue
GO

/******************************************************************************/
IF OBJECT_ID (’sp_help_revlogin’) IS NOT NULL
DROP PROCEDURE sp_help_revlogin
GO

CREATE PROCEDURE sp_help_revlogin
@login_name SYSNAME = NULL

AS

/*
**********************************************************************
**
** Object Name: sp_help_revlogin
** Object Type: Stored Procedure
** File Name: sp_help_revlogin.sql
** Database Name: master
** Author: < Name of the person who wrote the T-SQL
** script >
** Creation Date: 07.10.08 - use ANSI format
** Description: This procedure creates the actual T-SQL ‘Create
** Login’ statement with the information from
** the security tables in SQL Server 2005.
** Special Note: This script is also available from the
** Microsoft website.
** Modified Tables: None
** Called Procedures: sp_hexadecimal
** Called Jobs: None
** Called UDFs: None
** Calling Procedures: None
** Calling Jobs: None
** Calling UDFs: None
** Return Statuses: None
**
**********************************************************************
*/

– Declaration section
DECLARE @name SYSNAME
DECLARE @type VARCHAR(1)
DECLARE @hasaccess INT
DECLARE @denylogin INT
DECLARE @is_disabled INT
DECLARE @PWD_varbinary VARBINARY(256)
DECLARE @PWD_string VARCHAR(514)
DECLARE @SID_varbinary VARBINARY(85)
DECLARE @SID_string VARCHAR(514)
DECLARE @tmpstr VARCHAR(1024)
DECLARE @is_policy_checked VARCHAR(3)
DECLARE @is_expiration_checked VARCHAR(3)

IF @login_name IS NULL
DECLARE login_curs CURSOR FOR
SELECT
p.sid,
p.[name],
p.[type],
p.is_disabled,
l.hasaccess,
l.denylogin
FROM sys.server_principals AS p
LEFT JOIN sys.syslogins AS l
ON l.[name] = p.[name]
WHERE p.[type] IN( ‘S’, ‘G’, ‘U’ )
AND p.[name] <> ’sa’
ELSE
DECLARE login_curs CURSOR FOR
SELECT p.sid,
p.[name],
p.[type],
p.is_disabled,
l.hasaccess,
l.denylogin
FROM sys.server_principals AS p
LEFT JOIN sys.syslogins AS l
ON l.[name] = p.[name]
WHERE p.[type] IN( ‘S’, ‘G’, ‘U’ )
AND p.[name] = @login_name

OPEN login_curs

FETCH NEXT FROM login_curs
INTO @SID_varbinary, @name, @type, @is_disabled, @hasaccess, @denylogin

IF (@@FETCH_STATUS= -1)
BEGIN
PRINT ‘No login(s) found.’
CLOSE login_curs
DEALLOCATE login_curs
RETURN -1
END

SET @tmpstr = ‘/* sp_help_revlogin script ‘

PRINT @tmpstr

SET @tmpstr = ‘** Generated ‘ + CONVERT (VARCHAR, GETDATE()) + ‘ on ‘ + @@SERVERNAME + ‘ */’

PRINT @tmpstr
PRINT

WHILE ( @@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
PRINT
SET @tmpstr = ‘– Login: ‘ + @name
PRINT @tmpstr

IF (@type IN ( ‘G’, ‘U’))
BEGIN – NT authenticated account/group
SET @tmpstr = ‘CREATE LOGIN ‘ + QUOTENAME( @name ) + ‘FROM WINDOWS’
END
ELSE
BEGIN
– SQL Server authentication
– obtain password and sid
SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, ‘PasswordHash’ ) AS VARBINARY(256))
EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
EXEC sp_hexadecimal @SID_varbinary, @SID_string OUT

– obtain password policy state
SELECT @is_policy_checked =
CASE is_policy_checked WHEN 1 THEN ‘ON’ WHEN 0 THEN ‘OFF’ ELSE NULL END
FROM
sys.sql_logins
WHERE [name] = @name

SELECT @is_expiration_checked =
CASE is_expiration_checked WHEN 1 THEN ‘ON’ WHEN 0 THEN ‘OFF’ ELSE NULL END
FROM
sys.sql_logins
WHERE [name] = @name

SET @tmpstr = ‘CREATE LOGIN ‘ + QUOTENAME( @name )
+ ‘ WITH PASSWORD = ‘ + @PWD_string
+ ‘ HASHED, SID = ‘ + @SID_string

IF ( @is_policy_checked IS NOT NULL )
BEGIN
SET
@tmpstr = @tmpstr + ‘, CHECK_POLICY = ‘ + @is_policy_checked
END

IF ( @is_expiration_checked IS NOT NULL )
BEGIN
SET @tmpstr = @tmpstr + ‘, CHECK_EXPIRATION = ‘ + @is_expiration_checked
END
END

IF (@denylogin = 1)
BEGIN – login is denied access
SET @tmpstr = @tmpstr + ‘; DENY CONNECT SQL TO ‘ + QUOTENAME( @name )
END
ELSE IF
(@hasaccess = 0)
BEGIN – login has exists but does not have access
SET @tmpstr = @tmpstr + ‘; REVOKE CONNECT SQL TO ‘ + QUOTENAME( @name )
END

IF (@is_disabled = 1)
BEGIN — login is disabled
SET @tmpstr = @tmpstr + ‘; ALTER LOGIN ‘ + QUOTENAME( @name ) + ‘ DISABLE’
END

PRINT @tmpstr
END

FETCH NEXT FROM login_curs
INTO @SID_varbinary, @name, @type, @is_disabled, @hasaccess, @denylogin

END

CLOSE login_curs
DEALLOCATE login_curs

RETURN 0
GO