Getting the Most Out of SQL Server 2000's Query Analyzer, Part II

,

Introduction

In the first

part of this series, we took a look at how to bring up Query Analyzer 2000

and how to log in.  We dealt with two issues: using different sets of

credentials and problems with querying linked servers.  These two issues are often frustrating for developers

working with SQL Server. We left off with the promise to explore the Object Browser

and more specifically, the Transact-SQL Debugger. That's where this article

picks up.

When we open up SQL Server 2000's Query Analyzer for the first time, we can't

help but notice the Object Browser on the left side.  The Object Browser is

not part of SQL Server 7.0's Query Analyzer and is our first sign that Microsoft

has added some functionality to this essential client tool.  We'll discuss

the functionality provided in the Object Browser and dig into using the

Transact-SQL Debugger.  Debugging tools have been missing from the standard

SQL Server client set until this latest version.  Other Integrated

Development Environments (IDEs) produced by Microsoft have had at least marginal

debugging capabilities for a while now, dating back to the QuickBasic 4.0 days

of the late eighties. It's nice to see some basic but functional debugging

facilities in our bread and butter Query Analyzer.

We'll look at the following:

  • The Basic Layout
  • The Cost
  • Scripting Existing Objects
  • Scripting New Objects
  • Using the Transact-SQL Debugger

The Basic Layout

When we first open up Query Analyzer, we'll see a display similar to the

following (minus the labels):

On the left hand side is a new window, the Object Browser.  The Object

Browser has a drop down box (A) which contains a list of all SQL Servers

we've connected to since we've started Query Analyzer. It also has a tree view of

all our databases for the currently selected server,  common functions

ranging from our @@connections to OPENXML(), as well as the various system data types (B). 

If we want to turn Object Browser on or off, there's a button on the toolbar (C)

which allows us to click without going through the menus.  There is a

shortcut key, F8, which does the same.

Looking at the Object Browser, we see that there are two tabs.  There is

the Objects tab (A), which we've already explored a bit, and there is the

Templates tab (B), which contains quick scripting templates to help us

build Dynamic Definition Language (DDL) queries quickly and easily.

 

The Cost

Object Browser is an added tool to speed up our development efforts. 

Microsoft has spent quite a bit of time and resources with this new piece to our

SQL Server IDE, and from outward appearances, it looks clean and usable. 

But what's the cost? In order to be able to provide all this information, 

surely it's got to hit the server, right?  It does, and the actual cost is

expectedly low for most functions.

The Object Browser will require another connection to SQL Server.  For

instance, running the following query returns two rows:

SELECT spid, program_name

FROM sysprocesses

WHERE program_name LIKE 'SQL Query Analyzer%'

One of the rows is the initial connection Query Analyzer requires.  The

second is the Object Browser.  Now, with respect to getting information to

populate the database list, Query Analyzer already pulls that information when

it starts up.  As a result, the Object Browser doesn't need to make a

second query to get the same information.  Also, it doesn't populate user

tables and the like until such time as we actually ask for the information by

expanding the appropriate categories.  And when it does, it only asks for

the information it specifically requires.  For instance, to get the

information on user tables within the Foodmart database, the Object Browser will

execute:

USE [Foodmart]

select id, owner = user_name(uid), name, status from [Foodmart].dbo.sysobjects where type = N'U' order by name

Object Browser queries only what it needs.  It queries information only

when information is requested.   The cost to use this tool for our

basic purposes is fairly negligible. It's only when we start using the

Transact-SQL Debugger will costs begin to rise.  Let's talk about that a bit.

If we're stepping through a procedure (as we'll talk about later), the Object Browser

can actually lock system resources.   This makes sense, as we want to

ensure that nothing changes from line to line.  The whole point of

the debugger is to help isolate and control what's going on so we can figure out

what may be wrong with a particular stored procedure.  As a result, the

Transact-SQL debugger should only be run in a development

environment.  The last thing we want to do is impair a

production system as we try to troubleshoot why a particular stored procedure is

failing.

Scripting Existing Objects

When we deal with a lot of databases or a particular database with a lot of

objects, it can often become a chore trying to remember all the columns for a

particular table or the parameters for a selected stored procedure we want to

use.  This is where the Object Browser can save quite a bit of time. 

