You are on page 1of 476

Introduction To TSQL

Unit 1

Developed by
Michael Hotek

•  SQL - Structured Query Language

•  SQL is probably one of the simplest
languages you will ever learn. It is
also very simple to underestimate.
DON’T!!! This is arguably the most
powerful language you will learn.
•  SQL is a set oriented language. It
was designed and built to manage
groups of data.
•  ER Diagram - Entity Relationship
•  An ER Diagram, also known as a
database schema, gives you a
graphical depiction of the database
you are working with.
PUBS Database
Unit 1

•  What is a database
•  What is a table
•  Rows and columns
•  Connecting to your database
•  Change databases
•  Overview of PUBS database
•  Simple select
•  Select all columns from a table
•  Select specific columns from a table
•  Concatenate two columns
•  Create a query to give formatted

•  At the most basic level a database is

really just a file.

•  Databases come in all shapes and

sizes. Some are large and some are
small. But each database generally
serves a particular purpose.

•  Examples: Tracking employee

payroll, sales data on a particular
sales line, stock data for a particular

•  All databases are made up of

objects. The most important object
(and the one we will learn how to use
in this class) is a table.

•  A table is a storage structure made up

of rows and columns. (Sort of like a

•  Due to the differing terminologies,

there are interchangeable sets of

Database Mathematical Data Processing

Table Relation File
Row Tuple Record
Column Attribute Field

•  These terms are used interchangeably,

but we will generally use the table –
row – column terminology
Tables cont.

•  You will also hear a table referred to

as an entity. (Hence the name Entity
– Relationship Diagram)

•  In the most basic sense, an entity is

a person, place, thing, or idea.

•  Entities usually become tables

•  Example: books, publishers, titles,

Connect to a database

•  In this class we will use a tool called

ISQL/W. This stands for Interactive
SQL / Windows. This is where we
will execute all of our queries from.
A query as the term implies is a
question we ask the database.

•  In other environments you will see

this query tool called by different
names. It is generally referred to as
just isql.

•  Regardless of name, they all perform

the same purpose. This is to give
you an interface for sending SQL
statements and receiving results.
SQL Server Login

•  Startup ISQL/W
•  Login window
•  A SQL Server can have many
different databases running on it at
the same time.
•  Database setup on the server
•  Assign databases
•  Your first SQL statement
•  use <database>
•  This tells the SQL Server what
database you will be using to perform
your queries.
•  Example: use PUBS1
Verify your database

•  To check the database you are

accessing use:
•  select db_name()
•  Throughout this course some of the
things we discuss will be MS SQL
Server specific. The DBMS you are
using should have a command or
function similar to this, but not
necessarily the same.
Basic syntax rules

•  SQL keywords (use, select, from,

where, etc.) are case insensitive.

•  select is the same as SELECT is the

same as SeLeCt, etc.

•  However depending on the DBMS

(Database Management System), the
columns might be case sensitive.

•  select title_id from titles is not

necessarily the same as

•  The databases we have setup on our

server are case insensitive.
Rules cont.

•  Spacing does not matter (for the

most part).

•  select title_id…
is the same as
select title_id…

•  However, you must still separate

words. You can not use the
selecttitle_id… This will give a
syntax error, because SQL Server
must be able to find your SQL
Rules cont.

•  Carriage returns are ignored

•  select title_id from titles

is the same as
select title_id
from titles

•  The spacing and carriage returns just

make reading your SQL a lot easier.

•  The general format used by most

people is to place the separate
clauses of the statement on different
PUBS Database

•  PUBS is a database for a fictitious

book distributor that sells books to
book resellers. This is the database
for which you have an ER diagram

•  ER diagram explanation

•  You will generally get an ER diagram

at each client when you begin work
on a project. If you don’t have one,
ask for one. This will save time in
trying to determine what data is
where and how everything is linked
together. If you can’t get one, don’t
panic! There are ways to get the
database to tell you what it contains.

SELECT Statement Retrieves rows from the database.

SELECT [ALL | DISTINCT] <select_list> INTO [<new_table_name>]
[FROM <table_name> [, <table_name2> [..., <table_name16>]]
[WHERE <clause>] [GROUP BY <clause>] [HAVING <clause>] [ORDER
BY <clause>]
where <table_name> | <view_name> =
[[<database>.]<owner>.]{<table_name>. | <view_name>.}
<joined_table> =
{<table_name> CROSS JOIN <table_name> | <table_name> {INNER | LEFT
FULL [OUTER]} JOIN <table_name> ON <search_conditions>}
One or more of the following, separated with a space:
[INDEX = {<index_name> | <index_id>}]
WHERE <clause> =
WHERE <search_conditions>
GROUP BY <clause> =
GROUP BY [ALL] <aggregate_free_expression> [[,
HAVING <clause> =
HAVING <search_conditions>
ORDER BY <clause> =
ORDER BY {{<table_name>. | <view_name>.}<column_name> |
<select_list_number> | <expression>} [ASC | DESC] [...
{{<table_name16>. | <view_name16>.}<column_name> |
<select_list_number> | <expression>} [ASC | DESC]]
COMPUTE <clause> =
COMPUTE <row_aggregate>(<column_name>) [,
[BY <column_name> [, <column_name>]...]

•  A select statement is used to retrieve

data from a database. As you can
see from the syntax above, a select
statement can get very complicated.

•  Depending on the type of SQL

statement you are using most of this
is optional.

•  In order to get information from the

database, you must tell the database
what you are looking for. The first
step along this journey is to get some
simple information from the

•  select 'Mary had a little lamb.'

Mary had a little lamb.
(1 row affected)

•  If you ever want to return a specific

phrase from a database, use this

•  An asterisk (*) is used to designate

all columns in a table.

select *

•  We also need to tell it which table to

get the data from.

select * from authors

•  The main sections in every SQL

statement are called clauses. The
three clauses will will focus on are
the select, from, and where.

select * from authors

au_id au_lname au_fname
phone ...
----------- -------------------- --------------------
172-32-1176 White Johnson 408
213-46-8915 Green Marjorie 415
238-95-7766 Carson Cheryl 415
267-41-2394 O'Leary Michael 408
274-80-9391 Straight Dean 415
341-22-1782 Smith Meander 913
409-56-7008 Bennet Abraham 415
427-17-2319 Dull Ann 415
472-27-2349 Gringlesby Burt 707
486-29-1786 Locksley Charlene 415
527-72-3246 Greene Morningstar 615
648-92-1872 Blotchet-Halls Reginald 503
672-71-3249 Yokomoto Akiko 415
712-45-1867 del Castillo Innes 615
722-51-5454 DeFrance Michel 219
724-08-9931 Stringer Dirk 415
724-80-9391 MacFeather Stearns 415
756-30-7391 Karsen Livia 415

•  We can limit the columns returned by

specifying them instead of using *.
select au_lname, au_fname from
au_lname au_fname
White Johnson
Green Marjorie
Carson Cheryl
O'Leary Michael
Straight Dean
Smith Meander
Bennet Abraham
Dull Ann
Gringlesby Burt
Locksley Charlene
Greene Morningstar
Blotchet-Halls Reginald
Yokomoto Akiko
del Castillo Innes
DeFrance Michel
Stringer Dirk
MacFeather Stearns
Karsen Livia
Panteley Sylvia
Hunter Sheryl
McBadden Heather
Ringer Anne
Ringer Albert

(23 row(s) affected)


•  When you specify columns, you do not

have to specify them in the order they
appear in the table.

•  You could have also executed the


select au_fname, au_lname from

au_fname au_lname
Johnson White
Marjorie Green
Cheryl Carson
Michael O'Leary
Dean Straight
Meander Smith
Abraham Bennet
Ann Dull
Burt Gringlesby
(23 row(s) affected)

•  We can also combine data together.

This is called concatenation.
•  We really want to display the first
name and the last name separated
by a space and then the rest of the
data. The plus symbol (+) is the
most widely used symbol for
concatenation. (A double pipe || is
sometimes used, but very rarely.)
select au_fname+au_lname from authors
Innesdel Castillo
(23 row(s) affected)
Concatenation cont.

•  Concatenation is used for string

(character) data. If a concatenation
operator (+) is used on numeric data,
the data is simply added together.

select title_id,price,advance from titles

title_id price advance
-------- --------------------------
BU1032 19.99 5,000.00
BU1111 11.95 5,000.00
BU2075 2.99 10,125.00
BU7832 19.99 5,000.00
MC2222 19.99 0.00
(18 row(s) affected)

select title_id,price+advance from titles

-------- --------------------------
BU1032 5,019.99
BU1111 5,011.95
BU2075 10,127.99
BU7832 5,019.99
MC2222 19.99
(18 row(s) affected)

•  By combining the first select (selecting a

constant) with the select on authors we did
above, we can get some formatted output
from the database.

•  select au_fname+’ ‘ + au_lname, city + ’,’ +

state + ’ ‘+zip from authors
Johnson White Menlo Park,CA 94025
Marjorie Green Oakland,CA 94618
Cheryl Carson Berkeley,CA 94705
Michael O'Leary San Jose,CA 95128
Dean Straight Oakland,CA 94609
Meander Smith Lawrence,KS 66044
Abraham Bennet Berkeley,CA 94705
Ann Dull Palo Alto,CA 94301
Burt Gringlesby Covelo,CA 95428
(23 row(s) affected)

•  One of the many things you should take

away from this class is the ability to put
together a SQL statement like the one
above. This simple principle saves DBAs
hundreds of hours and year and makes
their jobs much more simple.

•  The title for our previous result set

isn't too informative, and we really
don't want to display our formula.

•  We can rename or alias a column in

two ways
–  Use a space and then the alias
–  Specify the keyword as and then the

•  select au_fname+’ ‘ + au_lname, city

+ ’,’ + state + ’ ‘+zip Name_Address
from authors

•  select au_fname+’ ‘ + au_lname, city

+ ’,’ + state + ’ ‘+zip as
Name_Address from authors

•  We can apply aliases in two places

within our SQL statements
–  Select clause
–  From clause

•  By specifying an alias in the select

clause we can rename the column
headers for the output

•  By specifying an alias in the from

clause, we can save some typing
and also perform some higher level
queries which will require this. (This
will be demonstrated in subsequent
Unit 1 Review

•  A database is a collection of objects, the

most prominent of which is a table.
•  A table consists of rows/tuples/records
and columns/attributes/fields.
•  use <dbname> allows you to select a
•  SQL keywords are not case sensitive.
•  Spacing and carriage returns are not
•  You can include a constant in your result
set by hadding it just as you would a
•  An * allows you to select all columns in a
•  A + is used for concatenating two
Unit 1 Exercises

•  Time allotted for exercises is 30

Introduction To SQL
Unit 2

Modern Business
Developed by
Michael Hotek
Unit 2

•  Limit result set with where
•  Use compound criteria
•  Grouping conditions
•  Comparison operators
•  Ranges
•  Wildcards
•  Escape characters
•  Pattern Matching
•  Negation

•  So far we have returned the entire

contents of a table.

•  This is usually not very practical

•  Suppose we wanted to see the

authors that live in California.

•  We could do a select * from authors

and scroll through the result set
looking for those where state = CA

•  While feasible for a small table, this

is not practical.

•  So to limit the result set to just the

data you need, we will use the third
major SQL clause: where

•  The where clause tells the database

which rows to retrieve.

•  To just retrieve those authors that live

in CA, we would use the following:

•  select au_lname, aufname, state

from authors where state = 'CA'
au_lname au_fname state
---------------------------------------- -------------------- -----
White Johnson CA
Green Marjorie CA
Carson Cheryl CA
O'Leary Michael CA
(15 row(s) affected)
Compound Criteria

•  This limited our result set to just

those authors in CA

•  But our list of authors could begin to

get very large and we’re only looking
for those authors with a last name of

•  We would do this with the following:

•  select au_lname, au_fname, state

from authors where state = 'CA' and
lname = 'Green'
au_lname au_fname state
---------------------------------------- -------------------- -----
Green Marjorie CA

(1 row(s) affected)
Compound Criteria

•  Make sure you are careful with the

spelling. Our database is case
insensitive, but this does not apply to
the data values.

•  Green does not equal GREEN

Compound Criteria

•  Now that we know how to get just

those authors who live in CA, how do
we get the authors that live in KS

•  We accomplish this through the use

of an OR instead of an AND

•  select * from authors where state =

'CA' or state = 'KS'
au_lname au_fname state
---------------------------------------- -------------------- -----
White Johnson CA
Green Marjorie CA
Carson Cheryl CA
O'Leary Michael CA
Straight Dean CA
Smith Meander KS
Bennet Abraham CA
Dull Ann CA
Gringlesby Burt CA
Locksley Charlene CA
(16 row(s) affected)
Compound Criteria

•  So, what is the difference between

using an AND and an OR?

•  The AND is exclusive

–  This means that the row must meet all of the
conditions in order to be selected

•  The OR is inclusive
–  This means that for a row to be selected, it
has to meet just one of the criteria
Compound Criteria

•  Now we are going to get a little more


•  We want to select all authors who

live in KS with a last name of Smith
and also every author from CA.

•  We know how to do the first part

•  select au_lname, au_fname, state

from authors where state = 'KS' and
au_lname = 'Smith'
Compound Criteria

•  We also know how to do the second


•  select au_lname, au_fname, state

from authors where state = 'CA'

•  We just need to put them together

•  select au_lname, au_fname, state

from authors where state = 'KS' and
au_lname = 'Smith' or state = 'CA'
au_lname au_fname state
---------------------------------------- -------------------- -----
Smith George CA
White Johnson CA
Green Marjorie CA
Carson Cheryl CA
O'Leary Michael CA
Straight Dean CA
Smith Meander KS
Bennet Abraham CA
(17 row(s) affected)
Grouping Criteria

•  While this SQL statement returns the

data we want, it isn’t very clear and is

•  When using compound criteria in a

where clause, you should always
group the criteria to make it plain
exactly what you want.

•  You group by using parenthesis

•  The proper SQL statement is as


•  select * from authors where (state =

'KS' and lname = 'Smith') or state =

•  Besides using an =, you can also use

any of the other comparison
operators: >, <, <=, >=.

•  Suppose we want to return all of the

books with a price greater than
select title_id, price from titles where price > 10

•  We could also write:

select title_id, price from titles where price >
title_id price
-------- --------------------------
BU1032 19.99
BU1111 11.95
BU7832 19.99
MC2222 19.99
PC1035 22.95
PC8888 20.00
(12 row(s) affected)

•  One other thing you can take

advantage of with comparison
operators is that they don’t simply
apply to numeric types of data.

•  They can also be used on character


•  To select all authors who live in

states that come after MA we could
use the following
select au_lname, state from authors where
state > 'MA'
au_lname state
---------------------------------------- -----
Greene TN
Blotchet-Halls OR
del Castillo MI
Panteley MD
Ringer UT
Ringer UT

(6 row(s) affected)
Range Output

•  Suppose we want to select all

authors who live in CA, MI, KS, and

•  We could write the following:

select au_lname, state from authors where
state = 'CA' or state = 'MI' or state = 'KS' or
state = 'UT'

•  With long lists, this get get very

tedious and take a lot of typing.

•  Fortunately, SQL gives us something

much better

•  Instead of using multiple ORs, we

can use an IN operator

select au_lname, state from authors where

state in ('CA','KS','MI','UT')

•  This will return the same list

au_lname state
---------------------------------------- -----
Smith CA
White CA
Straight CA
Smith KS
Bennet CA
Yokomoto CA
del Castillo MI
Stringer CA
McBadden CA
Ringer UT
Ringer UT

(20 row(s) affected)

Range Output

•  We now want to select all books that

have a price greater than or equal to
$10, but also less than or equal to

•  We could write the following:

select title_id, price from titles where price >=

10 and price <= 20

•  But, there is a much simpler way

•  SQL has given us a between


select title_id, price from titles where price

between 10 and 20

•  Sometimes we do not know exactly

what we are looking for

•  Or we are looking for the group of

data that match a certain pattern

•  In these cases we would use

wildcards within our where clause

•  SQL has two wildcard characters

–  The percent (%) symbol designates any
string of zero or more characters
–  The underscore (_) designates a single

•  Suppose we wanted to select all

authors whose first names start with

select au_fname, au_lname from authors where

au_fname like 'M%'
au_fname au_lname
Marjorie Green
Michael O'Leary
Meander Smith
Morningstar Greene
Michel DeFrance

(5 row(s) affected)

•  Maybe we want to select all of the

authors whose first name is Carl.

•  We have to be careful here, because

it could be spelled Carl or Karl

select au_fname, au_lname from authors where

au_fname like '_arl'
au_fname au_lname
-------------------- ----------------------------------------
Carl Burns
Karl Johnson

(2 row(s) affected)

•  You can combine wildcards to

retrieve exactly what you need

•  Suppose we needed to retrieve all of

the Smiths in the database

•  The last name could be spelled

Smith, Smithe, or Smythe. We want
to retrieve all of the spellings

select au_fname, au_lname from authors where

au_lname like 'Sm_th%'
au_fname au_lname
-------------------- ----------------------------------------
Meander Smith
Jim Smithe
Patti Smythe

(3 row(s) affected)
Escape characters

•  But what happens when we really

want to find a % inside of the data

•  To find this data we will employ an

escape character

select notes from titles where notes like '%@%

%' escape '@'

•  This tells the DBMS to treat the next

character after the escape character
(@) as a literal string
What happens when the data runs dry?%

(1 row(s) affected)
Pattern Matching

•  But what do we do when we know

what we are looking for, but know it
could have many variations.

•  We can employ a technique called

pattern matching

•  This technique can mix wildcards

with sets of characters that required
to be present

•  These are designated within brackets

inside of the string we are matching
Pattern Matching

•  Suppose we wanted to retrieve all of

the authors whose last names
started with either an L, M, or S

select au_lname, au_fname from authors where

au_lname like '[LMS]%'
au_lname au_fname
---------------------------------------- --------------------
Locksley Charlene
MacFeather Stearns
McBadden Heather
Smith George
Smith Meander
Smithe Jim
Smythe Patti
Straight Dean
Stringer Dirk

(9 row(s) affected)
Pattern Matching

•  Suppose we want to retrieve all five

letter first names where only the first
character is uppercase
•  We do not want to retrieve name
names like McDay
•  We also don't want names with
special characters like apostrophes

select au_lname, au_fname from authors where

au_lname like '[A-Z][a-z][a-z][a-z]'
au_lname au_fname
---------------------------------------- --------------------
Dull Ann

(1 row(s) affected)
Pattern Matching

•  We want to retrieve all books with a

title of Life Without Fear, but don't
know how the word without was
stored (uppercase, lowercase, or
mixed case)

select title_id, titles from titles where title

like '%[Ww][Ii][Tt][Hh][Oo][Uu][Tt]%'
title_id title
-------- --------------------------------------------------------
PS2106 Life Without Fear

(1 row(s) affected)
Pattern Matching

•  We now want to retrieve just those

authors whose first name is four
characters long

select au_lname, au_fname from authors where

au_fname like '____' (That's four
underscore characters)
au_lname au_fname
---------------------------------------- --------------------
Burns Carl
Gringlesby Burt
Johnson Karl
Ringer Ann
Straight Dean
Stringer Dirk

(6 row(s) affected)
Pattern Matching

•  But you ask, why do we see the entry

for Ann in this list. It only has three

•  This is for two reasons

–  There was a space added to the end
–  Depending on how the database was set
up, it could pad spaces on to the end
(Beyond scope)
Pattern Matching

•  To get around this we exclude the


select * from authors where au_fname

like '[^ ] [^ ] [^ ] [^ ]'
au_id au_lname au_fname
----------- ----------------------------------------
111-11-1112 Burns Carl
111-11-1113 Johnson Karl
274-80-9391 Straight Dean
472-27-2349 Gringlesby Burt
724-08-9931 Stringer Dirk

(5 row(s) affected)

•  The caret is a negation operator.

The query above says to retrieve any
first names that do not have a space
as one of the four characters
Pattern Matching

•  Granted, in most real world situations

you will not go to these lengths when
retrieving data.

•  But constructs like this are used

extensively to ensure only valid data
is entered into tables

•  Rules and constraints are beyond the

scope of this unit, but the examples
below are for demonstrative
purposes to give an idea of further
applications to pattern matching
Pattern Matching

•  Suppose you have a column that will

accept 6 characters

•  You have to be careful, because

numbers and special characters like
#,@,& will also go in this column

•  To restrict this to just characters, use

the following

[A-z] [A-z] [A-z] [A-z] [A-z] [A-z]

Real World Example

•  A table we are working with stores

social security numbers (complete
with dashes)

'[0-9] [0-9] [0-9]- [0-9] [0-9]- [0-9] [0-9]

[0-9] [0-9]'

•  Vehicle VIN numbers have a very

specific format that conforms to the
following VIN: 1G2JB14KOL7569785

' [0-9][A-Z] [0-9][A-Z][A-Z] [0-9] [0-9][A-

Z][A-Z][A-Z] [0-9] [0-9] [0-9] [0-9]
[0-9] [0-9] [0-9] '

•  We briefly touched on negation a few

slides before.

•  The negation operator is NOT or in

patterns a caret (^)

•  In a query above we extracted all

four letter first names that did not
have a space in them.

•  Now we want to extract everything

but these names

select au_fname, au_lname from authors where

au_fname not like '[^ ] [^ ] [^ ] [^ ]'
au_fname au_lname
-------------------- ----------------------------------------
Abraham Bennet
Reginald Blotchet-Halls
Carl Burns
Cheryl Carson
Michel DeFrance
Ann Dull
Marjorie Green
Morningstar Greene
Burt Gringlesby
Sheryl Hunter
Karl Johnson
Livia Karsen
(28 row(s) affected)

•  Select all authors who do not live in


select * from authors where state <> 'CA'

•  Depending on DBMS, this can also

be written as
select au_fname, au_lname from authors
where state != 'CA'
au_fname au_lname state
-------------------- ---------------------------------------- -----
Carl Burns MA
Karl Johnson MA
Patti Smythe MA
Jim Smithe MA
Meander Smith KS
Morningsta Greene TN
Reginald Blotchet-Halls OR
Innes del Castillo MI
Michel DeFrance IN
Sylvia Panteley MD
Anne Ringer UT
Albert Ringer UT

(12 row(s) affected)


•  A where clause allows us to restrict the

result set
•  We can combine multiple criteria in a single
where clause using and/or
•  We can use comparison operators to specify
ranges of data
•  IN allows us to easily specify a list of values
to find
•  Between simplifies some range searches
and is inclusive (The value specified as the
upper and lower bound is also retrieved)
•  We can use % and _ as wildcards to do
sophisticated searching
•  We can use an escape character to cause
SQL to ignore a wildcard and treat as a
•  These can be combined with pattern
matching to specify very specific patterns of
•  We can negate our searching by using not,
^, <>, or !=
Unit 2 Exercises

•  Time allotted is 30 minutes

Introduction To SQL
Unit 3

Modern Business
Developed by
Michael Hotek
Unit 3

•  Nulls
•  Group by
•  Order by
•  Distinct
•  Aggregates
•  Aggregates with grouping
•  Having
•  Compute
•  Unions

•  There are times when data is missing

or incomplete

•  To handle this missing data, most

DBMSs use the concept of a null

•  A null does not mean zero

•  A null also does not mean a blank

•  A null indicates that a value is

missing, unavailable, incomplete,
and inapplicable

•  Nulls represent an unknown quantity

or value

•  You can't guarantee that a null does

equal some other value

•  You also can't guarantee that a null

doesn't equal another value

•  A null also might or might not equal

another value

•  For example take the authors table

•  If we were to leave out the state data

for an author, this could bring up a
few questions

•  Is the author from CA?

•  Is the author not from CA?

•  Is the author from some other state?

•  Any or none of these questions could

be true

•  Any question about a null could

provide three answers: yes, no, or

•  This could mean that using nulls

gives us a very serious problem,
since rows are selected based on a
criteria being true

•  Fortunately the DBMS manufacturers

have given us some relief
Rules for Nulls

•  A null does not designate an

unknown value

•  A null does not equal another distinct


•  A null does not equal another null

Nulls cont.

•  I can obviously test for a null and I can place

a null into a column

•  Since I am placing the same "value" (a null)

into a column, how can a null not equal a

•  A null represents the nonexistence of data

•  Something that doesn't exist can't be

compared with something else that doesn't

•  If it could then, this would imply that the

values being compared actually do exist.
This violates the definition of a null
Nulls (theory aside)

•  All of this appears to be rather deep

and theoretical. In fact entire books
have been written about nulls.

•  This class is based on the practical

application of SQL theory

•  To that end the only things you need

to remember are the following:
–  You can select rows that have a null
–  A null does not equal a null
Nulls Applied

•  Suppose we want to get the titles

that do not have an assigned royalty

•  Based on our previous experience

we would probably do the following:
–  select * from titles where royalty = null

•  Paradoxically, this would work in

most DBMSs

•  This is because most DBMS

manufacturers recognize the
problems with null and seek to
protect you from yourself. The
DBMS will convert this into it's proper
form and return what you asked for
Nulls Applied

•  The proper way is to be explicit in

what you are asking.

•  We want to know where the values

are null

select title, royalty from titles where royalty is

- -----------
The Psychology of Computer Cooking (null)
Net Etiquette

(2 row(s) affected)
The Basics recap

•  This completes all of the basics of

selecting data

•  To quickly recap

•  The select clause specifies what

columns we want to see

•  The from clause tells what table we

want to see data from

•  The where clause restricts the data

we will see
Order by

•  The order by clause is used to

specify a sorting order of the result

•  The sorting can be performed by

column name or by column number

select au_fname,au_lname from authors order

by au_lname,au_fname


select au_fname,au_lname from authors order

by 2,1
Order by

•  Depending upon the DBMS, the

column you are ordering by does not
need to be specified in the select

select au_fname, au_lname from authors order

by state

•  While this does work on some

DBMSs, it is generally not advisable

•  The default sort order is ascending

(a-z), but you can specify a
descending order by using the
keyword desc

•  …order by au_lname desc,

Sort Order

•  If order by sorts the data, how do I

know what that order it is sorted in?

•  The sort order is determined by a

character set which is defined for a

•  In Sybase and MS SQL Server, this

character map can be retrieved by
executing sp_helpsort

exec sp_helpsort
Order by

•  An order by is not limited to actual

data columns

•  We can order by a calculation if we


select au_fname + ' ' + au_lname name from

authors order by name
Abraham Bennet
Akiko Yokomoto
Albert Ringer
Ann Dull
Meander Smith
Michael O'Leary
Michel DeFrance
Morningstar Greene
Patti Smythe
Reginald Blotchet-Halls
Sheryl Hunter
Stearns MacFeather
Sylvia Panteley

(27 row(s) affected)

Order by / Nulls

•  An order by is based upon a sort

order specified by a character set

•  Since nulls aren't characters, where

do these fit in?

•  Depending on the DBMS, you will

find the nulls at either the beginning
or the end of the result set.

•  Where they are depends on the way

the DBMS manufacturer has

•  As you have seen from some of the

queries we have run, you can get
what appear to be duplicate rows in
the result set

•  From the scope of the result set, they

are duplicates

•  From the scope of the database they

are not

•  This is because the select

statements we have performed up to
this point returned the row of data for
every row in a table that matched a
specific criteria

•  Sometimes we do not want to see

these duplicate rows

•  We can eliminate them by use of the

distinct keyword

•  The distinct is placed immediately

after the select

•  There can also be only one distinct

per SQL statement

•  The distinct applies to all columns in

the select list

select au_id from titleauthor


(25 row(s) affected)

select distinct au_id from titleauthor

(19 row(s) affected)


•  There are times when we want to

perform calculations on all of the
values in a column or table

•  We accomplish this through the use

of aggregates

•  The three we will explore are count,

sum, and average

•  Count will return exactly what it's

name implies

•  It returns a count of the number of

rows in a table that match a certain

select count(*) from authors will return the

number of rows in the authors table

(1 row(s) affected)

select count(*) from authors where state = 'CA'

will return the number of authors living in CA

(1 row(s) affected)

•  The sum is used to add up all of the

values in a column

select sum(advance) from titles will return the

total amount advanced to all authors

(1 row(s) affected)

•  Avg will return the average value in a


select avg(price) from titles will return the

average price of all books

(1 row(s) affected)

select avg(price) from titles where price > 10

will return the average price of the books
over $10

(1 row(s) affected)
Group by

•  Data in a table is essentially stored


•  We can impose one type of order on

the result set with an order by

•  We can impose another type of order

on a result set by using a group by
Group by

•  The group by will order the data into

groups that you specified and then
return the set of rows that determine
the groups

•  Duplicates are removed from this

result set

•  In this way, a group by performs a

similar operation to distinct

•  The distinct does not sort the data


•  You still need to specify an order by

clause to perform sorting
Group by

select type from titles group by type


(7 row(s) affected)

select type from titles group by type order by 1


(7 row(s) affected)
Group by and Nulls

•  Nulls are treated specially by a group

by clause

•  When a group by is being evaluated,

all nulls are put in the same group

select type from titles group by type


(7 row(s) affected)
Group by and where

•  You can use a where clause to limit

the set of data that the group by will

select type from titles where advance > 5000

group by type

(5 row(s) affected)
Group by

•  The true power of a group by comes

from using it in conjunction with an

•  Suppose we wanted a count of each

type of book

•  At first thought you might be tempted

to do this:

select type,count(*) from titles

Msg 8118, Level 16, State 1
Column 'titles.type' is invalid in the select list because it is not
contained in an aggregate function and there is no GROUP BY
Group by

•  This doesn’t quite get what we need

select type,count(*) from titles group by type

------------ -----------
(null) 2
business 2
mod_cook 2
popular_comp 3
psychology 5
trad_cook 3

(7 row(s) affected)
Group by

•  One thing to remember is that if you

use a group by with an aggregate,
you must specify all nonaggregate
columns in the group by clause

select city,state,count(*) from authors group by

state will return a syntax error
Msg 8120, Level 16, State 1
Column '' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.

select city,state,count(*) from authors group by

state,city will return a result set
city state
-------------------- ----- -----------
(null) MA 4
Ann Arbor MI 1
Berkeley CA 2
Corvallis OR 1
Covelo CA 1
Gary IN 1
(17 row(s) affected)
Group by

•  You can not specify an aggregate in

the group by clause

select count(*) from authors group by count(*)

will return a syntax error
Msg 144, Level 15, State 1
Cannot use an aggregate or a subquery in an expression used for the
by-list of a GROUP BY clause.

•  The having clause works just like a

where clause

•  There is a fundamental difference

•  The where clause defines the set of

data the grouping is done on

•  The having defines which groups are

going to be returned to the user

•  Having clause generally contain

aggregates as part of the selection

select pub_id,sum(advance) from titles group

by pub_id having sum(advance) > 10000
------ --------------------------
0736 24,400.00
0877 41,000.00
1389 30,000.00

(3 row(s) affected)

•  This will return only the set of

pub_ids that had an advance of more
then $10000.

select type,count(advance) from titles where

advance > 10000 group by type,advance

select type,count(advance) from titles group by

type,advance having advance > 10000

•  In both queries we want to know the

types of those books with an
advance > 10000, so why the
different results

•  This is due to the way the where and

having are applied

•  What happens is the data is selected

based on the result set
•  It is then passed to the group by for
•  Finally it goes to the having which
returns the data requested.

•  In the first query, only those rows that

had an advance of > $10000

•  The grouping is then applied to these


•  This was only 1 book for each of two

groups (the where criteria)

•  The having processes the

aggregates and grouping first instead
of the selection like where does

•  The having clause says give me the

groups that have one or more books
with an advance of > 10000

•  The concepts of where and having

clauses can get confusing very

•  The best way to get comfortable with

them is to perform a few and observe
the results

•  Then draw out each of the steps on

paper until you can duplicate the
result set

•  The book "The Practical SQL

Handbook" has a good explanation
on pages 180 - 185

•  Now that everything is about as clear

as mud, we are going to introduce
another clause that can be employed

•  In a nutshell, a compute is used to

calculate grand summaries

select title_id,type,price from titles where type

like '%cook%' compute avg(price)
title_id type price
-------- ------------ --------------------------
MC2222 mod_cook 19.99
MC3021 mod_cook 2.99
TC3218 trad_cook 20.95
TC4203 trad_cook 11.95
TC7777 trad_cook 14.99


(6 row(s) affected)
Compute by

•  A compute by is used to
•  This construct must be used with an
order by
select title_id, type, price from titles where type
like '%cook%' order by type compute
avg(price) by type
title_id type price
-------- ------------ --------------------------
MC2222 mod_cook 19.99
MC3021 mod_cook 2.99


title_id type price

-------- ------------ --------------------------
TC3218 trad_cook 20.95
TC4203 trad_cook 11.95
TC7777 trad_cook 14.99


(7 row(s) affected)
Compute/Compute by

•  These can be used in the same

select title_id,type,price from titles where type in
('business','mod_cook') order by type
compute sum(price) by type compute
title_id type price
-------- ------------ --------------------------
BU2075 business 2.99
BU7832 business 19.99


title_id type price

-------- ------------ --------------------------
MC2222 mod_cook 19.99
MC3021 mod_cook 2.99


(7 row(s) affected)
Compute/Compute by

•  With a compute/computed by, you
can only use columns in the select

select title_id,type from titles…compute

sum(price) would return a syntax error

•  You must order by the compute by


•  You can use any aggregate except

Compute/Compute by

•  Columns listed after the compute by
must be in the identical order to or a
subset of those listed after the order

•  Expressions must be in the same left

- right order

•  Compute by must start with the same

expressions as listed after order by
and not skip any expressions
Compute/Compute by

•  order by a,b,c
•  compute by a,b,c
•  compute by a,b
•  compute avg(price) by a

•  order by a,b,c
•  compute by b,a,c
•  compute by c,a
•  compute avg(price) by b

•  There are times when we want to

return two or more sets of data within
a single select statement

•  Examples of this are combining data

from two different tables when they
have mutually exclusive criteria

•  To do this we use a union


select * from authors where state = 'CA' union select * from authors where state
= 'MA'
au_lname state
---------------------------------------- -----
Bennet CA
Carson CA
Dull CA
Green CA
Gringlesby CA
Hunter CA
Karsen CA
Locksley CA
MacFeather CA
McBadden CA
O'Leary CA
Straight CA
Stringer CA
White CA
Yokomoto CA
Burns MA
Johnson MA
Smithe MA
Smythe MA

(19 row(s) affected)


•  The only restrictions on unions are

that the same number of columns
must be in each separate result set
and the datatypes must match

•  You can not union a select statement

that returns 2 columns with a select
that returns 3 columns

•  You also can't union a result set

where the first column of one select
is character data and the first column
of another select is numeric data
Unit 3 Review

•  Nulls are used to represent the nonexistence

of data
•  A null doesn't equal another null
•  An order by can be used to sort the result
•  The sort order is determined by the
database's character set
•  To remove duplicate rows from a result set
use distinct
•  You can perform calculations using
aggregates count(*), sum,avg are the most
•  You can group data together by using a
group by
•  Group by can be combined with aggregates
to perform sophisticated calculations
•  A having clause performs a restriction on a
group by
•  Having and where behave differently due to
the order they process the row selection
•  Compute can be used to calculate grand
Unit 3 Review cont.

•  Compute by can be used to calculate sub

•  Unions allow us to combine multiple results
sets and return them to the user in a group
Unit 3 Exercises

•  Time allotted for exercises is 1 hour

Introduction To SQL
Unit 4 To TSQL
Unit 4

Modern Business
Developed by
Michael Hotek
Unit 4

•  Primary keys
•  Foreign keys
•  Joining tables
•  Sub-selects
•  Advantages/disadvantages of joins
and sub-selects

•  A database derives its usefulness

from containing a group of tables that
have some relationship to each other

•  An entity is a person, place, or thing

of importance to an organization

•  An entity generally becomes a table

•  Relationships are the connections

between tables

•  Relationships are usually

implemented as keys in a database

•  For example take the titles and

publishers table

•  Every publisher publishes a title

•  And every title has a publisher

•  This relationship is implemented by

means of the key pub_id

•  Relationships come in three different


•  One to one
–  One row in a table is related to exactly
one row in another table

•  One to many
–  One row in a table is related to one or
more rows in another table

•  Many to many
–  Many rows in a table are related to one
or more rows in another table

•  A many to many relationship is

extremely poor database design

•  This type of relationship can cause a

large amount of confusion

•  The problem is that many to many

relationships do exist and must be
stored in a database

•  This is usually resolved into multiple

one to many relationships also
known as an intersection table

•  An intersection table is an artificial

construct that is commonly used in

•  It does not have any physical

meaning, but instead serves to break
up a many to many relationship

•  The titleauthor table is an example of

an intersection table

•  Relationships are implemented in a

database as keys

•  Keys are a logical construct; they are

not a physical part of the database

•  This means that a key does not

represent any physically quantifiable

•  You will generally see numbers used

as keys in a database (au_id,
pub_id, stor_id)
Primary Key

•  A primary key is a special type of key

that consists of one or more columns
that uniquely identify a row

•  Primary keys must be unique and

can not contain null values

•  A table will only have one primary


•  A primary key will reside on the one

side of a 1 - N relationship
Primary Key

•  pub_id is the primary key for the

publishers table

•  This will uniquely identify each

publisher in the table

•  We do not use the publisher's name,

because this could be the same as
another publisher

•  Also, it is easy to control data input to

ensure it is valid

•  It is much easier to check 4 digits

than 40 characters. Also a name can
be null.
Foreign Key

•  A foreign key is one or more columns

that refer to a primary key of another

•  pub_id is the primary key of


•  pub_id is a foreign key in titles

•  Example:
A publisher can publish many titles, but
a title must have a publisher
This relationship is shown by the
primary key of the publishers table
being stored with the title that
publisher published.
Composite Keys

•  A primary key and a foreign key can

consist of more than one column

•  When a key contains more than one

column, it is known as a composite

•  The primary key of the titleauthor

table is a composite (au_id,title_id)

•  A discussion of indexes is well

beyond the scope of this course,
there are a few naming items that
can be noted

•  Keys will be implemented in a

database as an object called an

•  An index could be a primary key, a

foreign key, or neither

•  A primary key is the same as a

primary index or unique index

•  A foreign key is the same as a

foreign index

•  Up to this point we have confined our

queries to a single table

•  While this is done primarily for

retrieving data into transaction
processing applications, it doesn't
represent a real world application of
data querying

•  All of the data in a database is

segmented into tables and we
generally need data from more than
one table to show what we need

•  To accomplish this, we use a join


•  You will notice that there is no such

thing as a join clause in our SQL

•  A join is simply a where clause

•  A join is generally constructed

between one primary key and
another primary key or between a
primary key and a foreign key

•  (Discussion of PK/FK symbols on

the ER Diagram)

•  Suppose we want to view a list of

sales for each store
•  We could simply do the following:

select * from sales

stor_id ord_num ord_date qty payterms...
------- ------------ ---------------------- ------ --------
6380 6871 Sep 14 1994 12:00AM 5 Net 60...
6380 722a Sep 13 1994 12:00AM 3 Net 60...
7066 A2976 May 24 1993 12:00AM 50 Net 30...
7066 QA7442.3 Sep 13 1994 12:00AM 75 ON invoice
7067 D4482 Sep 14 1994 12:00AM 10 Net 60...
7067 P2121 Jun 15 1992 12:00AM 40 Net 30...
7067 P2121 Jun 15 1992 12:00AM 20 Net 30...
7067 P2121 Jun 15 1992 12:00AM 20 Net 30...
7131 N914008 Sep 14 1994 12:00AM 20 Net 30...
7131 N914014 Sep 14 1994 12:00AM 25 Net 30...
7131 P3087a May 29 1993 12:00AM 20 Net 60...
(22 row(s) affected)

•  But, the stor_id is meaningless to us


•  What we want to see is the store

name, city, and state along with the
sales for each order

select stor_name,ord_num,qty from

stores,sales where stores.stor_id =
stor_name ord_num qty
---------------------------------------- -------------------- ------
Eric the Read Books 6871 5
Eric the Read Books 722a 3
Barnum's A2976 50
Barnum's QA7442.3 75
News & Brews D4482 10
News & Brews P2121 40
News & Brews P2121 20
News & Brews P2121 20
Doc-U-Mat: Quality Laundry and Books N914008 20
Doc-U-Mat: Quality Laundry and Books N914014 25
Doc-U-Mat: Quality Laundry and Books P3087a 20
Doc-U-Mat: Quality Laundry and Books P3087a 25
Doc-U-Mat: Quality Laundry and Books P3087a 15
Doc-U-Mat: Quality Laundry and Books P3087a 25
Fricative Bookshop QQ2299 15
Fricative Bookshop TQ456 10
Fricative Bookshop X999 35
Bookbeat 423LL922 15
(22 row(s) affected)

•  What does this mean?

•  The select clause simply designates

which columns we want to see. If we
were retrieving a column that had the
same name in the two tables, we
would have to specify which table the
data was coming from

select stores.stor_id,stor_name, ord_num, qty

from stores,sales
where stores.stor_id = sales.stor_id

•  From clause

•  We are retrieving data from more

than one table, so each table must
be specified in the from clause

•  The from clause can be seen as the

main driver of a SQL statement

•  If the table isn’t in the from clause,

none of it's columns can be used in
any other clause

•  The where clause

where stores.stor_id = sales.stor_id

•  This tells the DBMS to take the first

store ID in the stores table and add
the data from the corresponding
store ID in the sales table to the data
retrieved from the stores table

•  It then continues with the second

store ID, etc. until it reaches the end
of the table

•  A join can be seen as a special type

of selection criteria.

•  If there is a stor_id in the stores table

that does not exist in the sales table,
the data for that particular store will
not be returned

•  You can also add additional selection


select stores.stor_id,stor_name,city,
from stores,sales
where stores.stor_id = sales.stor_id and state =

•  As we have seen, you can specify

just those columns that you want to

•  For instance we are just concerned

with the quantity of sales in CA

select sum(qty) from stores,sales where

stores.stor_id = sales.stor_id and state =

(1 row(s) affected)

•  The type of join we have examined

so far is also referred to as an equi-
join or an inner join

•  In the case of stores and sales, we

could have a store that doesn't have
any sales

•  If we use the equi-join, we will not

see these stores that do not have
any sales

•  So, how do we get the list of sales for

all stores regardless of whether they
have any sales
Outer Joins

•  We accomplish this via an outer join

select stores.stor_id,stor_name, ord_num, qty

from stores,sales where stores.stor_id *=
stor_id stor_name ord_num qty
------- ------------------------------------ -------------------- ----
6380 Eric the Read Books 6871 5
6380 Eric the Read Books 722a 3
7066 Barnum's A2976 50
7066 Barnum's QA7442.3 75
7067 News & Brews D4482 10
7067 News & Brews P2121 40
7067 News & Brews P2121 20
7067 News & Brews P2121 20
7131 Doc-U-Mat: Quality Laundry and Books N914008 20
7131 Doc-U-Mat: Quality Laundry and Books N914014 25
7131 Doc-U-Mat: Quality Laundry and Books P3087a 20
7131 Doc-U-Mat: Quality Laundry and Books P3087a 25
7131 Doc-U-Mat: Quality Laundry and Books P3087a 15
7131 Doc-U-Mat: Quality Laundry and Books P3087a 25
7896 Fricative Bookshop QQ2299 15
7896 Fricative Bookshop TQ456 10
7896 Fricative Bookshop X999 35
8042 Bookbeat 423LL922 15
8042 Bookbeat 423LL930 10
8042 Bookbeat 756756 5
8042 Bookbeat P723 25
8042 Bookbeat QA879.1 30
(22 row(s) affected)
Outer Joins

•  Notice the use of the asterisk (*)

where stores.stor_id *= sales.stor_id

•  This tells the DBMS to return all of

the rows in the stores table with the
corresponding data in the sales table
and do not drop any store IDs that
are not in the sales table

•  Note: The use of an asterisk to

designate an outer join is used in
SQL Server (Sybase and MS) most
other DBMSs support a slightly
different syntax as does the ANSI-92
Outer Joins

•  Outer joins come in three different

–  Left
–  Right
–  Full

•  A left outer join is the same thing as

a right outer join except for the order

•  Left: stores.stor_id *= sales.stor_id

•  Right: sales.stor_id =* stores.stor_id

•  Every left outer join can also be

expressed as a right outer join and
vice versa
Full Outer Join

•  A full outer join is included here for


•  You should use a full outer join

ONLY under very specific

•  A full outer join will produce a cross

product of the two tables

•  If you have one table with 100 rows

and another with 1000 rows, a full
outer join will produce a result set of
100,000 rows
Full Outer Join

•  This is because with a full outer join,

you are telling the database to give
every combination of rows possible

•  i.e. Each row is matched to every

row in the other table

•  This type is query will almost never

be preformed and should be avoided
at all costs.

•  The first time you inadvertently fire

one of these off, you will get a rather
angry call from your DBA

•  Subqueries are simply a SQL

statement nested inside of another
SQL statement

•  The most common place to do this is

in a where or having clause.

select [distinct] select_list

from table_list
where {expression {[not] in | comparison [any|
all]}|[not] exists}
(select [distinct] subquery_select_list from
table_list where conditions)
[group by group_by_list]
[having conditions]
[order by order_by_list]

•  Subqueries come in two basic kinds:

correlated and noncorrelated

•  A noncorrelated subquery is one in

which the inner query is independent,
gets evaluated first, and passes it’s
result set back to the outer query

•  A correlated subquery is one in which

the inner query is dependent upon
the results from the outer query

•  Below are examples of these two


•  noncorrelated:
select pub_name from publishers
where pub_id in (select pub_id from titles
where type = 'business')

•  correlated:
select pub_name from publishers p
where 'business' in (select type from titles
where oub_id = p.pub_id)

•  As is the case with most of the

subqueries, you can also express
them as a join

•  Subqueries also come in three

different types:

•  They return zero or more items

•  They return exactly one item
•  They test for existence of a value

•  If you have a subquery of the first

type it must be preceeded by an IN.
where column = (select…) will return
an error if the subquery returns more
than one item
Noncorrelated Subqueries

•  At a conceptual level, a noncorrelated

subquery is executed in two parts.

•  First the inner query is executed

•  It then passes its results back to the outer

query which then finds the rows that match
the list passed back

•  The column names are resolved implicitly

based upon the from clause of the
corresponding query. You can always
explicitly define the table name.

•  This is recommended for complex

Correlated Subqueries

•  Processing of a correlated subquery

is much more complicated, but these
can handle queries you can't easily
do with noncorrelated subqueries or

•  A correlated subquery depends on

data from the outer query

•  The inner query will execute once for

each row in the outer query
Correlated Subqueries

•  The outer query retrieves the first

row of data and passes the data
values to the inner query

•  The inner query finds all rows that

match the data passed from the
outer query

•  Finally the rows from the inner query

are checked against the conditions in
the outer query

•  If one or more rows match the

conditions, the data corresponding to
that row will be returned to the user
Joins or Subqueries

select distinct pub_name from publishers,

authors where =
select pub_name from publishers where city in
(select city from authors)
will return the same results

•  But if you want data from both the

publishers and authors tables, you
must use a join.

select pub_name,au_fname,au_lname
from publishers,authors
where =
Joins or Subqueries

select au_lname,au_fname,city from authors

where city in (select city from authors where
au_fname = 'Dick' and au_lname = 'Straight')
can also be expressed as
select au_lname,au_fname,city from authors
a1, authors a2 where = and
a2.au_fname = 'Dick' and a2.au_lname =

•  This is referred to as a self join

Joins or Subqueries

•  Whether you use joins or subqueries

is usually a matter of choice

•  Most joins can be expressed as

subqueries and vice versa

•  Calculating an aggregate and using

this in the selection criteria is an
advantage of subqueries

select title,price from titles

where price = (select min(price) from titles)

•  Displaying data from multiple tables

is usually done with a join
Common Restrictions

•  The select list of a inner query

introduced by an IN can have only
one column. This column must also
be join compatible with the column in
the where clause of the outer query

•  Subqueries introduced by an
unmodified comparison operator (not
followed by ANY or ALL) can not
include a group by or having clause
unless this will force the inner query
to return a single value

•  Subqueries can not manipulate their

results internally. i.e. They can not
contain an order by or the keyword
Any and All

•  You use the ANY and ALL keywords

with a comparison operator in a

•  > ALL means greater than every

value in the results of the inner query
(> maximum value)

•  > ANY means greater than any value

in the results of the inner query (>
minimum value)
Any and All

ALL Results ANY Results

> all (1,2,3) > 3 >any (1,2,3) > 1
< all (1,2,3) < 1 < any (1,2,3) < 3
= all (1,2,3) = 1 and =2 and =3 = any (1,2,3) =1
or =2 or =3

select title from titles where advance > all

(select advance from publishers,titles where
titles.pub_id = publishers.pub_id and
pub_name = 'New Age Books')
The Busy Executive's Database Guide
Cooking with Computers: Surreptitious Balance Sheets
You Can Combat Computer Stress!
Straight Talk About Computers
Silicon Valley Gastronomic Treats
The Gourmet Microwave
The Psychology of Computer Cooking
But Is It User Friendly?
Secrets of Silicon Valley
Net Etiquette
Computer Phobic AND Non-Phobic Individuals: Behavior Variations
Is Anger the Enemy?
Life Without Fear
Prolonged Data Deprivation: Four Case Studies
(18 row(s) affected)

•  The last type of subquery is used to

test for the existence of something

•  To find all of the publishers who

publish business books we would do
the following:

select distinct pub_name from publishers where

exists (select 1 from titles where pub_id =
publishers.pub_id and type = 'business')
Algodata Infosystems
New Moon Books

(2 row(s) affected)
Additional Restrictions

•  A subquery that test for existence will

either contain one column or an
asterisk in the select list. It makes no
sense to include a column list,
because this type of query simply
tests to see if a row exists and does
not return any data
Nesting Subqueries

•  A subquery may contain another


•  In fact you can nest as many levels

as you need. However, for most
applications more than four levels is
an indication of poor database

select au_lname,au_fname from authors where

au_id in (select au_id from titleauthors where
title_id in (select title_id from titles where
type = 'popular_comp'))

•  This will return the list of authors who

have written at least one popular
computing book
Unit 4 Review

•  A relationships are connections between

•  A primary key is that set of columns that
define a unique row
•  You can have only one primary key per table
•  A foreign key is one or more columns that
refer to a primary key of the same or another
•  You can have up to 255 foreign keys per
•  A composite key consists of more than one
•  Joins are used when you need to retrieve
data from more than one table
•  The two kinds of joins are: equijoin and outer
•  An outer join comes in three flavors: left,
right, full
•  A full outer join will produce the cross
product of the two tables
•  Subqueries are nested SQL statements
Unit 4 Review

•  Subqueries come in two kinds: correlated

and noncorrelated
•  Subqueries are also of three different types:
return exactly one item, return zero or more
items, and test for existence
•  Most joins can be written as a subquery and
vice versa
•  A subquery is used when you need to
include an aggregate in the where conditions
•  A join is used when you want to retrieve data
from more than one table
•  All means every value (> all means greater
than every value)
•  Any means at least one value (> any means
greater than at least one value)
•  Exists allows us to test to see if a value
•  Exists queries are used with correlated
•  Subqueries can be nested any number of
Unit 4 Exercises

•  Time allotted for exercises is 1 hour

Introduction To SQL
Unit 5 To TSQL
Unit 5

Modern Business
Developed by
Michael Hotek
Naming Tables

•  Up to 30 characters
•  No blanks
•  Underscore is permitted
•  Must be unique within the database
•  Keep abbreviations to a minimum
•  Names should reflect the contents of
the table
Naming Columns

•  Up to 30 characters
•  No blanks
•  Underscore is permitted
•  Must be unique within the table
•  Keep abbreviations to a minimum
•  Names should reflect the contents of
the column
•  Names should be readily
Datatype Considerations

•  Determine what type of data will be

•  Find the range of possible values
•  Determine the accuracy of numeric
•  Efficiency
•  Utilize user defined datatypes to
enforce consistency

•  Exact Numeric
–  Stores data with a specific accuracy
•  Approximate numeric
–  Stores data with accuracy dependent
upon calculations performed
•  Money
–  Monetary data
•  Date and time
–  Storage of dates and times
•  Character
–  Alphanumeric data
•  Binary
–  Images, byte and bit values
Exact Numeric

•  tinyint
–  Whole numbers between 0 and 255
–  1 byte of storage
•  smallint
–  Whole numbers between -32678 and
–  2 bytes of storage
•  numeric(p,s)
–  Decimals between -1038 and 1038-1
–  2 to 17 bytes
•  decimal(p,s)
–  Decimals between -1038 and 1038-1
–  2 to 17 bytes
•  s = number of digits to the right of the
•  p = total number of digits
Approximate Numeric

•  Float(p)
–  Floating point numbers
–  4 or 8 bytes of storage
•  double precision
–  floating point numbers
–  8 bytes of storage
•  real
–  floating point numbers
–  4 bytes of storage
•  During arithmetic operations, the
number of digits to the right of a
decimal point will round based upon
the values in the calculation
•  Float allows you to specific the
precision, but not the location of the
significant digits in relation to the
decimal point

•  money
–  -922,337,203,685,477.5808 to
–  8 bytes of storage
•  smallmoney
–  -214,748.3648 to 214,748.3647
–  4 bytes of storage
•  Accurate up to 4 decimal places, but
are rounded to 2 places when

•  datetime
–  1/1/1753 to 1/31/9999
–  8 bytes of storage
•  smalldatetime
–  1/1/1900 to 6/6/2079
–  4 bytes of storage
•  There is no separate datatype for just
•  Time is stored along with a date with
an accuracy of 1/300th of a second
•  Due to the limitation on the range of
data, a smalldatetime should no
longer be used.
•  Dates and times can be entered into
these columns using a wide variety
of date and time formats
•  The default display type is
determined from the default
language for the server

•  char(n) and nchar(n)

–  Fixed length alphanumeric data
–  n bytes of storage
•  varchar(n) and nvarchar(n)
–  Variable length alphanumeric data
–  actual length of data
•  text
–  Unbounded alphanumeric data
–  16 bytes for an address + multiples of 2K
•  Char datatypes provide a small
performance benefit over varchar.
•  If the data size is predictable or 8
characters or less, use a char
•  nchar and nvarchar are used to store
multi-byte characters such as
Chinese and Japanese

•  Bit
–  0 or 1
–  1 byte of storage
•  binary(n)
–  up to 255 bytes
–  n bytes of storage
•  varbinary
–  up to 255 bytes
–  actual length of data
•  image
–  up to 231-1 bytes
–  16 bytes address + multiples of 2K bytes
of storage
Unbound Data

•  The text and image datatypes are

used to store large amounts of data
•  Text is used for alphanumeric data
•  Image is used for binary data
•  It is highly recommended that you
avoid this two datatypes if at all
–  They can cause a serious performance
problem as well as a space problem.
–  Support for them is very limited
(specialized functions are required to
manipulate them)
–  No application tool can handle binary
data streaming directly from a database
User Defined Datatypes

•  SQL Server gives you the ability to

create your own datatypes
–  Enforces consistency among columns
–  Gives a single point to bind a common
rule or default
•  Consists of a name, system
datatype, and nullability
Creating UDDTs

•  You add new types with sp_addtype

exec sp_addtype empid, int not null

•  This says to create a new type called

empid that is based upon an integer
and can not be null

exec sp_addtype tid, char(6), not null

•  This is a new type called tid that can

contain up to 6 characters and can
not be null
•  Use sp_droptype and sp_help type to
drop and return information about
user datatypes

•  An identity is a special column

–  Assigned a sequential numeric value for
each row that is inserted
–  They can be of integer or numeric
datatypes, but are only whole numbers
–  They can not be null
–  There can only be one identity column
per table
–  Can not be updated
–  Data can be explicitly inserted into them
using set identity_insert <table> on
•  This should only be done in rare
–  Normally start at 1, but a seed value can
be defined for them
–  This is normally a sequential number, but
you should not count on this
Creating Tables

CREATE TABLE [database.

({col_name column_properties
[constraint [constraint
[...constraint]]] | [[,]
constraint]} [[,] {next_col_name
| next_constraint}...])

•  Maximum number of columns per

table is 250
•  Maximum row size is 1962 bytes
•  To get information about a table use
sp_help <table_name>
Create Table Example

CREATE TABLE dbo.authors

(au_id id NOT NULL,
au_lname char(40) NOT NULL,
au_fname char(20) NOT NULL,
phone char(12) NULL,
address varchar(40) NULL,
city varchar(20) NULL,
state char(2) NULL,
zip char(5) NULL,
contract bit NOT NULL)
Unit 5 Review

•  Table names can be up to 30 characters

long and must be unique within a database
•  Column names can be up to 30 characters
and must be unique within a table
•  Types of data are: exact numeric,
approximate numeric, money, date time,
character, and binary
•  Use unbound datatypes only when strictly
•  User defined datatypes can be created from
system datatypes using sp_addtype
•  An identity is a special property for a column
that automatically provides a value for new
•  You can create and remove tables using the
create table and drop table commands
•  You can only have 250 columns in a table
•  The maximum size of a row is 1962 bytes
Unit 5 Exercises

•  Time allotted for exercises is 30

Introduction To SQL
Unit 6

Modern Business
Developed by
Michael Hotek
Temporary Tables

•  Temp tables are used to hold

intermediate result sets for further
•  These are used when you need to
perform a process that can not be
done in a single SQL statement
•  They come in two different types
•  local
–  accessible only to that connection
–  preceeded by a # ex: #authors
–  dropped when the session disconnects
•  global
–  accessible to all connections
–  must be explicitly dropped
–  preceeded by ## ex: ##authors
•  Names can only be 13 characters
Temporary Tables

•  Temp tables can be a powerful

addition to your code
•  They should be minimized at all
•  Many people overuse temp tables
–  Poor database design
–  Lack of SQL knowledge
–  Lazy
•  Temp tables can impose a significant
drain on system resources
Select Into

•  Select into can be used to create a

new table based upon a select
•  Creates the table to match the
structure of the select list
•  Adds any data from the select
•  The database option select into/
bulkcopy needs to be turned on
SELECT [ALL | DISTINCT] select_list
[INTO [new_table_name]]
[FROM {table_name | view_name}
[[, {table_name2 |
[..., {table_name16 |
[WHERE clause]
[GROUP BY clause]
[HAVING clause]
[ORDER BY clause]
Select Into

•  To create an empty table, include a

where clause that will always be

select * into temptitles from

where 1 = 2

•  It is highly recommended to do this

and then insert the data into the table
in a separate operation

•  Rules, defaults, constraints, indexes,

triggers, etc. are not associated with
the new table

•  Views are nothing more than a name

for a select statement that is stored
in the database
–  Behave exactly like a table
–  Do not store any data
–  May include more than one table
–  Simplify and/or customize data
–  Provides independence from the
database schema
–  Provides security
•  The main factor in using security
should usually be security

CREATE VIEW [owner.]view_name

[(column_name [,
AS select_statement [WITH CHECK

•  Always explicitly specify the columns

that will be included
•  With encryption means that the
definition of the view is encrypted
when it is stored
With Check Option

•  The with check option restricts the

data that can be inserted and
updated through a view
•  Leaving this out, allows inserts and
updates to the underlying data that
might not show up in the view due to
the where clause
•  When this is included, the insert and
update must conform to the where
clause of the view

•  Another view can be included in the

definition of a view, but only 16
tables/views can be emcompassed
•  Clauses not allowed
–  order by
–  compute/compute by
–  select into
•  Updates can be performed through a
view as long as only one table at a
time is updated
•  Updates can not be performed is a
distinct, group by, or aggregate is
included in the view
Unit 6 Review

•  Temporary tables can be created to hold

intermediate result sets
•  Temp tables are either local or global
•  Select into can be used to create either a
permanent or temporary table
•  Views can be defined to provide alternate
access to data
•  Views primary consideration should be
Unit 6 Exercises

•  Time allotted for exercises is 30

Introduction To SQL
Unit 7 To TSQL
Unit 7

Modern Business
Developed by
Michael Hotek

•  Integrity is the process by which data

is validated and consistency is
•  Databases were designed with
integrity as a primary factor
•  Integrity can be enforced by a variety
of means
–  Rules
–  Defaults
–  Constraints
–  Primary keys
–  Foreign keys
–  Unique indexes
–  Triggers
•  Integrity can also be programmatic or
Declarative Integrity

•  Defaults and constraints can be used

directly in a create table statement,
hence declarative integrity
•  Constraints include
–  Check
–  Unique
–  Primary Key
–  Reference
•  Constraints can be column or table
•  Defaults are only column level

•  A default clause is used to supply a

value for a column when one is not
explicitly specified in an insert
•  For a DEFAULT constraint:
[CONSTRAINT constraint_name]
{constant_expression | niladic-
function | NULL}
[FOR col_name]

create table address

(CompID int not null,
Address varchar(50) not null,
City varchar(30)
default 'Chicago',
State char(2) default 'IL')

•  Functions can also be used in place

of constants as long as they return a
single value
•  The value of the default must match
the datatype of the column
•  Character and date values must be
enclosed in quotes
•  A column can have only one default
•  sp_helpconstraint can be used to
return constraint information about a
Check Constraints

•  Check constraints are used to

enforce domain integrity
•  Can be applied at a table and a
column level
•  Constraints are used to specify:
–  List or set of values
–  range of values
–  Format for data
–  Conditions on a value
•  Enforced during inserts and updates
•  Must evaluate to a true or false
Column Constraints

create table people

(SSN char(11) not null
constraint chk_ssn
check (SSN like '[0-9][0-9]
FirstName varchar(30) not null,
LastName varchar(50) not null,
create table people
(SSN char(11) not null
check (SSN like '[0-9][0-9]
FirstName varchar(30) not null,
LastName varchar(50) not null,
Table Constraints

•  Used for more than one column

create table discounts
(Type varchar(40) not null,
StoreID char(4) not null,
LowQty int not null,
HighQty int not null,
Discount float null,
constraint chk_low_high
check (LowQty <= HighQty))

•  Separate structure attached to a

•  Contain pointers to the physical data
•  Used to increase performance when:
–  Finding rows
–  Correlating data across tables
–  Ordering result sets
–  Inserting data in some cases
•  Can enforce unique values in a
column or table


INDEX index_name
ON [[database.]owner.]table_name
(column_name [, column_name]...)
[ON segment_name]

•  Data is stored in SQL Server is a set

of structures called pages
•  Each page is 2K in size (8K in 7.0)
•  Many rows can be on a single page
•  A single row must be contained
entirely on a page
•  Each page contains a header area
that identifies the contents of each
•  Pages are stored in a doubly linked

•  As data gets added, a large number

of pages are created
•  Indexes were devised to quickly
navigate these pages
•  Indexes are also stored in pages
•  The index pages are stored in a B-
Tree to support quick location of

Index Pages Data Pages


267-41-2394 267-41-2394...
409-56-7008 341-53-8472...

177-32-1176 402-31-7808...


756-30-7391 532-86-9471...
899-46-2035 655-27-5281...


•  There are two types of indexes

–  clustered
–  nonclusterd
•  Only be 1 clustered index per table
•  Up to 249 nonclustered indexes
•  Order of data in the table is
determined by the type of index
–  clustered index
•  Data in the same order as the index
–  nonclustered index
•  Data in the order it was inserted
Keys and Indexes

•  Keys:
•  Logical
–  Primary, foreign, and common
•  Physical
–  Single column or composite
–  This is an index
•  Indexes are not necessarily logical
•  Indexes can be applied to columns
that are not keys
•  Can contain up to 16 columns
•  Can have a maximum size of 256
Clustered Index

•  Only one per table

•  This is your most powerful index
•  Physically orders the data in a table
•  Can be equated to the old card
•  Good for range searches
•  Slow for inserts
–  page splitting
Clustered Indexes

Data Pages
Page 1132
Key ptr Bennet
Page 1007 Chan
Bennet 1132 Dull
Greane 1133 Edwards
Hunter 1127
Key ptr
Page 1001
Bennet 1007 Page 1133
Karsen 1009 Greane
Smith 1062 Green

Key ptr
Page 1009
Karsen 1315 Page 11127

Root Page Intermediate Leaf Level

Clustered Indexes

•  The leaf level of the index is the data

page of the table
•  Only one entry can point to a page in
the next level
•  Require an additional 120% of space
during creation
Nonclustered Indexes

•  Data is stored in a random order at

the data page level
•  Up to 249 nonclustered indexes can
be defined per table
•  Good for searches of explicit values
•  Are much larger than a clustered
Nonclustered Indexes

Key Page 1241
ptr 10 O'Leary
Page 1132 11 Ringer
Row Page Bennet 1421,1 12 White
Key Chan 1129,3 13 Jenkins
ptr ptr Dull 1409,1
Page 1007 Edwards 1018,5
Bennet 1421,1 1132
Greane 1242,4 1133
Hunter 1242,1 1127 Page 1242
14 Hunter
Row Page 15 Smith
Key ptr ptr 16 Ringer
Page 1001 Page 1133 17 Greane
Bennet 1421,1 1007 Greane 1242,4
Karsen 1876,1 1305 Green 1409,2
Smith 1242,1 1062 Greene 1421,2
Page 1305 Page 1421
Karsen 1876,1 1311 18 Bennet
19 Greene
20 Ringer
Page 1127
Hunter 1242,1
Jenkins 1241,4

Page 1409
21 Dull
22 Green
23 White

Root Page Intermediate Leaf Pages Data Pages

Nonclustered Indexes

•  The root and intermediate levels

work similarly for both clustered and
nonclustered indexes
•  The leaf level of a nonclustered index
contains a pointer to the row on each
data page
•  The pointers at the leaf level are in
index order
Unique Constraint

•  Ensures no two rows have the same

•  Allows one null value in a column
•  Creates a unique, nonclustered index
by default

create table publishers

(pub_id char(4) null,
constraint u_pub_id unique,
pub_name varchar(30) not null)
Primary Key

•  Ensures no two rows have the same

•  Nulls are not allowed
•  Creates a unique, clustered index by

create table publishers

(pub_id char(4)
constraint publishers_PK primary
pub_name varchar(30))

create table sales

(stor_id char(4) not null,
ord_num varchar(20) not null,
date datetime nit null,
constraint sales_PK primary key
nonclustered (stor_id, ord_num))
Referential Integrity

•  Used to maintain foreign keys when

data is inserted or updated
•  Column
create table <table name>
(column datatype
[constraint constraint_name]
references ref_table [ref_column]
•  Table
[constraint constraint_name]
foreign key (column [{,column}…])
references ref_table
[(column [{, column}…])]
Referential Integrity

•  Use a column level constraint when

only one column needs to be
•  Use a table level constraint when
more than one column needs to be
•  The table in the references clause
must already have a primary/unique
constraint or a unique index defined
on the columns
•  A roll back is issued if referential
integrity is violated and a message is
sent back
Referential Integrity

•  Column Level
create table titles
(title_id tid not null,
title varchar(80) null,
pub_id char(4) null
constraint publishers_pub_id
references publishers(pub_id),
notes varchar(200) null)
•  Restrictions
Referential Integrity

create table salesdetail

(stor_id char(4) not null,
ord_num varchar(20) not null,
title_id tid not null,
qty int not null,
discount float not null,
constraint salesdetail_FK1
foreign key (stor_id, ord_num)
references sales(stor_id, ord_num),

constraint salesdetail_FK2
foreign key (title_id)
references titles(title_id))
Referential Integrity

•  When primary keys are deleted and

updated, three different option could
be performed:
–  Restrict
–  Cascade
–  Set null
•  Declarative RI enforces a restrict
•  Cascade and set null can only be
accomplished with triggers
•  In a perfect world, updates to a
primary key are not allowed
•  In an imperfect world, these should
be kept to a minimum
Error Messages

•  Custom messages can be added

with sp_addmessage
•  Drop a message with
•  Get a message with sp_getmessage
•  In Sybase, these messages can be
bound to a constraint so that on a
failure, a nice message to returned to
the user
•  Bind messages using sp_bindmsg
•  Unbind messages using
Alter Table

•  Once a table is created, certain

modifications to its structure can be
•  Allowed:
–  Add columns
–  Add, drop, or change constraints
•  Not allowed
–  Dropping columns
–  Changing datatypes
–  Changing width of columns
–  Changing nullability options
•  Constraints can only be modified with
an alter table statement
•  Modifications to constraints do not
affect existing data
Alter Table

ALTER TABLE [database.

| [[,] table_constraint]}
[, {next_col_name |
constraint_name [,
Getting Help

•  To obtain information about

constraints and defaults defined for a
table use
sp_helpconstraint table
Unit 7 Review

•  Constraints are used to enforce integrity

•  A default will supply a value during an insert
•  Check constraints enforce valid data during
inserts and updates
•  Data is stored in data pages that are 2K in size
•  A table can have 1 clustered index
–  Physically orders the data
–  Leaf level of index is the data pages
–  Used for range searches
•  A table can have up to 249 nonclusterd indexes
–  Does not order the data
–  The leaf level of the index contains pointers to
–  Used for explicit searches
•  Indexes can have up to 16 columns
•  Can be a maximum of 256 bytes
•  Unique constraint creates a unique, nonclustered
index by default and allows one null
•  Primary key constraint creates a unique,
clustered index by default and doe not allow nulls
Unit 7 Review

•  Foreign keys are enforced via a references

•  Referenced column(s) must have a primary/
unique constraint or a unique index defined
•  Roll back is performed if RI is violated
•  The only type of RI that can be applied when
modifying a primary key with constraints is restrict
•  You can add custom messages
•  Alter table can add columns
•  Alter can add, drop, or modify constraints
•  You can not drop a column
•  You can not change a datatype
•  You can not change the length of a column
•  You can not change the nullability
Unit 7 Exercises

•  Time allotted for exercises is 30

Introduction To SQL
Unit 8

Modern Business
Developed by
Michael Hotek

•  A default can exist as a separate

•  A default still follows the same rules
as a default constraint, but gives the
flexibility of reuse
create default default_name as
•  Once a default is created, it can be
bound to multiple columns using

create default D_city as 'Chicago'

exec sp_bindefault D_city,
exec sp_bindefault D_city,

•  To unbind a default, use

•  To drop a default, use drop default
•  A default must be unbound from all
columns before it can be dropped

•  A rule is the same as a check

constraint, except it exists as an
independent object
•  Just like a default object, this gives
the flexibility to use the rule in many
•  The name of the varibale used inside
a rule is arbitrary and can not be
directly accessed

create rule rule_name as


create rule R_state as

@state in ('IL', 'MI', 'MA')

create rule R_salary as

@salary < 1000000

create rule R_state as @state in ('IL',

'MI', 'MA')
exec sp_bindrule R_state,authors.state
exec sp_bindrule R_state,employee.state

•  To unbind a rule, use sp_unbindrule

•  To drop a rule, use drop rule
•  A rule must be unbound from all
columns before it can be dropped
•  Only one rule can be active on a
column at a time
•  The last rule bound to a column is
the one in effect
•  If the column also has a check
constriant, then the only acceptable
values are those that match both
User Datatypes

•  The true power of rules, defaults, and

user datatypes comes when they are
•  A rule and a default can be bound
directly to a user datatype.
•  Since the datatype can be used in
many columns, this allows you to
enforce a rule or default from a single
location with a single command
•  Any changes to the rule or default
are automatically reflected in all
columns where that datatype is used
•  A rule or default bound directly to a
column override the rule or default
bound to a column

•  During an insert, a default is checked

first and then any rule
•  During an update, the rule is checked
•  A rule or default bound directly to a
column overrides the rule or default
bound to the user datatype
•  The last rule or default bound is the
only one that is effective
•  If a rule is bound to a column that
has a check constraint, the only
allowed values are those that meet
both the rule and constraint

•  Just like every other object in the

database, information concerning a
rule or default can be obtained from
the system procedure sp_helptext

sp_helptext object_name
Unique Index

•  Unique indexes are used to enforce

uniqueness within a column or group
of columns
•  A unique index is created in three
–  Primary key constraint is defined
–  Unique constraint is defined
–  A unique index is explicitly created
•  When the index is created, the data
is checked for uniqueness. If
duplicates are present, the creation
of the index fails
•  The index is then enforced on all
subsequent inserts and updates
Implementing RI

•  Which method to choose?

Unit 8 Review

•  Defaults can be created as separate objects

•  sp_bindefault binds a default to a column or
•  Rules can also be created as separate objects
•  sp_bindrule binds a rule to a column or datatype
•  Rules and defaults promote reusablity
•  They can be combined with user datatypes for
increased power and flexibility
•  The last rule or default bound to a datatype takes
•  A rule or default bound directly to a column
overrides a rule or default bound to the column's
•  A unique index is used to enforce uniqueness
within a column or group of columns
Unit 8 Exercises

•  Time allotted for exercises is 30

Introduction To TSQL
Unit 9
Unit 9

Modern Business
Developed by
Michael Hotek
Data Manipulation

•  Up until this point we have covered

numerous ways to get data out of

•  But, this is only a quarter of the basic

SQL picture

•  We must have also have a way to

add new data to a table, modify
existing data, and delete data

•  To accomplish this, we will use the

insert, update, and delete statements

•  These statements are also referred

to as DML, data manipulation

•  Partial syntax:
insert [into] table_name [(column_list)] {values
(expression [,expression]…}| {select

•  The insert statement is used to add

data to a table

•  It has two clauses, insert and values

with an optional columns clause

•  The insert specifies which table the

data is added to and the values
clause specifies what that data is

insert into authors

values('409-56-7008', 'Bennet', 'Abraham',
'415 658-9932', '6223 Bateman St.', 'Berkeley',
'CA', '94705')

•  Any character or date data must be

enclosed within single quotes

•  If you are specifying a numeric or

monetary amount, do not enclose
these in quotes

•  If you do not have a value for a

particular column, specify the
keyword null

•  Because the previous statement

does not have a column_list, the data
is inserted into the table in the order
of the columns

•  For example the result of this

statement would be a new row in the
table that had the following:
au_id = 409-56-7008
au_lname = Bennet
au_fname = Abraham
phone = 415 658-9932
address = 6223 Bateman St.
city = Berkeley
state = CA
zip = 94705

•  If you did not have a value for the

address, the insert statement would
be as follows:
insert into authors
values ('409-56-7008', 'Bennet', 'Abraham',
'415 658-9932',null, 'Berkeley', 'CA', '94705')

•  The word into is optional, but it is

recommended for clarity

•  You do not always have to insert data

in the exact order of the columns in
the table, but you must then specify
the column list

insert into authors (au_lname,city,state,au_id,

values('Bennet', 'Berkeley', 'CA',
'409-56-7008', 'Abraham', '94705',
'6223 Bateman St.','415 658-9932',)

•  This will produce the set result as the

previous insert statement

•  You also must use a column list if

you do not specify all of the values

•  In the authors table, au_id,

au_lname, and au_fname are the
only columns that require a value
(not null)

•  We could also write:

insert into authors (au_id,au_lname, au_fname)

values ('409-56-7008', 'Bennet', 'Abraham')

•  Finally, the values clause can be

replaced by a select statement

•  The way this works is that the first

column of the result set from the
select statement is placed in the first
column of the column list in the insert

•  The second to the second, etc.

insert into authors (au_id,au_lname, au_fname)

select ID,LastName,FirstName from

•  You can also do this same type of

insert without specifying a column list

•  The result set from the select

statement must match the table you
are inserting into in the number of
columns, and datatype of columns

•  The column names do not have to


insert into authors select * from authors_tmp


•  The select statement that you use for

inserting data can be of any variety

•  You can use a subquery(s), group by,

order by, where, having, multiple
tables, etc.

•  You can not use a compute or

compute by

update table_name set column_name1 =

{expression1/null | (select statement)}
[,column_name2 = {expression2/null | (select
from table_name [where search_conditions]

•  An update statement is used to

modify existing data in a table

•  If you wanted to give a 10% discount

on all titles:

update titles set price = price * .9


•  You use the where clause to restrict

which rows are updated

•  If you only wanted to discount those

books published before 1/1/87:

update titles set price = price * .9

where pubdate < '1/1/87'

•  You can also change multiple

columns at the same time

update authors set city = 'Oakland West', zip =

'94611' where city = 'Oakland' and address
like '%College%'

•  There is a special type of column in

some DBMSs called an identity,
autoincrement, sequence, etc. This
is beyond the scope of this class, but
it is important to know you can not
update these columns

update titles_ident set title_id = 200 where

title_id = 1 will return an error

•  When you need to restrict the update

to a set of rows that are based upon
more than one table, you must use
the from clause

•  We want to discount only those

books that are from publishers in CA

update titles set price = price * .9 from titles t,

publishers p where t.pub_id = p.pub_id and
p.state = 'CA'

•  Finally to delete data from a table,

we use a delete statement

delete table_name [from table_name,

table_name…] [where search_conditions]

•  If you do not specify any search

conditions, you will delete all rows
from the specified table

delete authors

•  To restrict the rows you delete use a

where clause

delete from authors where state = 'CA'

•  To delete rows where the criteria is

based on multiple tables, use the
from clause

delete titles from titles t, publishers p where

t.pub_id = p.pub_id and p.state = 'CA'
Transaction Logs

•  The full discussion of transaction

logs is beyond the scope of this class

•  Every change to data (insert, update,

and delete) is logged to a special file
called a transaction log.

•  This is why insert, update, and delete

are referred to as logged operations

•  You can also delete all of the data in

a table without using a delete.

•  This is accomplished via a truncate


•  truncate table table_name

truncate table authors

is the same as
delete authors
as far as the effect on the authors table

•  The difference is in how these two

commands are handled

•  Delete is a logged operation

•  Truncate is a nonlogged operation

•  This becomes important in

recovering a server from a crash

•  Generally you should not use a

truncate command

•  In some client sites, this is a

command that is reserved for the
DBA (database administrator)

•  The truncate will perform faster,

because it does not write to the
transaction log, but this command
should be avoided at all costs by
anyone other than a DBA

•  It is included here for completeness

Unit 9 Review

•  An insert statement allows you to add data

to a table
•  The insert can contain a list of columns
•  An insert can also obtain it's values from
another table
•  An update statement is used to change
existing data
•  An update can not be performed on an
identity/autoincrement/sequence column
•  A delete will delete data from a table
•  Insert, update, and delete part of the DML
(Data Manipulation Language)
•  Insert, update, and delete are logged
•  Truncate will also remove all data from a
table, but should be avoided at all costs
Unit 9 Exercises

•  Time allotted for exercises is 1/2 hour

Introduction To TSQL
Introduction To SQL
Unit 10
Unit 10

Modern Business
Developed by
Michael Hotek

•  In addition to the standard SQL

statements, SQL Server and most
other DBMSs include a set of
functions to perform additional

•  The functions fit into 6 categories

–  string
–  conversion
–  date
–  mathematical
–  aggregate
–  general

•  To determine which functions are

available for your particular DBMS,
you should consult the online help for
your DBMS

•  Overview of Books Online

String Functions

•  The string functions we will discuss

–  substring
–  right
–  upper
–  lower
–  charindex
–  patindex
–  ascii
–  char
–  ltrim
–  rtrim
–  space
–  str
–  soundex
–  replicate
String Functions

•  Substring gives you the ability to

extract a portion of a string from a
another string or piece of data

•  Right returns the right portion of a

String Functions

•  Upper converts a string to upper


•  Lower converts a string to lower case

String Functions

•  charindex returns the starting

position of a string the specify

•  patindex performs the same

operation as charindex, but can also
include wildcard characters and can
be used on text columns
String Functions

•  ascii converts a character to it's

equivalent ASCII value

•  char takes an ascii value and returns

the corresponding character
String Functions

•  ltrim and rtrim remove leading or

trailing spaces. ltrim from the left
and rtrim from the right
ltrim(' abcde')

rtrim('abcde ')

ltrim(rtrim(' abcde '))

String Functions

•  Space constructs a string of the

number of spaces specifiied
2 spaces

•  Str will convert a number to a string

and round it off to the specified
number of decimal places
String Functions

•  soundex converts a character

expression to a four character code.
This is used to find similar words. It
ignores any vowels
soundex('smith'), soundex('smythe')

•  replicate creates a string composed

of the number of copies of a string
that you specify
Converting Data

•  Some data within SQL Server is

implicitly converted

•  A money datatype will convert to a

real or a float without any

•  Sometimes though, we want a

number to be treated as a character
or vice versa

•  To do this we need to use the convert


•  The string function str gave us a

quick way to convert a number to a

•  The convert function gives us much

more control over the exact datatype
the data is converted to.

•  convert(datatype,expression [,style])

select title_id, 'The number of books

sold: ' +
convert(varchar(10),ytd_sales) from
titles where title_id like 'PS20%'
-------- ------------------------------------
PS2091 The number of books sold: 2045

(1 row(s) affected)

•  By using the third optional argument

of the convert function, you can
utilize some formatting while
converting data.

•  This argument is used when

converting a date to a string

select convert(varchar(8),pubdate,2)
from titles where title_id = 'MC3026'

Date Conversion

•  Some of the most commonly used

values are as follows:
–  2
–  3 dd/mm/yy
–  4
–  5 dd-mm-yy
–  102
–  103 dd/mm/yyyy
–  104
–  105 dd-mm-yyyy

•  Consult your online manual for other

Date Conversion

•  A datetime value can be directly

compared to a string datatype that
has a datetime value, because the
string can be implicitly converted

select title_id from titles where pubdate

= '6/30/86'


•  The built in function getdate() will

return the current date and time from
OS where the DBMS resides
Date Functions

•  Sometimes we only want a portion of

a date or we want to do date

•  To do this we will use the following

–  datename
–  datepart
–  dateadd
–  datediff
Date Functions

•  datename will return the name of a

specified part of a date

•  The parameter values are as follows:

–  yy year
–  qq quarter
–  mm month
–  dw day of week
–  dy day of year
–  dd day
–  wk week
Date Functions

•  datepart will return the numeric part

of a date

•  dateadd adds or subtracts a

specified amount of time to a date

•  To subtract from a date, specify a

negative value:
Date Functions

•  datediff is used to calculate the

difference between two dates of

•  Available paramters for datediff are:

–  yy year
–  qq quarted
–  mm month
–  dw day of week
–  dd day
–  wk week
–  hh hour
Year 2000

•  SQL Server is year 2000 compliant

•  It accomplishes this by utilizing a

comparison technique

•  If you enter a two digit year less than

50, SQL Server assume 20xx.

•  If the two digit year is greater than or

equal to 50, SQL Server will assume

•  If you send it a four digit year, it

stores the entire year in the database
thus avoiding any confusion.
Mathematical Functions

•  Mathematical functions allow to you

manipulate and do calculations on
numeric data. The functions we will
examine are:
–  abs
–  ceiling
–  floor
–  round
–  exp
–  rand
–  log
–  pi
–  power
–  sqrt
–  sin
–  cos
–  tan
Mathematical Functions

•  abs returns the absolute value of a

–  abs(number)
–  abs(-59)
–  Result
–  59

•  round returns a value rounded off to

the number of digits specified
–  round(number,digits)
–  round(123.4567,2)
–  Result
–  123.4600
•  You can round down by specifying a
negative value
•  The result is padded with zeros to
keep the total number of digits the
Mathematical Functions

•  ceiling returns the next highest

integer value
–  ceiling(number)
–  ceiling(123.4)
–  Results
–  124

•  floor returns the next lowest integer

–  floor(number)
–  floor(123.4)
–  Results
–  123
Mathematical Functions

•  exp raises the constant e to the

specified power

•  log returns the natural logarithm of

the specified number
Mathematical Functions

•  rand returns will generate a set of

pseudo-random numbers

•  The rand function is seeded at server

startup by the DBMS and uses the
system clock as part of the seed

•  You can ensure a repeatable

sequence by using the same seed
value and making sure that only one
person accesses the rand function
while the repeatable sequence is
Mathematical Functions

•  pi returns the mathematical constant

–  pi()
–  Results
–  3.1415926…

•  power raises a number to a specified

–  power(number,power)
–  power(10,3)
–  Results
–  1000

•  sqrt returns the square root of a

–  sqrt(number)
–  sqrt(100)
–  Results
–  10
Mathematical Functions

•  sin, cos, and tan return the sine,

cosine, and tangent of an angle

•  The angle is measured in radians

and not degrees

sin( )

•  You can also use the degrees and

radians functions to convert values
from one to another
Aggregate Functions

•  We've already touched on most of

the aggregate functions previously,
but a brief overview follows

count(*) number of selected rows

count(column) number of non null rows
sum(column) total of all values in a column
avg(column) average of aq column
max(column) maximum value in a column
min(column) minimum value in a column

•  The isnull function can be used to

avoid some of the side effects of null

•  This function substitute a specified

value for a null

select title_id, isnull(notes, 'No notes for
title') from titles
BU1032 An overview of available database systems with ...
BU1111 Helpful hints on how to use your electronic resources to ...
BU2075 The latest medical and psychological techniques for living...
BU7832 Annotated analysis of what computers can do for you: ...
MC2222 Favorite recipes for quick, easy, and elegant meals.
MC3021 Traditional French gourmet recipes adapted for modern...
MC3026 No notes for title
(18 row(s) affected)
Unit 10 Review

•  The functions fit into 6 categories

–  string
–  conversion
–  date
–  mathematical
–  aggregate
–  general
•  You can convert data from one data type to
•  Most of the functions you will use are the
standard aggregates of count(*), sum, min,
and max
•  Isnull allows a graceful way of handling nulls
Unit 10 Exercises

•  There are no exercises for this unit

Introduction To TSQL
Introduction To SQL
Unit 11 Unit 11

Modern Business
Developed by
Michael Hotek

•  Most SQL statements have the ability

to be run as batches

•  A batch is nothing more than a group

of SQL statements executed at the
same time

•  The batch is submitted and

processed by the server

•  If there is an error in any statement in

the batch, the entire batch is rejected

select title from titles

select au_lname from authors
select stor_name from stores
The Busy Executive's Database Guide
Cooking with Computers: Surreptitious Balance Sheets
You Can Combat Computer Stress!
Straight Talk About Computers
Silicon Valley Gastronomic Treats
The Gourmet Microwave
The Psychology of Computer Cooking
But Is It User Friendly?
(18 row(s) affected)

(23 row(s) affected)

Eric the Read Books
(6 row(s) affected)
Batch Restrictions

•  Some SQL statements can not be

combined with others in a batch
–  use
–  create rule
–  create default
–  create trigger
–  declare cursor

•  An object can not be dropped and

recreated in the same batch

•  Stored procedures in a batch must

be preceded by an exec or execute
unless they are the first statement

•  You can add comments to any of

your SQL batches to improve
readability and also to document the

•  The are two ways to comment in

SQL Server: /*…*/ and --

/* The comments included between

these delimiters can span multiple

--The double hyphen must precede

--line of your comment

•  All pieces of data in a database have

a specific datatype

•  Each column is defined as being of a

specific datatype

•  This means that if a column is

defined an integer datatype, you will
not be able to enter alphabetic
characters into it

•  The common datatypes in SQL

Server, and most DBMSs, are:
–  char fixed width alphanumeric data
–  varchar variable width alphanumeric data
–  integer whole number values
–  datetime Date and time values

•  The main difference in char and

varchar columns is in the amount of
storage space they require

•  A varchar is also not space padded

Refer to the data model

•  Variables in SQL can have one of

two scopes, local or global

•  All of the variables you will create will

be local in scope

•  Global variables are reserved for use

by SQL Server and can not be
assigned values by the user
Local Variables

•  Local variables are:

–  User defined
–  Created using declare
–  Have a name and datatype
–  Can be assigned values by the user
–  Are initialize to null when created
–  Are confined to the batch, stored
procedure, or trigger they are declared in

declare @variable_name datatype

declare @mmyvar char(10)
Local Variables

•  Variable names must be preceded by

an @ symbol, can be up to 30
characters in length, and can not be
reserved words

•  To assign values to a variable, use a

select @variable = expression [,@variable
= expression]…

declare @myvar int

select @myvar = 42
Local Variables

•  You can assign constants, values

from a table, or an expression to a

•  Variables are scalar; they contain

exactly one value

•  They can only be used in place of


•  They can not be used in place of

table names, column names, or other
database objects
Local Variables

•  If no values are returned by the

assignment select, the variable
remains unchanged

•  If more than one value is returned by

the assignment select, the last value
is stored in the variable

•  An assignment select does not return

any data to the user

•  To return the value of a variable to a

user, use a select on the variable
Local Variables

declare @myvar int

select @myvar = 42
select @myvar

declare @sales money

select @sales = price*ytd_sales from titles
where title_id = 'BU1032'
select @sales

(1 row(s) affected)


(1 row(s) affected)
Local Variables

declare @myvar int --@myvar is null

select @myvar = 1 --@myvar is 1
select @myvar = ytd_sales from titles where
title_id = '99999'
--row does not exists
--@myvar is still 1
select @myvar = ytd_sales from titles where
title_id = 'BU1032'
--row does exist
select @myvar
(1 row(s) affected)

(0 row(s) affected)

(1 row(s) affected)


(1 row(s) affected)
Local Variables

•  Local variables are used for a variety

of things in SQL Server
–  Perform conditional branching based on
a variable's value
–  Pass values to and from stored
–  Eliminate the need to use subqueries for
–  Reuse of constants throughout a batch
–  Return custom messages to the user
Common Errors

declare @myvar int

select @myvar = 'This is an error'

•  This results in an error, because the

datatypes do not match. The DBMS
will first try to implicitly convert the

•  This can result in other types of

–  Rounding errors
•  Assigning a money datatype to an integer
removes the cents
–  Insufficient space
•  Assigning a 30 character string to a
variable defined as char(10)

•  Select more than one value into a

Global Variables

•  Global variables are defined and

managed by the server

•  They can not be assigned values by

the user

•  Are preceded by an @@

Global Variables

•  @@error - contains the error number

generated by the last statement
–  Assigned by connection

•  @@identity - contains the last

identity value used
–  Assigned by connection

•  @@rowcount - contains the number

of rows affected by the last statement
–  Assigned by connection

•  Variables assigned by connection

mean that each connection has it's
own copy of the variable. Changes
to the variable for one connection do
not affect any others
Global Variables

•  @@version - Contains the SQL

Server version number
–  Assigned by server

•  @@max_connections - contains the

maximum number of user
connections allowed
–  Assigned by the server

•  @@servername - contains the name

of the SQL Server
–  Assigned by the server

•  Assigned by the server means that

there is one copy of this variable for
access by all connections
Global Variables

•  The two most common global

variables you will use extensively are
@@error and @@rowcount

•  @@error will be used in much of

your error checking to branch to
appropriate error handling

•  @@rowcount will be used to verify

the number of rows affected by an
operation. It will also be used to
determine if you need to step through
a result set via a cursor
Control Of Flow

•  No language would be complete

without the ability to branch to other
parts of code or perform many
iterations of a task

•  SQL accomplishes this through a

small set of constructs

Control Of Flow

•  if…else allows you to conditionally

execute a statement

•  begin…end groups statements into a


•  while loops through a set of


•  return exits a batch

•  waitfor executes based on an event

•  goto branches to a user defined label


if boolean_expression
[else [if boolean_expression]

•  A boolean expression evaluates to

either true or false

•  You can include a select statement in

the boolean expression, but it must
return only one value and the select
must be enclosed in parenthesis

declare @myvar money

select @myvar = avg(price) from titles

if @myvar < 15
update titles set price = price * 2
update titles set price = price * 1.1

•  You can only nest up to 150 levels


•  An if statement will execute the only

next statement

•  Consider the following:

declare @myvar money
select @myvar = avg(price) from titles
if @myvar < 15
update titles set price = price * 2
select @myvar = avg(price) from titles

•  The second statement will execute

every time through the batch. It is
not dependent on the if statement

•  What happens if we want to execute

more than one statement following a
conditional test?

•  To overcome this, the begin…end

construct is used

•  The begin…end allows two or more

statements to follow an if and be
executed as a group

statement block

declare @myvar money

select @myvar = avg(price) from titles

if @myvar < 15
update titles set price = price * 2
print "Prices doubled"
update titles set price = price * 1.1
print "Prices increased by 10%"
If [not] exists

•  Using exists and not exists are useful

when you are only concerned
whether data exists

declare @name varchar(30)

select @name = 'Smith'
if exists (select * from authors where au_lname
= @name)
select "There is a match"
select "There is no match"

•  An if exists query stops processing

as soon as it finds a match. Because
of this, it is very useful for enforcing
referential integrity

•  Return is used to exit a batch, trigger,

or stored procedure unconditionally

•  Any statements following the return

are not executed

if not exists (select 1 from titles where title_id =

print "No such title"
insert into salesdetail...

•  While is used to execute a

statement(s) repeatedly

while boolean_expression
statement block to execute as long
as the condition is true

while (select avg(price) from titles) < 40

update titles set price = price + 2
select avg(price) from titles

•  You can control the statements in a

while loop via break or continue

•  break exits the loop, but not the


•  continue restarts processing at the

beginning of the loop

while (select avg(price) from titles) > 20

update titles set price = price - 2
if (select max(price) from titles) < 40
if (select avg(price) from titles) > 20

•  A case statement is a more compact

way of expressing nested if…else
SELECT Category =
CASE type
WHEN 'popular_comp' THEN 'Popular Computing'
WHEN 'mod_cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad_cook' THEN 'Traditional Cooking'
ELSE 'Not yet categorized'
"Shortened Title" = CONVERT(varchar(30), title), Price = price
FROM titles
COMPUTE AVG(price) BY type
Case - Results

Category Shortened Title Price

------------------- ------------------------------
Business The Busy Executive's Database 19.99
Business Cooking with Computers: Surrep 11.95
Business You Can Combat Computer Stress 2.99
Business Straight Talk About Computers 19.99


Category Shortened Title Price

------------------- ------------------------------
Modern Cooking Silicon Valley Gastronomic Tre 19.99
Modern Cooking The Gourmet Microwave 2.99


Category Shortened Title Price

------------------- ------------------------------
Popular Computing But Is It User Friendly? 22.95
Popular Computing Secrets of Silicon Valley 20.00

(21 row(s) affected)

•  goto will branch to a user defined


…if @@error != 0
select @errno = 30000
select @errmsg = 'Some error message'
goto error
/* Errors handling */
raiserror @errno @errmsg
rollback transaction

•  waitfor allows execution to be

delayed until an event occuurs

•  waitfor {delay time | time time…}

–  delay suspends execution until a
specified time has elapsed (up to 24
–  time suspends execution until a specified
time of day (you can not specify a date)

--endless loop that records number of locks

--every half hour
while 2 > 1
waitfor delay '0:30:00' --30 minutes
insert into num_procs
select getdate(), count(*) from master..syslocks
•  waitfor is superceded by tasks in MS SQL Server
Unit 11 Review

•  Batches consist of more than one SQL statement

•  You can add comments two ways: /*…*/ or --…
•  Datatypes define what types of data can be
contained within a column
•  Variables can be either global or local
•  Global variables can be accessed but not written
to by the user and are preceeded by an @@
•  Local variables are created and managed by the
user and are preceeded by an @
•  A select is used to assign a value to a local
•  Control of flow in batches can be accomplished
via 7 main constructs
–  if…else
–  begin…end
–  while...
–  goto
–  case
–  return
–  waitfor
Unit 11 Exercises

•  There are no exercises for this unit

Introduction To TSQL
Introduction To Unit
SQL 12
Unit 12

Modern Business
Developed by
Michael Hotek
Transaction Management

•  Most of the following discussion of

transaction management is specific
to Sybase SQL Server and MS SQL

•  But, the principles can be applied to

virtually any DBMS

•  Transactions by definition are a

logical unit of work

•  A logical unit of work is a SQL

operation or a set of SQL statements
executed against a database
–  Usually include at least one DML
–  Changes the database from one
consistent state to another

•  A transaction can have two outcomes

–  When it completes successfully, it is
"committed" or "saved"
–  When a transaction fails, it is "rolled
back" or "undone"

•  Another definition is a single

recoverable unit of work that
executes either:
–  Completely
–  Not at all

•  A transaction can be anything from a

single DML command to a series of
commands (multiple inserts or

•  After a transaction is committed, it

can not be undone

•  When a transaction is rolled back, all

modifications of the transaction are

•  Partial execution of a transaction is

not allowed

•  delete authors can only have two

possible outcomes:
–  All rows are deleted (committed) or
–  None of the rows are deleted (rolled
Need for Transactions

•  Transactions are the result of

business rules being applied to the
database world

•  These rules state that an operation

either completes successfully or
none of the operations can be

•  In the following scenario, we will

consider a bank teller machine
Need for Transactions

•  The business function we are trying

to apply is the transfer of funds from
a savings to a checking account

•  The amount debited from the savings

account must be added to the
checking account

•  Both the debit and the credit must

occur or neither must occur
Need for Transactions

•  Here are the possible problems in

transferring $1000
–  Partial transfer
•  Money is debited, but not credited
–  Another operation against your account
could conflict with the transfer

–  Another operation could see invalid data

•  The debit does not work, but the money is
credited. A check for an amount greater
than should be in the checking account is
processed and approved
–  Another operation could see data at the
wrong time

•  Transaction management is
implemented to cover the following
–  Protect data from software, hardware, or
power failure
–  Provide access to multiple user
–  Prevent simultaneous read and write of
the same data by multiple users

•  Transaction control is implemented

via three methods
–  Locking
–  Transaction control statements
–  Error management
Data Storage

•  How data is physically stored by

SQL Server is beyond the scope of
this class

•  However, there is one principle that

must be understood in order to
continue with the next topic

•  A table's data is stored in a series of

pages called data pages

•  SQL Server handles this page

allocation internally and also "knows"
where to find the particular data via a
set of internal structures

•  Locking is automagically handled by

SQL Server via a process called the
Lock Manager

•  As reads or writes are performed on

a data page, the lock manager
places a lock on that page

•  This ensures that simultaneous

transactions do not interfere with
each other

•  Without this locking, you may get

data inconsistency in a multi-user

•  The locking mechanism also reduces

availability of data

•  All locking decisions are handled by

SQL Server

•  There are two levels of locking

–  page and table

•  Page locks are less restrictive than

table locks, because the lock is
placed only on a single page and
therefore on a small subset of data

•  Page locks are used whenever

Table Locks

•  A table lock is the most restrictive


•  As it's name implies, it is a lock that

covers the entire table

•  A table lock is implemented via a

means called escalation

•  If a user is going to access an entire

–  an update with no where clause
•  SQL Server will escalate the page
lock to a table lock

•  Once a SQL statement accumulates

200 page locks, it is escalated to a
table lock

•  Obviously there can only be one

table lock

•  So, it would seem that you want to

avoid this if at all possible

•  The type of lock acquired is generally

not a concern as SQL Server tries to
maintain the most appropriate lock
for the least duration of time

•  The granularity of a lock refers to the

amount of data that can be locked at
one time. This can range from a
single page to an entire database

•  By increasing the lock granularity, the

processing required to obtain a lock
decreases. But this also degrades

•  As lock granularity decreases, the

amount of processing required to
maintain and coordinate the locks
Types of Page Locks

•  There are three types of locks

–  Shared
•  Multiple transactions can lock a shared
•  No transactions can change the page
•  Usually released as soon as the page is
–  Exclusive
•  Only one transaction can lock a page
•  Other transactions must wait until the lock
is released
•  Exists for the duration of the transaction
–  Update
•  Allows reads, but will not allow shared or
exclusive locks
•  Becomes an exclusive lock when the
page is ready to be modified
•  Is an internal lock to help avoid deadlocks
•  Exists for the duration of the transaction
Lock Interactions

Can another process:

Command Lock Select Modify
select title_id from titles shared yes no

delete titles exclusive no no

where price > 25

insert into titles values (…) exclusive no no

update titles set type= update, yes no

'general' where type = then exclusive no

•  Locking is affected by:

–  Indexes
–  Transactions
–  Isolation Levels
–  Table and page level locking
Isolation Levels

•  The ANSI standard defines four level

of isolation for transactions
–  Level 0 allows dirty reads (You can see
data that has been changed, but not
necessarily committed, by another user
–  Level 1 prevents dirty reads
–  Level 2 prevents non-repeatable reads
–  Level 3 prevents phantom reads

•  The higher the isolation level, the

higher the consistency

•  The higher the isolation level, the

lower the concurrency
Isolation Levels

•  All higher levels include all of the

restrictions of the lower levels

•  Level 0
–  No shared locks for reads or exclusive
locks on pages or tables being changed.
An update still acquires a shared lock for
its read
•  Level 1
–  Exclusive lock on objects being changed.
Hold lock until end of transaction
–  Shared locks on pages being searched.
Release locks after object is processed.
Isolation Levels

•  Level 2
–  Exclusive lock on pages being changed.
Hold lock until end of transaction
–  Shared lock on pages being searched.
Remove lock after processing object
•  Level 3
–  Exclusive lock on pages being changed
–  Shared lock on pages/tables being
–  Hold all locks until end of transaction
(accumulate locks)

•  The default isolation level for SQL

Server is 1
•  The default isolation level for the
ANSI-92 standard is 3
•  The current isolation level can be
gotten from @@isolation

•  noldlock/noholdlock is an option for a

select statement that overrides the
isolation level set for the duration of
the select statement

•  Holdlock
–  Enforces isolation level 3
–  Makes a shared lock more restrictive, by
causing the server to hold all shared
locks until the transaction is complete
–  Applies a shared pages lock if the search
argument references indexed columns,
otherwise it applies a table lock
–  Use only if strictly necessary

•  Use the noholdlock option only if you

want SQL Server to release any
shared locks regardless of isolation

begin tran
declare @avg_adv money
select @avg_adv = avg(advance) from
titles holdlock where type = 'business'

if @avg_adv > 5000

select title from titles where type =
'business' and advance > @avg>adv
commit tran

Since the average must remain

constant for the duration of the
transaction, holdlock will prevent
anyone from writing to the titles table
until the transaction is complete

•  A deadlock can occur when two

processes hold locks on a page on
which the other process holds a
conflicting lock

•  SQL Server detects this and aborts

one of the transactions

•  SQL Server will detect a deadlock

and chooses the user with the least
amount of CPU time as the "victim"

•  Even the "winner" will see a

significant decrease in performance

•  Application need to program for the

possibility of a deadlock (error 1205
in Sybase SQL Server)

•  If a deadlock occurs, the application

should resubmit the transaction
Avoiding Deadlocks

•  To minimize the possibility of a

–  Have all transaction access the tables in
the same order
–  Use holdlock only when repeatable reads
are necessary
–  Avoid long running transactions; make
transactions small and commit as soon
as possible
–  Avoid user input while you have a
holdlock on a table
–  Avoid numerous simultaneous
executions of DML commands like insert,
update, delete
Avoiding Deadlocks

•  The best way to avoid deadlocks is

to write transaction in the same
order. Avoid the following:
begin tran begin tran
update table A update table B
update table B update table A
commit tran commit tran

•  Wherever possible try to use stored

procedures to perform transactions
to ensure consistent access order to
Transaction Control

•  Provides the control required for

managing transaction

•  Enables the grouping of SQL

commands in a transaction that meet
business requirements

•  Enables a programmer to influence

SQL Server's locking strategy

•  Creates predictable effects when

committing or rolling back

•  begin transaction and commit

transaction mark the beginning and
end of a transaction
Transaction Control

•  There are three transaction control

–  begin tran
•  Alerts SQL Server that a transaction is
beginning. You can optionally name a
–  rollback tran
•  Undoes the changes either to the named
savepoint or the beginning of the
transaction. Execution continues with the
next statement
–  commit tran
•  End the transaction and saves changes to
the database

•  Before a commit is issued, a

transaction can be either partially
rolled back to a savepoint or
completely rolled back

•  After a commit is issued, a

transaction can not be rolled back

•  In unchained mode, you can set up

savepoints in a transaction

•  These serve as an intermediate point

in a transaction

•  There could be cases where you

want to only rollback a portion of the
work you have done.

•  save {transaction | tran }


•  To undo all statements or procedures

between a savepoint and the rollback

•  rollback {transaction | tran | work}


•  Always name savepoints

•  After a rollback, execution continues

with the statement immediately
following the rollback
Savepoint Example

A bank can charge a fee for every use

of an ATM. The specific transaction
might fail, but the charge still needs
to be applied

begin tran
update service_charge set service_charge =
service_charge + .50 where account_num =
save tran service_charge
update savings set balance = balance - 500 where
account_num = '99999'
if @@transtate = 2
select @@error
rollback tran service_charge
Error Processing

•  You can monitor a transaction

through two global variables:
–  @@error detects errors during/after
statements execute
–  @@transtate monitors the current state
of the transaction

Value Meaning
0 transaction in progress
1 transaction committed
2 previous statement aborted and
transaction still in progress
3 transaction aborted/statement rolled back

•  @@transtate is reset after insert,

update, delete
Error Handling

•  Failure with a rollback (@@transtate = 3)

–  Errors of severity level 19 or higher are fatal
and will immediately abort the transaction and
roll back all statements to the beginning of the
•  Failure with continue (@@transtate = 2)
–  Errors from a failed statement cause the
statement to fail, but other statements are
•  No error, completed (@@transtate = 1)
–  Transaction finished and saved all its changes
•  No error, in progress (@@transtate = 0)
Error Handling

•  @@transtate is not always set to 2

or 3 when a statement fails

•  Insert into a null into a column that

does not allow nulls
–  An error is reported for each attempt
–  All rows that contain valid data will be
–  The error is found in @@error
–  There is no indication in @@transtate
•  @@error should be used exclusively
–  Maintain atomicity of transactions
•  If any commands fail, undo all changes
•  Abort the transaction using a return
•  Ensure each batch contains only one
transaction so you can predict what is
rolled back on an abort
Error Handling

•  If you are using insert statements in

a transaction, you should always
check @@error

begin tran
insert …
if @@error != 0
rollback tran

commit tran

•  @@rowcount will tell you how many

rows were affected by a statement
–  An insert, update, or delete may affect
more than one row
–  A select into a variable may not return
any rows which could cause invalid
results later in the transaction
•  If you expect rows and @@rowcount
–  Issue a rollback tran
–  Issue a return to abort the transaction
Reporting Errors

•  If an error occurs, we want to return

a user friendly message of what

•  This is accomplished by using


•  Develop a numbering system for

error messages
–  20001 - 21000 = update errors
–  21001 - 22000 = insert errors...

•  Standardize you error output

•  Add a new error message with

Report Errors Example

exec sp_addmessage 40000, "An error occurred

while updating '%1!' table with a publisher ID of
declare @error int,
@rows int
begin tran
update publishers set pub_id = 'a' where
pub_id = '0736'
select @error = @@error, @rows = @@rowcount
if @error != 0
rollback tran
raiserror 40000,'publishers','0736'
commit tran
Msg 40000, Level 16, State 1:
An error occurred while updating publishers table
with publisher ID of 0736.
Unit 12 Review

•  A transaction is a logical unit of work

•  Transactions can be committed or rolled back
•  Once a transaction is committed it can not be
rolled back
•  Pages are locked as they are accessed. A large
number of page locks will escalate into a table
•  There are four isolation levels which can be used
to control the locking in the database
•  Use the holdlock/noholdlock to override an
isolation level setting
•  Deadlocks occur when two transaction are trying
to obtain a lock on a page where the other has a
conflicting lock
•  Deadlocks need to be avoided at all costs
•  There are three transaction control statements:
begin tran, commit tran, rollback tran
•  There are two transaction modes: chained and
•  Savepoints can be implemented to preserve
some of the work done in the event of an error
•  @@error detects errors during or after statement
Unit 12 Review

•  @@transtate is used to check the state of a

transaction - It has four values
•  @@rowcount stores the number of rows affected
by a given statement
•  Raiserror is used to return an error message back
to an application
Unit 12 Exercises

•  Time allotted for exercises is 1/2 hour

Introduction To TSQL
Introduction To Unit
SQL 13
Unit 13

Modern Business
Developed by
Michael Hotek

•  A cursor is a name that is associated

with a select statement

•  SQL is a set oriented language which

means that an operation is
performed on all rows that meet a

•  Sometimes, due to business rules,

you must process a result set one
row at a time

•  A cursor gives you this ability


•  Cursor consist of two parts

–  cursor result set - result set of the
associated select statement
–  cursor position - a pointer to the current
row in the result set

•  A cursor allows a program to perform

an action row by row on a result set
instead of on the entire result set

•  Provides the ability to delete or

update a row based on cursor

•  Bridges the set orientation of an

RDBMS and row oriented

•  There are four types of cursors

–  Language - declared in a batch
–  Server - declared in a stored procedure
–  Client - declared in an open client app
–  Execute - declared in an open client app

•  Cursors are handled by SQL Server

differently based on the type of

•  To the user, the effect of a cursor is

the same regardless of type

•  There are five steps to using a cursor

–  Declare the cursor for the select
statement you are using
–  Open the cursor
–  Fetch each row into the cursor, repeating
until the entire result set has been
–  Close the cursor
–  Deallocate the cursor to free up system

•  The last step is generally forgotten

by most developers. Make sure you
deallocate any cursors when you
have finished with them.

•  A cursor is one of the most

expensive operation that can be
performed in terms of resource

•  If a cursor is not deallocated, all of

the resources that it used are still
taken and are not available to any
other processes
Declaring Cursors

declare cursor_name cursor for

select_statement [for {read only | update [of

declare mycursor cursor for

select * from titles
for read only

•  The declare cursor can be the only

statement in a batch

•  The cursor can have two modes

–  read only
–  for update
Declaring Cursors

•  The cursor name must be a valid


•  The select statement can consist of

any number of clauses

•  The select
–  Must contain a from clause
–  Can not contain a compute, for browse,
or into
–  The column_list is the list of columns
defined as updateable
Declaring Cursors

•  A cursor that is in read only mode

does not allow deletes or updates

•  For update is the default mode, but

you should always explicitly state
what mode the cursor is for

•  Regardless of mode, the cursor will

be placed in read only mde if the
select statement contains
–  distinct
–  group by
–  aggregate functions
–  unions
Opening Cursors

•  After declaring a cursor, the next step

is to open the cursor

•  Opening the cursor causes the select

statement to be executed, make the
result set available for processing,
and positions the cursor pointer to
the first row

declare mycursor cursor for

select * from titles
for read only

open mycursor
Fetching Rows

•  Once the cursor is opened, you are

ready to begin fetching rows

declare mycursor cursor for

select * from titles
for read only
open mycursor
fetch mycursor

•  The cursor determines which row

can be updated or deleted based on
the cursor position
Fetching Rows

•  When you fetch rows, there are two

global variables that are important
–  @@rowcount
–  @@fetch_status (MS SQL Server)
–  @@sqlstatus (Sybase)

•  As you fetch rows, the value in

@@rowcount increases
Fetching Rows

•  @@sqlstatus can have three values

–  0 successful fetch
–  1 error in fetch
–  2 no more to fetch

•  @@fetch_status can also have three

–  0 successful fetch
–  -1 error in fetch or no more rows
–  -2 fetched row doesn't exist
Fetching Rows

•  To add to the flexibility, you can fetch

the data into variables

fetch cursor_name [into fetch_list]

•  The list of variables must match the

column list in the select statement

declare @title_name varchar(80)

declare mycursor cursor for select title from
titles for read only
open mycursor
fetch mycursor into @title_name
Close and Deallocate

•  When you are done with the cursor,

close and deallocate it

close cursor_name
deallocate cursor_name

declare mycursor cursor for select title from

titles for read only
declare @title_name varchar(80)
open mycursor
fetch mycursor into @title_name
close mycursor
deallocate mycursor
Close and Deallocate

•  SQL Server will close a cursor when

–  exit the session
–  return from a stored procedure that
declared the cursor

•  Do not rely on this to clean up your


•  You can reopen a cursor after it has

been closed without declaring it
again only if you do not deallocate it

open mycursor...
close mycursor
open mycursor…
close mycursor
deallocate mycursor

--The below code will display business books at an 8% increase

declare @title_id char(6),

@type char(12),
@price money

--Declare cursor and perform initial fetch

declare curbooks cursor for select title_id, title, price from titles where type =
‘mod_cook’ for read only

open curbooks
fetch curbooks into @title_id, @type, @price

--Loop through all of the rows

while @@fetch_status = 0
select @title_id, @type, convert(money,@price*1.08)

--Subsequent fetches
fetch curbooks into @title_id, @type, @price

close curbooks
deallocate curbooks

--The code below is equivalent to the cursor

select title_id, type, convert(money, price*1.08)
from titles
where type = ‘mod_cook’
Data Modification

•  You can delete a row based on the

cursor position

•  Declare the cursor for update

declare mycursor … for update

open mycursor
fetch mycursor
delete … where current of mycursor
Data Modification

•  For data modification based on

cursor position, the table requires a
unique index

•  Even if a cursor is declared for

update, you can not delete a row if
the cursor's select statement
contains a join clause or references a
multi-table view
Data Modification

•  You can also update data based on

cursor position

declare mycursor … for update

open mycursor
fetch mycursor
update … where current of mycursor
Data Modification

•  An update does not move the cursor


•  The same row can be updated more

than once until the next fetch is

•  You can update a multi-table view or

joined tables only if the update is
being performed on one table

•  Always specify for read only or for


•  Do not leave cursors open for a long


•  If the same operation is performed

on every row in the result set, do not
use a cursor

•  Always close and deallocate your

Unit 13 Review

•  Cursor allow you to perform an operation one row

at a time
•  Cursors can have two modes:
–  for read only
–  for update
•  The steps to using a cursor are:
–  declare
–  open
–  fetch
–  close
–  deallocate
•  @@rowcount and @@sqlstatus or
@@fetch_status will give you information about
your fetch operations
•  For more flexibility, you can fetch data into
•  You can delete or update data by using the where
current of cursor_name clause
•  Always close and deallocate your cursors
Unit 13 Exercises

•  Time allotted for exercises is 1/2 hour

Introduction To TSQL
Introduction To SQL
Unit 14

Modern Business
Developed by
Michael Hotek

•  Previously we can discussed batches

of SQL statements

•  A brief review:
–  A batch is one or more SQL statements
–  If one statement in a batch is invalid, the
entire batch is rejected
–  An object can not be created, dropped,
and recreated in a batch
Stored Procedures

•  So, what does this have to do with

stored procedures

•  A stored procedure is a batch of

SQL statements

•  The only difference is that a batch is

compiled at the time of execution and
a stored procedure is already
Stored Procedures

•  A stored procedure is a collection of

SQL statements that are stored
under a name and executed

•  Allow many users to execute the

same code

•  Provide a centralized and consistent

implementation of code

•  Commonly used by
–  Frequently used queries
–  Business logic
–  Error handling routines
–  Repetitive administrative functions
Steps to Execution

•  When a SQL statement is executed,

many things happen on the server
–  Parsing - the statement is parsed into a
format SQL Server can handle for
efficient operation
–  Syntax checking - During the parsing
stage, the SQL is also checked for any
syntax errors
–  Resolution - all objects are resolved to
their internal representations (IDs)
–  Compile - The statement is compiled into
machine language the server can
–  Query plan - A plan for executing the
query is determined for the fastest
access to data

•  All of this happens rather quickly on

the server and is required for every
statement you execute
Stored Procedures

•  When you create a stored procedure

all of the steps of parsing, checking,
compiling, etc. are carried out

•  When the user executes the stored

procedure none of these steps need
to be performed

•  This is what makes stored

procedures execute more quickly
than batches
Stored Procedures

•  The first time a stored procedure is

executed, a query plan is built and

•  This query plan is determined by any

arguments passed to the proc the
first time and statistics SQL Server

•  After the first execution, the stored

query plan is used an does not need
to be rebuilt

•  A stored procedure is not a shared

object. Each concurrent user
receives their own copy.
–  If two users simultaneously execute a
stored procedure, there will actually be
two copies of the object executing (one
for each user)

•  Execute faster than the same set of

commands run as a batch
–  The code is already compiled
–  No query plan needs to be created
–  The code generally resides in memory
•  Reduce network traffic
–  You are sending an exec proc command
instead if the entire batch of SQL across
the network
•  Enforce consistency
–  Commands are executed the same
–  Error handling is standardized
•  Provide security
–  Users can be given execution permission
on a stored procedure that modifies data
instead of permission to directly modify
the table
•  Modular design

•  To create a stored procedure, you

issue the create procedure command

create procedure proc_name

SQL statement or batch

•  The stored procedure is stored in the

current database, but it can access
objects in other databases

•  The create procedure command can

not be combined with any other
statements in a single batch

•  Manage the source code of your

stored procs the same as you would
any other code in the development

•  Even though the DBMS will return at

the end of a proc, always end a
procedure with the return statement

•  Develop naming, commenting, and

documentation standards for all of
your stored procedures.
–  Makes procedures more readable
–  Simplifies identification of procedures
–  Reduces the administrative overhead
Valid Statements

•  Just about any SQL statement can

be included in a stored procedure
–  create view
–  create rule
–  create default
–  create procedure
–  create trigger
–  use

•  Not being able to issue a use can be

at times be limiting, so be careful to
plan where the stored procedures
are located

•  One little known fact for SQL Server

(Sybase and MS) is that any
procedure named sp_… is treated as
a system stored procedure and can
be executed with a database
different than the one created in

•  You can cause the stored procedure

to execute in the context of another
database simply be preceding it with
a database name
(exec pubs..sp_test)

•  To execute a stored procedure, the

user issues an execute proc

execute proc_name or exec proc_name

•  You can leave off the exec if the

statement is the first statement in a
batch, but this is very poor

•  Procedures can be called from:

–  Batches
–  Other stored procedures
–  Triggers
–  Other programs
Stored Procedures

•  To view the source code for a stored

procedure, you would use the
sp_helptext (or the equivalent) stored
–  exec sp_helptext myproc

•  You can rename a procedure with

–  exec sp_rename myproc sp_myproc

•  To delete (drop) a procedure, issue

the drop procedure command
–  drop procedure myproc
–  You must drop a procedure before you
create one with the same name
–  When you change the source code for
the procedure
Input Parameters

•  Stored procedures can accept input

parameters. (Most procs are
constructed this way.)

•  An input parameter is nothing more

than a variable that is supplied a
value when the user executes the

•  The input parameter(s) are defined

within the stored procedure

•  This increases the flexibility of the

Input Parameters

create procedure proc_name

(@parameter datatype
[,@parameter datatype…])
SQL batch

--Single input parameter

create procedure myproc
(@name vahrchar(40))
select * from authors where au_lname =

exec myproc ‘Smith’

Input Parameters

•  Parameter names can be up to 30

characters including the @

•  There can be up to 255 parameters

in a procedure

•  A value passed to a procedure can

contain a wildcard character as long
as the parameter is used in a like

•  An object name can not be passed

as a parameter
Executing Procedures

•  A procedure with parameters can be

executed two ways:
–  by name
–  by position

•  When a proc is executed by name,

the input parameter is explicitly
–  exec myproc @name = ‘Smith’
•  When called by position, the
arguments are in the order the
parameters were defined
–  exec myproc ‘Smith’

•  You will very rarely execute a

procedure by name. But, executing
by name is more self-documenting
Multiple Parameters

•  You can define more than one

parameter for a stored procedure

create proc myproc

(@var1 int, @var2 int, @var3 char(2))
Default Value

•  You do not have to always pass the

same number of arguments that
have been defined in the procedure

•  To allow this, input parameters can

be defined with default values

create procedure proc_name

(@parameter datatype = default
[,@parameter datatype = default…])
SQL batch
Default Values

•  When executing a procedure, you

must pass values for all parameters
that do not have defaults assigned to

•  If a parameter is optional, or is
usually assigned a particular value,
assign a default to that parameter
Common Errors

•  Values are not compatible with the

defined datatype

•  Parameters are passed via mixed

methods; some by name, some by

•  One or more parameters is missing

•  Parameters are passed in the wrong

Stored Procedures

•  Sometimes we need to return values

from a stored procedure

•  This is accomplished with output

–  This is not supported in all DBMSs

create procedure proc_name

(@parameter datatype = default
[,@parameter datatype = default…]
[,@parameter datatype output…])
Error Handling

•  You should always implement error

handling in your stored procedures

•  This includes the use of

–  raiserror
–  transactions
–  return status

•  To debug your stored procedures,

make use of the print statement to
inform you of states of variables and
execution branches

•  Just make sure to remove these

before the procedure goes into
Output Values

create procedure myproc

(@book_id char(6),
@total_sales int output)
select @total_sales = sum(qty)
from salesdetail
where title_id = @book_id

declare @total int

exec myproc 'PS2091' @total output
select @total

Return Status

•  Every procedure will return a status

–  0 for successful completion
–  -1 to -99 for errors

•  Use a return statement to specify a

return value
–  return 10

•  The return statement does not

accept a variable. (This is what the
output parameter is for.)

•  When returning values from your

procedure do not use one of the
reserved numbers from SQL Server

•  Add comments to document


•  Establish standards to promote


•  Suggestions
–  Break large single statements across
multiple lines
–  Create a common header for all procs
•  Purpose
•  Return values/data
•  How to use
•  Description of each parameter and
•  Modification history
•  Author, mod date, and creation date
–  I generally don't identify the author, but
this is preference

•  Suggestions con't:
–  Include all comments after the as
•  Any comments included before the as
statement will not get included
–  Do all variable declarations and
assignment selects in a block

•  Example
•  (Can be found at
Transaction Control

•  Establish a transaction mode

(chained or unchained) for your
application -- Sybase only

•  Establish a consistent error handling

strategy for any failed transaction

•  Implement standard procedure

templates and transaction control in
nested stored procedures to maintain

•  @@trancount contains the nesting

level of transaction

•  Each begin tran increments the


•  Each commit decrements the


•  Rollback resets @@trancount to 0

begin tran --@@trancount = 1

begin tran --@@trancount = 2
begin tran --@@trancount = 3
commit --@@trancount = 2
rollback --@@trancount = 0
Nested Procedures

•  You can nest procedures (have one

procedure that calls another) up to
16 levels deep

create proc…
exec proc2...
exec proc3...

•  A stored procedure containing a

transaction can contain another
procedure containing a transaction

•  Use @@trancount to keep track of

the nesting level

•  After a commit or rollback in an inner

nested procedure, will cause
subsequent statements in the outer
batch to execute

•  Keep in mind the effect of commit

and rollback on @@trancount
Nesting and Savepoints

•  Nested transactions that contain

savepoints, if rolled back, will not
cause the outermost transaction to
be rolled back

•  In order to achieve this effect, you

must explicitly name the savepoint

save tran xyz...

rollback tran --Roll back to the savepoint

save tran xyz…

rollback --Rolls back everything
Server Cursors

•  Server cursors are cursors that

execute within a stored procedure

•  They are declared and used exactly

as was explained in the cursors unit

create proc…
declare mycursor for…
open mycursor…
fetch mycursor

close mycursor
deallocate mycursor
Cursor Scope

•  A stored procedure can access the

cursors that are declared outside the
procedure or in other procedures in
the call tree

•  If a proc pA declares a cursor cA and

then calls proc pB, pB can access
cursor cA

•  If pB declares a cursor cA, then the

cursor in pA is no longer available to
pB or any procedures that it calls

•  Add defaults to all input arguments

•  Check for missing arguments and

print a usage statement

•  Check the validity of parameters

•  Include return status for error


•  Print meaningful messages for the


•  Comment your code


•  Some SQL statements can not be


•  Create tables before you refer to


•  A table can not be created, dropped,

and recreated in the same procedure

•  You must drop a procedure before

creating another one of the same

•  Procedures can be nested up to 16

levels deep

•  Stored procedures can reference

objects in another database

•  Temporary tables created in a

procedure are dropped when the
procedure ends

•  Set options in a procedure stay in

effect for the duration of the
procedure and are reset when it ends

•  Stored procedures operate on one or

more objects in a database(s)

•  Use the sp_depends stored

procedure to get a list of objects the
stored procedure references

sp_depends proc_name

•  A query plan is created the first time

a procedure is executed

•  Sometimes, the query plan is out of

date or a different query plan should
be used

•  To cause SQL Server not recreate

the query plan, use the with
recompile option

create proc…
with recompile

•  Use the with recompile only when

there is no way to predict the best
query plan at compile time

•  You can also do this on a one time

basis by specifying the with
recompile in the execute statement

exec myproc with recompile

•  This is generally done to update a

query plan with the statistics now
available to the DBMS
Unit 14 Review

•  A stored procedure is a batch of SQL that is

compiled and stored in a database
•  Some SQL statements can not be used in a
•  A stored procedure can use input parameters to
increase the flexibility of the procedure
•  Input parameters can be created with default
•  Output parameters can be used to return values
•  Every procedure will give a return status
•  Comments should be placed in procedures to
document the code
•  A procedure will take on the current transaction
mode the session is working under
•  Transactions can be nested
•  @@trancount keeps track of the current nesting
–  begin increments
–  commit decrements
–  rollback sets to 0
•  Stored procedures can see cursors declared
within their calling tree
•  Use the with recompile option to recreate a query
Unit 14 Exercises

•  Time allotted for exercises is 1 hour

Introduction To SQL
Unit 15 To TSQL
Unit 15

Modern Business
Developed by
Michael Hotek

•  Triggers are a special type of stored

procedure that go into effect when a
user issues an insert, update, or
delete on a table

•  Executing a trigger is called "firing

the trigger"

•  Triggers are automatically executed

when an insert, update, or delete is

•  Triggers are not directly called or


•  Triggers are used to:

–  Enforce referential integrity
–  Custom business rules
–  Admin functions

•  Cascading updates and deletes can

only be accomplished through a
Referential Integrity (RI)

•  RI is the process whereby

relationships are maintained within
the data

•  A child row without a parent row is

referred to as an orphan

•  RI prevents orphans

•  For example:
•  A title can not exist without an author

•  If the author is deleted, his titles can

not exist in the table

•  Cascading is the process whereby

changes to a parent are propagated
to the child

•  If we update the parent value, we

must also update the child value in
order to maintain the relationship

•  The same is true of deletions


•  There are three different effects for

–  Delete
•  When the parent is deleted, all
corresponding children are also deleted
–  Restrict
•  If a child exists, do not allow the deletion
of the parent
–  Set Null
•  When a parent is deleted set the
corresponding child value to null

•  Update triggers have only two

–  Update
•  When the parent changes, change the
–  Restrict
•  If a child exists, do not allow changes to
the parent
Roles of Triggers

•  Triggers can be a very powerful

addition to any application

•  Triggers are used for the following

additional functions:
–  Maintain duplicate data
•  Used to create an additional copy of the
data for use in another system
–  Maintain derived data
•  Used to maintain aggregated data so that
an application doesn't have to create the
aggregate on the fly
–  Enforce complex restrictions
•  Enforce business rules such as a person
can not have a salary > 1 million dollars
–  Perform custom recording
•  Acts as an additional audit trail
Action of a Trigger

•  When data is inserted, updated, or

deleted from a table the trigger fires

•  The trigger fires after the data is in

the table

•  The trigger is part of the same

transaction as the modification

•  A trigger is fired only once for a

modification statement
–  If you insert 5000 rows in a single
transaction, the trigger will only fire once

•  The trigger can roll back the

transaction or send and error back to
the client (raiserror)
Create a Trigger

create trigger trigger_name on

for {insert | update | delete}
[,{insert | update | delete}]…
SQL statements

•  A table can have up to three triggers:

–  1 for insert
–  1 for update
–  1 for delete

•  Only the table owner can create a


•  Triggers can not be directly called or

take parameters
Create a Trigger

•  The for clause indicates for which

modification statement(s) will fire the

•  Multiple events can be defined for a

single trigger
–  insert and delete
create trigger tiu_sales on sales
for insert, update as ...

•  Conform to a specific naming

convention for triggers:
–  t[i,u,d]_tablename
–  i.e. ti_sales, td_sales, tiu_stores,
tud_authors, tiud_employee
Special Tables

•  Triggers have access to special

temporary tables

•  These tables do not exist and can

not be accessed outside of the
trigger they are created for

•  These tables are

–  inserted
•  Contains any rows added to a table as
the result of an insert or delete
–  deleted
•  Contains any rows removed from a table
as the result of an update or delete
Special Tables

•  The inserted table contains rows

whenever an insert or update is

•  The deleted table contains rows

whenever an update of delete is

•  An update is considered an insert/

delete pair

•  When data is updated, the image of

the data before the row was changed
is placed in the deleted table. The
image of the row after the data is
updated is contained in the inserted
Special Tables

•  Inserted and deleted have the same

structure as the table that is being
inserted into, updated, or deleted
Update Triggers

•  A very important concept to

understand is that an update is
actually an insert/delete pair (in most

•  However, you can not interact with

the insert or the delete portions of an

•  This is all hidden behind the scenes

by SQL Server
Update Triggers

•  So, if I can't interact with the insert or

delete happening for an update, why
should I even know about it?

•  You need to know because of the

effect on the inserted and deleted

•  The before image is stored in the

deleted table

•  The after image is stored inserted

How Triggers Work

•  When you insert, update, or delete

rows from a table that has a trigger, it
is fired
–  It fires whether or not any rows are
–  @@rowcount will tell you how many
rows are effected
–  If you are inserting and a kkey violation
occurs, the trigger will not fire

•  By checking @@rowcount in your

code, you can avoid unnecessary

•  If @@rowcount = 0 exit the trigger

Row Counting

•  The row counts can be used to verify

a dependent table correctly refers to
the parent table

create trigger ti_salesdetails on

salesdetails for insert as
declare @numrows int
--Get the rows effected as this changes
-- every time data is modified
select @numrows = @@rowcount
if (select count(*) from titles t,
inserted i where t.title_id =
i.title_id) != @numrows
Row Counting

•  An alternative method to the …select

count(*)… is to use an exists query

•  An exists query will return a true as

soon as a matching value is found

•  It also alleviates the multirow

Delete Example

Example: Delete Trigger

create trigger td_publishers
on publishers for delete as
--if no rows deleted exit trigger
if @@rowcount = 0
--For deleted publishers, delete corresponding titles
delete titles from titles t, deleted d
where t.pub_id = d.pub_id
--Any additional actions
Insert Example

Example: Insert trigger

create trigger tiu_titleauthor on titleauthor for insert,
update as
--Find number of rows modified
declare @numrows int
select @numrows = @@rowcount
if @numrows = 0
--Make sure all title ids match
if (select count(*) from titles t, inserted i where
t.title_id = i.title_id) != @numrows
raiserror 31113 "Attempt to insert invalid title_id into
rollback transaction
--Make sure all au_ids match
if (select count(*) from authors a, inserted i where
a.au_id = i.au_id) != @numrows
raiserror 31114 "Attempt to insert invalid au_id into
rollback transaction
Update Trigger

•  You can check to see if a column has

been changed by using the if update

•  if update (columnname)
•  [{and | or} update (columnname)]…

•  Returns true if the specified column

has been modified

•  This eliminates unneeded processing

•  If update can only be used in a

Update Example

Example: Update trigger

create trigger tu_publishers on publishers for update as
--Find out how many rows were modified
declare @numrows int
select @numrows = @@rowcount
if @numrows = 0
if update (pub_id) --Was primary key updated
--Multiple updated rows not allowed
if @numrows > 1
raiserror 31113 "Update to primary keys of multiple
rows is not permitted."
rollback transaction
--Cascade update to titles table
update titles set t.pub_id = i.pub_id
from titles t, inserted i, deleted d
where t.pub_id = d.pub_id
Multi-row Operations

•  It is very important to take into

account the possibility of multi-row
insert, update, deletes

•  You can get this information from


•  If @@rowcount is > 1 then you have

multiple rows in the inserted and
deleted tables to be concerned with

•  If a set operation is not possible,

cursors are used to handle the
multiple rows

•  To get the text of a trigger or stored

procedure, use sp_helptext

sp_helptext [proc_name | trigger]

•  To see object dependencies, use


•  sp_depends tablename will show all

of the triggers that reference a given

•  sp_depends triggername will show

all of the tables that are referenced
by a trigger

•  To drop a trigger, use the drop


•  There are two methods of

maintaining referential integrity
–  Triggers
–  Declarative RI

•  The main difference between the two

is that triggers can accomplish
cascading updates and deletes. DRI
is not capable of this
Transaction Control

•  You can not rollback to a named

transaction in a begin tran inside of a
•  A run time error will occur
•  Everything is rolled back and the
trigger and proc are aborted
Transaction Control

•  If you have a nested trigger, the

rollback trigger will roll back all work
done in all of the triggers and also
the DML that fired the first trigger in
the chain

•  Issuing a rollback trigger outside of a

trigger will cause SQL Server to
ignore it

•  A rollback trigger outside of a trigger,

but inside of a transaction will cause
SQL Server to rollback and abort the
Nested Triggers

•  Triggers can be nested up to 16

levels deep

•  The 16 level limit is a combination of

triggers and regular stored procs

•  After 16, the entire transaction is


•  You can disallow nested riggers with

a configuration option
Nested Triggers

•  A trigger will normally not call itself

–  An update is issued which fires and
update trigger on the table. The update
trigger updates the same table. The
second update will not fire the trigger
–  By using set self_recursion (Sybase) or
changing the nested triggers option(MS
SQL Server), you can recursively call a
trigger up to 16 times

•  Parameters can not be passed to a


•  insert, update, and delete statements

inside of a trigger do no affect the
inserted and deleted tables for the

•  Views and temporary tables can not

have triggers

•  You can not create objects in a


•  Do not rollback to a named

transaction in begin tran

•  You can nest or recurse triggers up

to 16 levels deep with the proper

•  Triggers can execute stored procs

•  When you define a new trigger for an

action, the old trigger is overwritten

•  Minimally logged operations such as

truncate table and bcp do not fire

•  To return info to a user from a trigger

use print or raiserror
Unit 15 Review

•  A trigger is a special type of stored procedure that

is executed automatically when a DML statement
is issued
•  Triggers are used to enforce RI, apply custom
business rules, and perform admin functions
•  Every table can have up to three triggers
•  Each trigger has access to it's own special
temporary tables called inserted and deleted
•  An update causes an insert/delete pair to be
•  If update allows you to test if a particular column
has been changed
•  For any type of cascading operations, you must
use a trigger to enforce RI instead of DRI
•  Triggers can be nested up to 16 levels deeo
•  Triggers can also recursively call themselves up
to 16 levels deep
Unit 15 Exercises

•  Time allotted for exercises is 1/2 hour