Deploying a Startup Parameter on All Servers

Downloads
48763.zip

No successful entries were submitted for the December Reader Challenge, "Troubleshoot Performance Problems." Here’s a recap of the problem and the solution to the December Reader Challenge.

Problem:


Kevin is a database administrator who manages several data warehouses in his organization. All the data warehouses are stored in SQL Server 2000 with Service Pack 3 or 4. Each data warehouse consists of a reporting database and a historical data store. There are several applications that connect to the reporting database to perform ad-hoc queries or operations. Kevin encounters blocking or performance issues periodically, and he wants to be able to troubleshoot these problems more efficiently. Help Kevin do the following:

  1. Identify the executing spid, blocked status, wait type, wait resource, CPU, IO, and memory counters in a particular database.
  2. Identify the current executing statement with the appropriate stored procedure or function name, if present.
  3. Develop a simple query that Kevin can use to retrieve these details.

Solution:


Kevin can use the master.dbo.sysprocesses system table to get the executing spid, blocked status, wait columns and counters in a particular database. The query to obtain this information for all user connections to a particular database is shown below:

use northwind
go
select p.spid, p.blocked, p.waittype, p.waittime, p.lastwaittype, p.waitresource
     ,p.cmd, p.status, p.cpu, p.physical_io, p.memusage, p.login_time, p.last_batch,
p.program_name
  from master.dbo.sysprocesses as p
  where p.spid >= 51
   and p.dbid = db_id()
go

SQL Server 2000 with Service Pack 3 and above contains a system function fn_get_sql that can be used to retrieve the text of a particular SQL handle representing a cached plan. Additionally, the sysprocesses system table also contains the offsets to the currently executing statement in the text represented by the plan. The relevant columns in sysprocesses that provide this information are sql_handle, stmt_start and stmt_end. The stmt_start and stmt_end columns are zero-based, representing the offset to the statement in bytes. The text returned by fn_get_sql is a Unicode string but is returned as an ASCII string.

Kevin can now use this information to write a T-SQL user-defined function that retrieves the current executing statement using the fn_get_sql system function, given the SQL handle and statement offsets. The definition of the T-SQL user-defined function is shown below:

use northwind
go
if object_id('GetCurrentSqlStmt') is not null
    drop function GetCurrentSqlStmt
go
create function GetCurrentSqlStmt (@sql_handle binary(20), @stmt_start int, @stmt_end int)
returns varchar(8000)
as
begin
    return (
            select coalesce(quotename(object_name(s.objectid)) + ':', ')
                 + cast(substring(s.text, (@stmt_start/2) + 1
                               , (((case @stmt_end when -1 then datalength(s.text) else @stmt_end
end) - @stmt_start)/2) + 1) as varchar(8000))
            from ::fn_get_sql(@sql_handle) as s
    )
end
go

Modifying the query on sysprocesses to include the T-SQL user-defined function GetCurrentSQLStmt, provides Kevin with the information necessary to troubleshoot the performance issue. The modified query is shown below:

use northwind
go
select p.spid, p.blocked, p.waittype, p.waittime, p.lastwaittype, p.waitresource
     , dbo.GetCurrentSqlStmt(sql_handle, stmt_start, stmt_end) as sql_text, p.cmd, p.status
     , p.cpu, p.physical_io, p.memusage, p.login_time, p.last_batch, p.program_name
  from master.dbo.sysprocesses as p
 where p.spid >= 51
   and p.dbid = db_id()
go

An example of a stored procedure used to simulate a long-running operation is shown below. Run the stored procedure from a Query Analyzer window, and use the query above to see the current executing statement.

use northwind
go
if object_id('LongRunningProc') is not null
    drop procedure LongRunningProc
go
create procedure LongRunningProc
as
begin
    declare @start datetime, @count int, @wait_time char(8)
    set @start = current_timestamp
    while(datediff(minute, @start, current_timestamp)

<p><h3>JANUARY READER CHALLENGE:</h3><br>
Now, test your SQL Server savvy in the January Reader Challenge, "Deploying a Startup Parameter on All Servers"(below). Submit your solution in an email message to challenge@sqlmag.com by December 20. Umachandar Jayachandran, a <i>SQL Server Magazine</i> technical editor, will evaluate the responses. We’ll announce the winner in an upcoming <i>SQL Server Magazine UPDATE</i>. The first-place winner will receive $100, and the second-place winner will receive $50.</p>

<p><h3>Problem:</h3><br>
Charlie is a database administrator who manages a combination of more than 50 installations of SQL Server 7.0 and SQL Server 2000. He wants to add a new trace flag as a startup parameter on all the servers to generate a report in the event of a SQL Server deadlock. For this problem, assume that the trace flag that generates this deadlock report is 1204. How can Charlie quickly deploy this new startup parameter to all the servers?</p>

Discuss this Article 5

Carlos (not verified)
on Sep 6, 2007
Hi mpanarusky, I'm interested in having this sp (InstantDoc #48763) at my company, can you please provide the right function code? Thanks and Regards e-mail:cagoworld@hotmail.com
javdvd (not verified)
on Jun 3, 2008
I think it should be something like this: if object_id('GetCurrentSqlStmt') is not null drop function GetCurrentSqlStmt go create function GetCurrentSqlStmt (@sql_handle binary(20), @stmt_start int, @stmt_end int) returns varchar(8000) as begin return ( select coalesce(quotename(object_name(s.objectid)) + ':', cast( substring( s.text, (@stmt_start/2) + 1, (((case @stmt_end when -1 then datalength(s.text)*2 else @stmt_end end) - @stmt_start)/2) + 1) as varchar(8000)) ) from ::fn_get_sql(@sql_handle) as s ) end go
MARK (not verified)
on Mar 23, 2007
I made some changes (simplifications) to deal with the compile error reported earlier, but noted that the function was returning half the SQL string when @stmt_end = -1. I corrected this by modifying the CASE statement to double the substring length: "when -1 then datalength(s.text) * 2 else ..."
Nirmal (not verified)
on Apr 23, 2007
mpanarusky, can you post the corrected GetCurrentSqlStmt userdefined function on the site. It would be a great help for me.
MARK (not verified)
on Mar 23, 2007
The function GetCurrentSqlStmt does not compile. The error is "Unclosed quotation mark before the character string...", pointing to the single quote at the end of: select coalesce(quotename(object_name(s.objectid)) + ':', '). Please provide a correction.

Please or Register to post comments.

IT/Dev Connections

Las Vegas
September 30th - October 4th

Paul ThurottOur Experts will show you:
• Common SQL Server
Problems
• Best Practices for T-SQL
• SQL Server Integration
Services
• Database Development

Come See Michael Otey & Tim Ford in Person!

Early Registration Now Open

From the Blogs
May 21, 2013
blog

A Common Misconception about MAXDOP

Out of the box, SQL Server is (and has been) able to take advantage of multiple processors/cores without any effort on behalf of administrators....More
May 9, 2013
blog

My ISO 8601-Compliant Signature 2

My family recently just "officially" announced that we're in the process of adopting a child from South Africa. We're quite excited, of course, but there's a ton of paperwork to do—along with the need for gobs of signatures....More
May 8, 2013
blog

Use SSIS for ETL from Hadoop

In this blog post, Mark Kromer walks you through using SSIS as a way to use ETL techniques using Microsoft's Hadoop on Windows (HDInsight) as a source using Hive connectors...More
SQL Server Pro Forums

Get answers to questions, share tips, and engage with the SQL Server community in our Forums.