By right-clicking on the table name we need (in this case the Categories table

from the Northwind database), we can choose to script the appropriate T-SQL

command we need.  In this case, I'm going to script the Select to a new

window:

Query Analyzer will create the new window and I'll find the following code

already there for me:

SELECT [CategoryID], [CategoryName], [Description], [Picture] FROM [Northwind].[dbo].[Categories]

All the columns for the Categories table are present in the query, and I can

now go in and edit the query to only return the columns I want.  I could

also choose to script the object to the clipboard, and then insert the code

where I needed it.  This is especially helpful if we're trying to build

stored procedures and already have some code in a window.  There's no point

to scripting the object to a new window, then going through the process of

cutting or copying the code, next switching to the window where we're

building the stored procedure, and finally pasting the code we've just copied.

We can also script stored procedure execution.  Not only will it script

the parameter names, but also the data type for each parameter.  This

ensures we not only cover all the parameters, but also we avoid type mismatches

or unexpected type conversions.  For instance, we can choose to script the

CustOrderHist stored procedure from the Northwind database:

When we paste the code to Query Analyzer, we get the following:

DECLARE @RC int

DECLARE @CustomerID nchar(5)

-- Set parameter values

EXEC @RC = [Northwind].[dbo].[CustOrderHist] @CustomerID

Now, one limitation to the Object Browser is that multiple objects can't be

selected together to be scripted.  So if we're looking to script tables to

join together, we'll have to script each table individually and then manually

building the join.  Also, if we're looking to script database objects to

put into Visual SourceSafe or some other change management repository, the

Object Browser won't be of much help.  There are better options with

Enterprise Manager or by using DMO.

Scripting New Objects

One nice addition to Query Analyzer in SQL Server 2000 is the ability to

create and use templates.  Microsoft ships the basic templates for creating

standard database objects and we can choose to modify these or create our

own.  If we've set up SQL Server 2000 with the default paths, we'll find

the folders containing our templates in C:\Program Files\Microsoft SQL Server\80\Tools\Templates\SQL Query Analyzer

with a folder structure that exactly matches the tree view for the Templates

tab.  Here is the Create Procedure Basic Template:

-- =============================================

-- Create procedure basic template

-- =============================================

-- creating the store procedure

IF EXISTS (SELECT name 

    FROM sysobjects 

    WHERE name =

N'<procedure_name, sysname, proc_test>' 
    AND type

= 'P')

   DROP PROCEDURE <procedure_name,

sysname, proc_test>

GO

CREATE PROCEDURE <procedure_name,

sysname, proc_test> 

  <@param1, sysname,

@p1> <datatype_for_param1, ,

int> = <default_value_for_param1, ,

0>, 

  <@param2, sysname, @p2> <datatype_for_param2, ,

int> = <default_value_for_param2, ,

0>
AS

  SELECT @p1, @p2

GO

-- =============================================

-- example to execute the store procedure

-- =============================================
EXECUTE <procedure_name,

sysname, proc_test> <value_for_param1, ,

1>, <value_for_param2, ,

2>

GO

If we look closely, we see several structures of the format <parameter

name, parameter type, default value> scattered throughout the template

file.  These structures can be replaced by going to the Edit

menu and selecting Replace Template Parameters or by using the

shortcut Ctrl+Shift+M.

.

When we choose to replace the template parameters, a dialog box comes up

where we can edit the parameters. 

Once we click Replace All, SQL Server will take care of making

the changes for us.  As a result, we can quickly build the skeleton

structure for our stored procedures and other database objects and use templates

to save on typing.  Not only will this speed up our writing code, but it'll

also reduce a little on the typos.

But what if the standard template isn't enough?  Where I work, stored

procedures have to be commented in a certain fashion.  The Create

Procedure Basic Template doesn't have the comment structure I need.  I

can edit it, or I can create my own.  I chose to do the latter, adding the

comment block as so:

-- =============================================

-- Create procedure with comments

-- =============================================

-- creating the store procedure

IF EXISTS (SELECT name 

    FROM sysobjects 

    WHERE name =

N'<procedure_name, sysname, proc_test>' 
    AND type

= 'P')

   DROP PROCEDURE <procedure_name,

