Click here to Skip to main content
15,891,375 members
Articles / Database Development / SQL Server
Article

SQL Server Concepts and Best Practices to Build Transact SQL Stored Procedures

Rate me:
Please Sign up or sign in to vote.
3.00/5 (4 votes)
3 Jun 2010CPOL3 min read 66.8K   6   2
Explains basic SQL Server concepts and some best practices to build Transact SQL Stored Procedures.

Introduction

Microsoft SQL Server has a lot of components that you can use. If you want a DBMS, you the SQL Server Database Engine is a really good choice.

SQL Server Database Engine

The SQL Server Database Engine includes:

  • Core service for storing
  • Processing, and securing data
  • Replication
  • Full-text search, and tools for managing relational and XML data

Image 1

Diagram 1 - SQL Server Database Engine and the Windows Operating System

Database Engine Components

Relational Engine

The core of the database engine is responsible for all the relevant security decisions.

Storage Engine

This is a resource provider, and manages the resources by using the Operating System. When the relational engine tries to execute a query for the first time, it calls the Storage engine to retrieve the object, put the object in memory, and returns the pointer to the Execution engine.

Image 2

Diagram 2 - Database Engine Components

Relational Engine Tasks

  • Establish the user context
  • Check the syntax of each Transact SQL query
  • Compile each query
  • Check permissions and determines if the query can be executed by the user associated with the request
  • Optimizes the query request
  • Builds and stores the query plan on the cache, and executes the query

Query Processing

The Query Optimizer checks inputs and determines the most efficient way to process information and builds the query execution plan that consists of a sequence in which the tables can be accessed and the methods used to get the information.

Query optimization of a SELECT statement

Best Practices to Build SQL Statements

Sub Queries vs. Joins

  • The performance of a query can be similar to using a sub query or a join
  • Difference: a sub query can require a Query Optimizer to perform additional steps

Query with Date Range

One of the difficulties when a programmer works with Transact SQL is working with date ranges; some useful ways to work with them are shown in the next examples:

Example 1:

SQL
use Northwind 
declare @iniDate as varchar(15)
declare @endDate as varchar(15)
set @iniDate = '19960710'
set @endDate = '19960716'
select * from dbo.Orders 
where ShippedDate between @iniDate and @endDate

Example 2:

SQL
declare @iniDate as varchar(8)
declare @endDate as varchar(8)
set @iniDate = '20080801'
set @endDate = '20081125'

select * from  sysobjects 
where crdate  between @iniDate and dateadd (d, 1, cast(@endDate as datetime))

Logical Operations and the Use of Parenthesis

You also must know that the following sentences are different; you must be clear about the concepts of logic and mathematics:

Example 1:

SQL
select * from dbo.Orders 
where EmployeeID = 5 and ShipRegion = 'RJ' OR ShipRegion = 'SP'

Example 2:

SQL
select * from dbo.Orders 
where EmployeeID = 5 and (ShipRegion = 'RJ' OR ShipRegion = 'SP')

Conditionals and “IF” Sentences

Some of the sentences that you write using IF sentences can be rewritten in a different way, see these examples:

Example 1:

SQL
use Northwind 
declare @chrNOMBRE  as nvarchar(40)
set @chrNOMBRE  = 'Queso'
--set @chrNOMBRE  = '‘

IF @chrNOMBRE = '' 
select * from dbo.Products
ELSE 
select * from dbo.Products where ProductName like '%'+@chrNOMBRE+'%'

This is equivalent to:

SQL
select * from dbo.Products 
where ProductName like '%' + UPPER(@chrNOMBRE) + '%'

Example 2:

SQL
use Northwind 
Declare @productID as int 
set  @productID = 3
if @productID = 0 
begin
      select * from dbo.Products 
end
else
begin
      select * from dbo.Products 
      where ProductID = @productID 
end

It’s equivalent to:

SQL
use Northwind 
Declare @productID as int 
set  @productID = 0
select * from dbo.Products 
where ProductID = case @productID when 0 then ProductID else @productID end

Rows Count

The best way to make a row count is by using a constant inside the function instead of using “*”; that’s because SQL Server first gets all the information of the columns and rows required and then counts the data. The sentence below:

SQL
SELECT     @NUM=COUNT(*) FROM Products

Is better if you rewrite in this way:

SQL
SELECT     @NUM= COUNT (1) FROM  Products

Null Values

You cannot compare null values on a sentence like in the next example:

Example 1:

SQL
select * from dbo.Orders where ShipRegion = null

Is better if you do the following:

SQL
select * from dbo.Orders where ShipRegion is null 

Example 2:

SQL
declare @ShipRegion nvarchar(15)
set @ShipRegion = ''
select * from dbo.Orders 
where ShipRegion = case when @ShipRegion = '' then ShipRegion else @ShipRegion end

Having that in the previous declaration, the column “ShipRegion” allows nulls, the declaration must be rewritten as follows:

SQL
declare @ShipRegion nvarchar(15)
set @ShipRegion = ''
select * from dbo.Orders 
where isnull(ShipRegion, '') = case when @ShipRegion = '' 
      then isnull(ShipRegion, '') else @ShipRegion end

Get Values from a Table

SQL
use Northwind 
Declare @productID as int 
Declare @productName as nvarchar(40)
Declare @QuantityPerUnit as nvarchar(40)
Declare @UnitPrice as money

/*You can do this:*/
set  @productID = (select top 1 ProductID from dbo.Products)
set  @productName = (select top 1 ProductName from dbo.Products)

/*but, Is better to do the following:*/
select top 1 @productID = ProductID, @productName = ProductName, 
            @QuantityPerUnit = QuantityPerUnit, @UnitPrice = UnitPrice 
from dbo.Products 

select top 1 @productID, @productName, @QuantityPerUnit, @UnitPrice

Considerations When Coding Stored Procedures with Transact SQL

  • Use standards
  • Write comments (that helps future reviews and corrections)
  • Try to avoid the use of cursors
  • Don't write queries with “SELECT *
  • Use "SET NOCOUNT ON"
  • Be careful with the use of transactions
  • Avoid using more than one action in a Stored Procedure
  • Use “RETURN” if you are going to get a value from the database

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Peru Peru
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
General[My vote of 1] Could be a good start but needs work sorry Pin
spoodygoon3-Jun-10 14:47
spoodygoon3-Jun-10 14:47 
I'm sorry but I vote 1 as well, but if you would like I'll make a few suggestions that may help.

1. At the bottom of the page there is a bullit point that say "Don't write queries with “SELECT *”" but that is almost all you did in the article.
2. No mention of data structure, no sql statment no matter how good can make up for bad structure.
3. Using functions in a where statement cause that function to be called for every row.
4. Same things goes for casting in the where statment if your casting a variable do it ahead of time
5. There is no mention of locking/isolation or join hints
6. No mention at all of indexes
7. No mention of SET STATISTICS IO/TIME ON/OFF which would tell you a lot about performance.
8. Joins and sub queries get 2 lines?
9. No mention of the use of IN ('','') as instead of chaining AND/OR together

I hope your not angry with me but the article just needs to be worked on, it has a long way to go before it can be concidered "Best Practices". However it can be a good start for you to work on.
GeneralMy vote of 1 Pin
icestatue3-Jun-10 9:36
icestatue3-Jun-10 9:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.