sysname, proc_test>

GO

/*************************************************************************************************************** 

Written By : <author_name, , Brian Kelley>

Date : <create_date, smalldatetime, 01/01/2002> 

Purpose : <procedure_purpose, , > 

Input Params : <@param1, sysname, @p1>, <@param2, sysname, @p2>

Output Params : <@outparam1, sysname, @op1> 

Updates : 

***************************************************************************************************************/
CREATE PROCEDURE <procedure_name,

sysname, proc_test> 

  <@param1,

sysname, @p1> <datatype_for_param1, ,

int> = <default_value_for_param1, ,

0>, 

  <@param2, sysname, @p2> <datatype_for_param2, ,

int> = <default_value_for_param2, ,

0>
AS

  SELECT @p1, @p2

GO

Having saved it as Create Procedure with Comments.tql in C:\Program Files\Microsoft SQL Server\80\Tools\Templates\SQL Query Analyzer\Create Procedure,

I can choose it like any other stored procedure template and have my comment

block with parameters that can be replaced.  This will ensure every stored

procedure I create meets my organization's standards for commenting without me

having to either type in the entire comment block or find an existing stored

procedure and copying the comment block from it.

Transact-SQL Debugger:

The Transact-SQL Debugger is probably the biggest addition to SQL Server

2000's Query Analyzer.  Prior to SQL Server 2000's release, I would see

postings asking if anyone knew of a good debugger for stored procedures in SQL

Server (then 7.0).  With SQL Server 2000, that deficiency has been

remedied, but the Transact-SQL Debugger is not readily visible.  In order

to get to the debugger, we have to use the Object Browser or the Object Search

(from the Tools menu) to list the stored procedure.  We then right click on it, and select Debug:

A new dialog box comes up which lists the stored procedure and allows us to

set the values of the parameters:

I'll enter Seafood for @CategoryName and 1999 for @OrdYear

in order to be able to trace through the stored procedure. Notice below the

parameters there is a check box for Auto roll back.  This

ensure that when we are done tracing through the stored procedure,  any

changes it made will be rolled back.  If we want our changes to become

permanent, we'll need to uncheck this box.  Once we have set our parameters

and decided upon Auto roll back, we can click Execute, and that'll take us to

the debug window:

We have the code before us at the top of the debug window.  Notice the

yellow arrow to the left of the code.  This arrow tells us what line we're

on.  Below the code we see windows where Query Analyzer is tracking both the local

and global parameters, as well as the current Callstack. Finally, at the bottom

we see the Results Text window.  Notice there is an empty row in the Global

Parameters window.  If we have other global parameters we want to watch (e.g.

@@IDENTITY), we can add them and track their values as we debug the stored

procedure.  

In order to use the Transact-SQL Debugger, we have to be familiar with the

various commands available to us.  The commands exist as both buttons on

the toolbar as well as keyboard shortcuts.  Let's look at them:

Button Command Purpose
Go (F5) Executes the stored procedure in debug mode

until either a breakpoint or the end of the stored procedure is reached.

Set Breakpoint (F9) Toggles a breakpoint on or off where the cursor

currently is.  A breakpoint will be marked by a red circle to the

left of the line. Execution will be paused when a breakpoint is reached.

Clear All Breakpoints (Ctrl+Shift+F9) Removes all breakpoints. This will allow Go to

process through the entire stored procedure.

Step Into (F11) Steps through the stored procedure

line-by-line.  The next line of the stored procedure will execute,

and then execution will be paused.  This is especially helpful if

we're trying to see the procedure flow since we can follow one line at a

time, at our own pace.

Step Over (F10) Also steps through the stored procedure

line-by-line.  The difference between Step Into and Step

Over can only be seen if we make calls to other stored

procedures.  Using Step Into, we can step through called

stored procedures line-by-line as well.  

However, using Step Over executes the called stored procedure

in its entirety and puts us at the next line in the current stored

procedure.  We'd use Step Over for a called stored procedure

when we know that stored procedure is correct and working

properly.  We don't need to go line-by-line throught it, and Step

Over ensures we don't.  If we're not sure about the called

stored procedure, we can use Step Into to check the called stored

procedure is executing as it should.

Step Out (Shift+F11) Executes the remaining lines, until a

breakpoint or the end of the stored procedure is reached.  If we've

gone into Step Into or Step Over mode, and we no longer

desire to go line by line, we use Step Out.

Run To Cursor (Ctrl+F10) This works like a breakpoint except it doesn't

require us to explicitly set one.  We position our cursor in the

stored procedure wherever we want execution to pause, and then we use Run

To Cursor.  The stored procedure will execute until it reaches

the line our cursor is on and then it will pause.

Restart (Ctrl+Shift+F5) Restarts the stored procedure from the

beginning.  Helpful if we've been stepping through and we realize

we missed something.

Stop Debugging (Shift+F5) Stop Debugging sounds like it would end

debug mode, but it actually means stop the current debugging

step-through.  We'll still remain in debug mode, which means we can

start debugging again by using Go.  This is useful if we

need to stop debugging and we aren't planning on restarting

immediately.   

The best way to get comfortable with the Transact-SQL Debugger is to

"play."  This is actually true of any debugger for any IDE

whether it is part of Query Analyzer, Visual Studio,  Forté for Java, or

some other product.  Pick stored procedures that work perfectly well, ones

which you are very familiar with.  Work with the parameters for the stored

procedures, set breakpoints, and use the various Step commands.  Once

you're comfortable with that, take working stored procedures, alter them so that

still pass syntax checks, but the code does something other than what is

normally expected.  Experiment with the debug commands to get to the code

that's been altered.  The idea is to get comfortable with the debug

environment for the day when it'll be used on a new or relatively unfamiliar

stored procedure.  

Now, for our current example, by playing with the Debugger and the SalesByCategory

stored procedure, we can choose to step through line-by-line.  If we do,

we'll notice that our local parameter @OrdYear will change values from

the 1999 that we typed in to the value 1998. The reason is the

following set of code within the stored procedure:

IF @OrdYear != '1996' AND @OrdYear != '1997' AND @OrdYear != '1998' 

BEGIN

  SELECT @OrdYear = '1998'

END

@OrdYear isn't 1996, 1997, or 1998, and as a result the stored procedure is

going to change it!  Had we not stepped through the stored procedure, we

might never have realized why we kept getting 1998 results for Seafood. 

This is why the Debugger can really be of help.  By going line-by-line and

watching the values for the local parameters, we can see if and when those

parameters change.  This is why single step debuggers are worth the time it

takes to learn them and get comfortable with them.  And once we are

comfortable with the Transact-SQL Debugger, we'll be able to use it to debug

stored procedures on SQL Server 6.5 SP2 and higher SQL Servers.  As a

result, those of us running in mixed environments can leverage the Transact-SQL

Debugger across all our SQL Server platforms. 

Wrap Up

In this article we talked about the Object Browser, a new feature in SQL

Server 2000's Query Analyzer.  The Object Browser allows to rapidly develop

Transact-SQL code by auto-scripting for us not only existing database objects

but also by providing templates for new ones.  We can script the execute of

a stored procedure, complete with all parameters, or the insert or delete on a

table, with all the columns listed for our convenience.  By using templates

we can fill out predefined parameters and generate the skeleton T-SQL code for

creating a new database object.  We can use the stock templates or create

our own.

We also talked about the Transact-SQL Debugger.  The Transact-SQL

Debugger represents a sizeable upgrade on our debugging capabilities with

respect to stored procedures.  Not only does it work against SQL Server

2000 servers, but also on any SQL Server from SQL Server 6.5 SP2 and up. 

The Transact-SQL Debugger gives us the ability to go line-by-line and carefully

watch how parameters change.  It allows us to set breakpoints to run to,

much like other single step debuggers.  Because of these new-found

debugging capabilities, we can often save considerable time finding bugs in our

code that otherwise would be difficult to extract.

Hopefully you've found this brief synopsis of the Object Browser

helpful.  In the next article we'll scale back a bit and look at how to

configure our Query Analyzer environment for our liking.  We'll look at

modifying the toolbars, setting connecting settings, and defining shortcut

keys.  We'll also look briefly at changing how we output result sets. 

By examining the various options available to us, we can customize the Query

Analyzer for maximum use.

Rate

5 (1)

Share

Share

Rate

5 (1)