Sie sind auf Seite 1von 100

Introduction to SQL

Week 1
Database language
1. Allows to create database and table structures to perform basic data management (add,
delete and modif! and to perform comple" #ueries designed to transform raw data into
useful information.
$. %ust perform suc& basic functions wit& minimal user effort and its command structure and
snta" must be eas to learn.
'. It must be portable( t&at is, it must conform to some basic standard so t&at an indi)idual
does not &a)e to relearn t&e basics w&en mo)ing from one *D+%S to anot&er.
SQL functions fit into two broad categories,
It is a data definition language (DDL!, SQL includes commands to create database ob-ects
suc& as tables, inde"es, and )iews, as well as commands to define access rig&ts to t&ose
database ob-ects.
It is a data manipulation language (D%L!, SQL includes commands to insert, update, delete,
and retrie)e data wit&in t&e database tables.
SQL is a nonprocedural language, ou merel command w&at is to be done( ou don.t &a)e to
worr about &ow it is to be done. /&e American 0ational Standards Institute (A0SI! prescribes a
standard SQL1t&e current full appro)ed )ersion is SQL2$33'. /&e A0SI SQL standards are also
accepted b t&e International 4rgani5ation for Standardi5ation (IS4!, a consortium composed of
national standards bodies of more t&an 163 countries. Alt&oug& ad&erence to t&e A0SI7IS4 SQL
standard is usuall re#uired in commercial and go)ernment contract database specifications, man
*D+%S )endors add t&eir own special en&ancements.
Sc&ema is a group of database ob-ects1suc& as tables and inde"es1t&at are related to eac& ot&er.
8suall, t&e sc&ema belongs to a single user or application. A single database can &old multiple
sc&emas belonging to different users or applications. /&ink of a sc&ema as a logical grouping of
database ob-ects, suc& as tables, inde"es, and )iews. Sc&emas are useful in t&at t&e group tables
b owner (or function! and enforce a first le)el of securit b allowing eac& user to see onl t&e
tables t&at belong to t&at user.
/&e Database %odel
A customer ma generate man in)oices. 9ac& in)oice is generated b one customer.
An in)oice contains one or more in)oice lines. 9ac& in)oice line is associated wit& one
in)oice.
9ac& in)oice line references one product. A product ma be found in man in)oice lines. (:ou
can sell more t&an one &ammer to more t&an one customer.!
A )endor ma suppl man products. Some )endors do not (et;! suppl products.(<or
e"ample, a )endor list ma include potential )endors.!
If a product is )endor2supplied, t&at product is supplied b onl a single )endor.
Some products are not supplied b a )endor. (<or e"ample, some products ma be produced
in2&ouse or boug&t on t&e open market.
/&e =90D4* table contains )endors w&o are not referenced in t&e >*4D8?/ table. Database
designers note t&at possibilit b saing t&at >*4D8?/ is optional to =90D4*( a )endor ma
e"ist wit&out a reference to a product.
9"isting =@?4D9 )alues in t&e >*4D8?/ table must (and do! &a)e a matc& in t&e =90D4*
table to ensure referential integrit.
A few products are supplied factor2direct, a few are made in2&ouse, and a few ma &a)e
been boug&t in a ware&ouse sale. In ot&er words, a product is not necessaril supplied b a
)endor. /&erefore, =90D4* is optional to >*4D8?/.
Data /pes
?AA* B <i"ed c&aracter lengt& data, 1 to $66 c&aracters
=A*?AA*B=ariable c&aracter lengt& data,1 to $,333 c&aracters.
08%+9* B 0umeric data. 08%+9*(C,$!is used to specif numbers wit& two decimal places and up
to nine digits long, including t&e decimal places. Some *D+%Ss permit t&e use of a %409: or a
?8**90?: data tpe.
I0/ BInteger )alues onl
S%ALLI0/BSmall integer )alues onl
DA/9 formats )ar. ?ommonl accepted formats are, .DD2%402::::., .DD2%402::., .%%7DD7::::.,
and .%%7DD7::.
?reating tables
?*9A/9 /A+L9 tablename (
column1 data tpe DconstraintED,
column$ data tpe DconstraintEED,
>*I%A*: F9: (column1 D, column$E! ED,
<4*9IG0 F9: (column1 D, column$E! *9<9*90?9S tablenameED,
?40S/*AI0/ constraintE !(
9", (SQL Ser)er!
?*9A/9 /A+L9 tbl@Sample (
S@ID int ID90/I/:(1,1! 04/ 08LL,
S@0A%9 )arc&ar(633!,
S@A%/ mone,
S@80I/ int,
S@>*I?9 decimal(13,H!,
>*I%A*: F9:(S@ID!!(
?onstraints
?onstraints come in )arious fla)ors. /&e following list contains a #uick o)er)iew of eac&
tpe of constraint a)ailable in SQL Ser)er,
>*I%A*: F9:1A column or combination of columns w&ose )alues uni#uel identif
eac& row in t&e table
<4*9IG0 F9:1A column or combination of columns used to establis& and enforce a
link between t&e data in two tables
80IQ8919nsures t&at no duplicate )alues are entered in specific columns t&at do not
participate in a primar ke
?A9?F19nforces domain integrit b limiting t&e )alues t&at are accepted b a
column
D9<A8L/1Defines column )alues stored w&en no )alue &as been assigned
0ullabilit1Designates t&at a column will accept null )alues
9ac& constraint tpe &as an associated /2SQL statement format wit& )arious
implementations.
9" ,
?*9A/9 /A+L9 tbl@Sample (
S@ID int ID90/I/:(1,1! 04/ 08LL,
S@0A%9 )arc&ar(633!,
S@A%/ mone,
S@80I/ int,
S@>*I?9 decimal(13,H!,
?40S/*AI0/ >F@ID >*I%A*: F9:(S@ID!!(
Wit& constraint ,
?*9A/9 /A+L9 tbl@SampleA (
=@ID int ID90/I/:(1,1! 04/ 08LL,
=@0A%9 )arc&ar(633!
>*I%A*: F9:(=@ID!
!(
?*9A/9 /A+L9 tbl@Sample+ (
S@ID int ID90/I/:(1,1! 04/ 08LL,
S@0A%9 )arc&ar(633!,
S@A%/ mone,
S@80I/ int,
S@>*I?9 decimal(13,H!,
=@ID int
?40S/*AI0/ >F@IDA >*I%A*: F9:(S@ID!,
<4*9IG0 F9: (=@ID! *9<9*90?9S tbl@SampleA 40 D9L9/9 ?AS?AD9
!(
In t&is e"ample we &a)e $ tables, tbl@SampleA and tbl@Sample+, notice t&at on tbl@Sample+, we created a
contraint named >F@IDA w&ic& will ser)e as t&e name of our primar ke. We also declared =@ID as our
foreign ke and reference tbl@SampleA. 0otice t&e command 40 D9L9/9 ?AS?AD9; It means t&at if we
delete an )alues from column =@ID of tbl@SampleA, all related c&ild column of =@DI found in tbl@Sample+
&a)ing t&e same )alue will also be deleted.
/&ere is also an option called 40 8>DA/9 ?AS?AD9, w&ere t&e foreign column indicated will be automaticall
updated once t&e column from t&e main table is updated.
SQL Inde"es
inde"es can be used to impro)e t&e efficienc of searc&es and to a)oid duplicate column )alues.In t&e
pre)ious section, ou saw &ow to declare uni#ue inde"es on selected attributes w&en t&e table is created.
In fact, w&en ou declare a primar ke, t&e D+%S automaticall creates a uni#ue inde". 9)en wit& t&is
feature, ou often need additional inde"es. /&e abilit to create inde"es #uickl and efficientl is important.
8sing t&e ?*9A/9 I0D9I command, SQL inde"es can be created on t&e basis of an selected attribute. /&e
snta" is,
?*9A/9D80IQ89E I0D9I inde"name 40 tablename(column1D, column$E!
<or e"ample, based on t&e attribute >@I0DA/9 stored in t&e >*4D8?/ table, t&e following command creates
an inde" named >@I0DA/9I,
?*9A/9 I0D9I >@I0DA/9I 40 >*4D8?/(>@I0DA/9!(
SQL does not let ou write o)er an e"isting inde" wit&out warning ou first, t&us preser)ing t&e
inde" structure wit&in t&e data dictionar. 8sing t&e 80IQ89 inde" #ualifier, ou can e)en create an
inde" t&at pre)ents ou from using a )alue t&at &as been used before. Suc& a feature is especiall
useful w&en t&e inde" attribute is a candidate ke w&ose )alues must not be duplicated,
?*9A/9 80IQ89 I0D9I >@?4D9I 40 >*4D8?/(>@?4D9!(
If ou now tr to enter a duplicate >@?4D9 )alue, SQL produces t&e error message Jduplicate )alue
in inde".K %an *D+%Ss, including Access, automaticall create a uni#ue inde" on t&e >F
attribute(s! w&en ou declare t&e >F. A common practice is to create an inde" on an field t&at is
used as a searc& ke, in comparison operations in a conditional e"pression, or w&en ou want to list
rows in a specific order. <or e"ample, if ou want to create a report of all products b )endor, it
would be useful to create an inde" on t&e =@?4D9 attribute in t&e >*4D8?/ table.
*emember t&at a )endor can suppl man products. /&erefore, ou s&ould not create a 80IQ89
inde" in t&is case. +etter et, to make t&e searc& as efficient as possible, using a composite inde" is
recommended.
Suc& duplication could &a)e been a)oided t&roug& t&e use of a uni#ue composite inde", using t&e
attributes
9%>@08%, /9S/@?4D9, and /9S/@DA/9,
?*9A/9 80IQ89 I0D9I 9%>@/9S/D9I 40 /9S/(9%>@08%, /9S/@?4D9, /9S/@DA/9!(
+ default, all inde"es produce results t&at are listed in ascending order, but ou can create an
inde" t&at ields output in descending order. <or e"ample, if ou routinel print a report t&at lists all
products ordered b price from &ig&est to lowest, ou could create an inde" named >*4D@>*I?9I
b tping,
?*9A/9 I0D9I >*4D@>*I?9I 40 >*4D8?/(>@>*I?9 D9S?!(
/o delete an inde", use t&e D*4> I0D9I command,
D*4> I0D9I inde"name 40 table0ame
<or e"ample, if ou want to eliminate t&e >*4D@>*I?9I inde", tpe,
D*4> I0D9I >*4D@>*I?9I 40 >*4D8?/(
Inserting *ows
SQL re#uires t&e use of t&e I0S9*/ command to enter data into a table./&e I0S9*/ command.s
basic snta" looks like t&is,
I0S9*/ I0/4 tablename =AL89S ()alue1, )alue$, ... , )aluen!
+ecause t&e >*4D8?/ table uses its =@?4D9 to reference t&e =90D4* table.s =@?4D9, an integrit
)iolation will occur if t&ose =90D4* table =@?4D9 )alues don.t et e"ist./&erefore, ou need to
enter t&e =90D4* rows before t&e >*4D8?/ rows. Gi)en t&e =90D4* table structure defined
earlier and t&e sample =90D4* data s&own in, ou would enter t&e first two data rows as follows,
I0S9*/ I0/4 =90D4*
=AL89S ($1$$6,L+rson, Inc.L,LSmit&sonL,LM16L,L$$'2'$'HL,L/0L,L:L!(
I0S9*/ I0/4 =90D4*
=AL89S ($1$$M,LSuperloo, Inc.L,L<lus&ingL,LC3HL,L$162NCC6L,L<LL,L0L!(
Inserting *ows wit& 0ull Attributes
/&us far, ou &a)e entered rows in w&ic& all of t&e attribute )alues are specified.+ut w&at do ou do
if a product does not &a)e a )endor or if ou don.t et know t&e )endor code; In t&ose cases, ou
would want to lea)e t&e )endor code null. /o enter a null, use t&e following snta",
I0S9*/ I0/4 >*4D8?/
=AL89S (L+*/2'H6L,L/itanium drill bitL,L1N24ct23CL, O6, 13, H.63, 3.3M, 08LL!(
Incidentall, note t&at t&e 08LL entr is accepted onl because t&e =@?4D9 attribute is optional1
t&e 04/ 08LL declaration was not used in t&e ?*9A/9 /A+L9 statement for t&is attribute.
Inserting *ows wit& 4ptional Attributes
/&ere mig&t be occasions w&en more t&an one attribute is optional. *at&er t&an declaring eac&
attribute as 08LL in t&e I0S9*/ command, ou can indicate -ust t&e attributes t&at &a)e re#uired
)alues.:ou do t&at b listing t&e attribute names inside parent&eses after t&e table name. <or t&e
purpose of t&is e"ample, assume t&at t&e onl re#uired attributes for t&e >*4D8?/ table are
>@?4D9 and >@D9S?*I>/,
I0S9*/ I0/4 >*4D8?/(>@?4D9, >@D9S?*I>/! =AL89S (L+*/2'H6L,L/itanium drill bitL!(
/&e S9L9?/ command is used to list t&e contents of a table. /&e snta" of t&e S9L9?/ command is
as follows,
S9L9?/ columnlist <*4% tablename
/&e column list represents one or more attributes, separated b commas. :ou could use
t&eP(asterisk! as a wildcard c&aracter to list all attributes. A wildcard c&aracter is a smbol t&at can
be used as a general substitute for ot&er c&aracters or commands. <or e"ample, to list all attributes
and all rows of t&e >*4D8?/ table, use,
S9L9?/ P <*4% >*4D8?/(
8se t&e 8>DA/9 command to modif data in a table. /&e snta" for t&is command is,
8>DA/9 tablename
S9/ columnname Be"pressionD, columnname Be"pressionE
DWA9*9 conditionlistE(
<or e"ample, if ou want to c&ange >@I0DA/9 from December 1', $33C, to Qanuar 1N, $313, in t&e
second row of t&e >*4D8?/ table (see <igure O.'!, use t&e primar ke (1'2Q$7>$! to locate t&e
correct (second! row./&erefore, tpe,
8>DA/9 >*4D8?/
S9/ >@I0DA/9 BL1N2QA02$313L
WA9*9 >@?4D9BL1'2Q$7>$L(
If more t&an one attribute is to be updated in t&e row, separate t&e corrections wit& commas,
8>DA/9 >*4D8?/
S9/ >@I0DA/9 BL1N2QA02$313L,>@>*I?9B1O.CC, >@%I0B13
WA9*9 >@?4D9BL1'2Q$7>$L(
/&e ?4%%I/ command permanentl sa)es all c&anges1suc& as rows added, attributes modified,
and rows deleted1made to an table in t&e database. /&erefore, if ou intend to make our
c&anges to t&e >*4D8?/ table permanent, it is a good idea to sa)e t&ose c&anges b using,
?4%%I/(
If ou &a)e not et used t&e ?4%%I/ command to store t&e c&anges permanentl in t&e database,
ou can restore t&e database to its pre)ious condition wit& t&e *4LL+A?F command. *4LL+A?F
undoes an c&anges since t&e last ?4%%I/ command and brings t&e data back to t&e )alues t&at
e"isted before t&e c&anges were made. /o restore t&e data to t&eir Jprec&angeK condition, tpe,
*4LL+A?F(
?4%%I/ and *4LL+A?F work onl wit& data manipulation commands t&at are used to add, modif,
or delete table rows. <or e"ample, assume t&at ou perform t&ese actions,
1. ?*9A/9 a table called SAL9S.
$. I0S9*/ 13 rows in t&e SAL9S table.
'. 8>DA/9 two rows in t&e SAL9S table.
H. 9"ecute t&e *4LL+A?F command.
Will t&e SAL9S table be remo)ed b t&e *4LL+A?F command; 0o, t&e *4LL+A?F command will
undo onl t&e results of t&e I0S9*/ and 8>DA/9 commands. All data definition commands (?*9A/9
/A+L9! are automaticall committed to t&e data dictionar and cannot be rolled back.
It is eas to delete a table row using t&e D9L9/9 statement( t&e snta" is,
D9L9/9 <*4% tablename
DWA9*9 conditionlistE(
<or e"ample, if ou want to delete from t&e >*4D8?/ table t&e product t&at ou added earlier
w&ose code (>@?4D9! is L+*/2'H6L, use,
D9L9/9 <*4% >*4D8?/
WA9*9 >@?4D9BL+*/2'H6L(
<inall, remember t&at D9L9/9 is a set2oriented command. And keep in mind t&at t&e WA9*9
condition is optional. /&erefore, if ou do not specif a WA9*9 condition, all rows from t&e specified
table will be deletedR
Week $
/o add multiple rows to a table, using anot&er table as t&e source of t&e data. /&e snta" for t&e
I0S9*/ statement is,
I0S9*/ I0/4 tablename S9L9?/ columnlist <*4% tablename(
In t&at case, t&e I0S9*/ statement uses a S9L9?/ sub#uer. A sub#uer, also known as a nested
#uer or an inner #uer, is a #uer t&at is embedded (or nested! inside anot&er #uer./&e inner
#uer is alwas e"ecuted first b t&e *D+%S. Gi)en t&e pre)ious SQL statement, t&e I0S9*/
portion represents t&e outer #uer, and t&e S9L9?/ portion represents t&e sub#uer. :ou can nest
#ueries (place #ueries inside #ueries! man le)els deep( in e)er case, t&e output of t&e inner
#uer is used as t&e input for t&e outer (&ig&er2le)el! #uer.
/&e )alues returned b t&e S9L9?/ sub#uer s&ould matc& t&e attributes and data tpes of t&e
table in t&e I0S9*/ statement. If t&e table into w&ic& ou are inserting rows &as one date attribute,
one number attribute, and one c&aracter attribute, t&e S9L9?/ sub#uer s&ould return one or more
rows in w&ic& t&e first column &as date )alues, t&e second column &as number )alues, and t&e t&ird
column &as c&aracter )alues.
Select Queries
Selecting *ows wit& ?onditional *estrictions
S9L9?/ columnlist
<*4% tablelist
DWA9*9 conditionlistE(
/&e S9L9?/ statement retrie)es all rows t&at matc& t&e specified condition(s!1also known as t&e
conditional criteria1ou specified in t&e WA9*9 clause. /&e condition list in t&e WA9*9 clause of
t&e S9L9?/ statement is represented b one or more conditional e"pressions, separated b logical
operators. /&e WA9*9 clause is optional.
If no rows matc& t&e specified criteria in t&e WA9*9 clause, ou see a blank screen or a message
t&at tells ou t&at no rows were retrie)ed. <or e"ample, t&e #uer,
S9L9?/ >@D9S?*I>/, >@I0DA/9, >@>*I?9, =@?4D9
<*4% >*4D8?/
WA9*9 =@?4D9B$1'HH
returns t&e description, date, and price of products wit& a )endor code of $1'HH.
/&e following e"ample uses t&e Jnot e#ual toK operator,
S9L9?/ >@D9S?*I>/, >@I0DA/9, >@>*I?9, =@?4D9
<*4% >*4D8?/
WA9*9 =@?4D9ST$1'HH
8sing comparison operators on ?&aracter Attributes
String (c&aracter! comparisons are made from left to rig&t. /&is left2to2rig&t comparison is
especiall useful w&en attributes suc& as names are to be compared. <or e"ample, t&e string
JArdmoreK would be -udged greater t&an t&e string JAarensonK but less t&an t&e string J+rownK(
suc& results ma be used to generate alp&abetical listings like t&ose found in a p&one director. If
t&e c&aracters 3UC are stored as strings, t&e same left2to2rig&t string comparisons can lead to
apparent anomalies. <or e"ample, t&e AS?II code for t&e c&aracter J6K is, as e"pected,greater t&an
t&e AS?II code for t&e c&aracter JH.K :et t&e same J6K will also be -udged greater t&an t&e string
JHHK because t&e first c&aracter in t&e string JHHK is less t&an t&e string J6.K <or t&at reason, ou
ma get some une"pected results from comparisons w&en dates or ot&er numbers are stored in
c&aracter format.
?omparison 4perators on Dates
Date procedures are often more software2specific t&an ot&er SQL procedures. <or e"ample, t&e
#uer to list all of t&e rows in w&ic& t&e in)entor stock dates occur on or after Qanuar $3, $313
will look like t&is,
S9L9?/ >@D9S?*I>/, >@Q4A, >@%I0, >@>*I?9, >@I0DA/9
<*4% >*4D8?/
WA9*9 >@I0DA/9 TB L$32Qan2$313L
?omputed ?olumns and Aliases
SQL accepts an )alid e"pressions (or formulas! in t&e computed columns. Suc& formulas can
contain an )alid mat&ematical operators and functions t&at are applied to attributes in an of t&e
tables specified in t&e <*4% clause of t&e S9L9?/ statement.
S9L9?/ >@D9S?*I>/, >@Q4A, >@>*I?9, >@Q4AP>@>*I?9
<*4% >*4D8?/
/o make t&e output more readable, t&e SQL standard permits t&e use of aliases for an column in a
S9L9?/ statement. An alias is an alternati)e name gi)en to a column or table in an SQL
statement.
S9L9?/ >@D9S?*I>/, >@Q4A, >@>*I?9, >@Q4AP >@>*I?9 AS /4/=AL89
<*4% >*4D8?/
:ou could also use a computed column, an alias, and date arit&metic in a single #uer. <or e"ample,
assume t&at ou want to get a list of out2of2warrant products t&at &a)e been stored more t&an C3
das. In t&at case, t&e >@I0DA/9 is at least C3 das less t&an t&e current (sstem! date.
S9L9?/ >@?4D9, >@I0DA/9, DA/9(! 2 C3 AS ?8/DA/9
<*4% >*4D8?/
WA9*9 >@I0DA/9 SB DA/9(!2 C3
Arit&metic operators, *ule of precedence
As ou perform mat&ematical operations on attributes, remember t&e rules of precedence. As t&e
name suggests, t&e rules of precedence are t&e rules t&at establis& t&e order in w&ic& computations
are completed. <or e"ample, note t&e order of t&e following computational se#uence,
1. >erform operations wit&in parent&eses.
$. >erform power operations.
'. >erform multiplications and di)isions.
H. >erform additions and subtractions.
Logical 4perators, A0D, 4* and 04/
We use A0D if bot& conditions are true, 4* if at least one of t&e condition and 04/ if we want to
negate t&e result of a conditional e"pression.
S9L9?/ >@D9S?*I>/, >@I0DA/9, >@>*I?9, =@?4D9
<*4% >*4D8?/
WA9*9 =@?4D9B$1'HH 4* =@?4D9B$H$NN
S9L9?/ >@D9S?*I>/, >@I0DA/9, >@>*I?9,=@?4D9
<*4% >*4D8?/
WA9*9 >@>*I?9 S 63 A0D >@I0DA/9 T L162Qan2$313L
S9L9?/ >@D9S?*I>/, >@I0DA/9, >@>*I?9, =@?4D9
<*4% >*4D8?/
WA9*9 (>@>*I?9 S 63 A0D >@I0DA/9 TL162Qan2$313L! 4* =@?4D9B$H$NN
S9L9?/ P<*4% >*4D8?/
WA9*9 04/ (=@?4D9B$1'HH!
Special 4perators
A0SI2standard SQL allows t&e use of special operators in con-unction wit& t&e WA9*9 clause. /&ese
special operators include,
+9/W990, 8sed to c&eck w&et&er an attribute )alue is wit&in a range
IS 08LL, 8sed to c&eck w&et&er an attribute )alue is null
LIF9, 8sed to c&eck w&et&er an attribute )alue matc&es a gi)en string pattern
I0, 8sed to c&eck w&et&er an attribute )alue matc&es an )alue wit&in a )alue list
9IIS/S, 8sed to c&eck w&et&er a sub#uer returns an rows
/&e +9/W990 Special 4perator
If ou use software t&at implements a standard SQL, t&e operator +9/W990 ma be used to c&eck
w&et&er an attribute )alue is wit&in a range of )alues. <or e"ample, if ou want to see a listing for
all products w&ose prices are between V63 and V133, use t&e following command se#uence,
S9L9?/ P <*4% >*4D8?/
WA9*9 >@>*I?9 +9/W990 63.33 A0D 133.33
/&e IS08LL Special 4perator
Standard SQL allows t&e use of IS 08LL to c&eck for a null attribute )alue. <or e"ample, suppose
t&at ou want to list all products t&at do not &a)e a )endor assigned (=@?4D9 is null!. Suc& a null
entr could be found b using t&e command se#uence,
S9L9?/ >@?4D9, >@D9S?*I>/, =@?4D9
<*4% >*4D8?/
WA9*9 =@?4D9 IS 08LL
/&e LIF9 Special 4perator
/&e LIF9 special operator is used in con-unction wit& wildcards to find patterns wit&in string
attributes. Standard SQL allows ou to use t&e percent sign (W! and underscore (@! wildcard
c&aracters to make matc&es w&en t&e entire string is not known,
W means an and all following or preceding c&aracters are eligible. <or e"ample,
LQWL includes Qo&nson, Qones, Qernigan, Qul, and Q2$'1Q.
LQoW Lincludes Qo&nson and Qones.
LWnL includes Qo&nson and Qernigan.
@ means an one c&aracter ma be substituted for t&e underscore. <or e"ample,
L@$'2H6M2MONCL includes 1$'2H6M2MONC, $$'2H6M2MONC, and '$'2H6M2MONC.
L@$'2@6M2MON@L includes 1$'216M2MON1, 1$'2$6M2MON$, and N$'2C6M2MONN.
L@o@esL includes Qones, ?ones, ?okes, totes, and roles.
<or e"ample, t&e following #uer would find all =90D4* rows for contacts w&ose last names begin
wit&Smit&.
S9L9?/ =@0A%9, =@?40/A?/, =@A*9A?4D9, =@>A409
<*4% =90D4*
WA9*9 =@?40/A?/ LIF9 LSmit&WL
/&e I0 Special 4perator
%an #ueries t&at would re#uire t&e use of t&e logical 4* can be more easil &andled wit& t&e &elp
of t&e special operator I0. <or e"ample, t&e #uer,
S9L9?/ P<*4% >*4D8?/
WA9*9 =@?4D9B$1'HH 4* =@?4D9B$H$NN
can be &andled more efficientl wit&,
S9L9?/ P<*4% >*4D8?/
WA9*9 =@?4D9 I0 ($1'HH, $H$NN!
/&e 9IIS/S Special 4perator
/&e 9IIS/S special operator can be used w&ene)er t&ere is a re#uirement to e"ecute a command
based on t&e result of anot&er #uer. /&at is, if a sub#uer returns an rows, run t&e main #uer(
ot&erwise, don.t. <or e"ample, t&e following #uer will list all )endors, but onl if t&ere are products
to order,
S9L9?/ P<*4% =90D4*
WA9*9 9IIS/S (S9L9?/P <*4% >*4D8?/ WA9*9 >@Q4ASB>@%I0!
/&e 9IIS/S special operator is used in t&e following e"ample to list all )endors, but onl if t&ere are
products wit& t&e #uantit on &and, less t&an double t&e minimum #uantit,
S9L9?/ P
<*4% =90D4*
WA9*9 9IIS/S (S9L9?/P <*4% >*4D8?/ WA9*9 >@Q4AS>@%I0P $!
Week '
Additional Data Definition ?ommands
All c&anges in t&e table structure are made b using t&e AL/9* /A+L9 command, followed b a
keword t&at produces t&e specific c&ange ou want to make. /&ree options are a)ailable, ADD and
D*4>. :ou use ADD to add a column, and D*4> to delete a column from a table. %ost *D+%Ss do
not allow ou to delete a column (unless t&e column does not contain an )alues! because suc& an
action mig&t delete crucial data t&at are used b ot&er tables. /&e basic snta" to add or modif
columns is,
AL/9* /A+L9 tablename
XADDY ( columnname datatpe DXADDY columnname datatpeE !(
/&e AL/9* /A+L9 command can also be used to add table constraints. In t&ose cases, t&e snta"
would be,
AL/9* /A+L9 tablename
ADD constraint D ADD constraintE (
:ou could also use t&e AL/9* /A+L9 command to remo)e a column or table constraint./&e snta"
would be as follows,
AL/9* /A+L9 tablename
D*4>X>*I%A*: F9:Z?4L8%0 columnname Z?40S/*AI0/ constraintnameY
0otice t&at w&en remo)ing a constraint, ou need to specif t&e name gi)en to t&e constraint. /&at
is one reason w& ou s&ould alwas name our constraints in our ?*9A/9 /A+L9 or AL/9* /A+L9
Adding ?olumn
:ou can alter an e"isting table b adding one or more columns. In t&e following e"ample, ou add
t&e column named >@SAL9?4D9 to t&e >*4D8?/ table.
AL/9* /A+L9 >*4D8?/
ADD (>@SAL9?4D9 ?AA*(1!!
Dropping a ?olumn
4ccasionall, ou mig&t want to modif a table b deleting a column. Suppose t&at ou want to
delete t&e =@4*D9* attribute from t&e =90D4* table. /o accomplis& t&at, ou would use t&e
following command,
AL/9* /A+L9 =90D4*
D*4> ?4L8%0 =@4*D9*
Adding >rimar Fe and <oreign Fes
/o define t&e primar ke for t&e new >A*/ table, use t&e following command,
AL/9* /A+L9 >A*/
ADD >*I%A*: F9: (>A*/@?4D9!
<or e"ample, if t&e >A*/ table.s foreign ke &as not et been designated, it can be designated b,
AL/9* /A+L9 >A*/
ADD <4*9IG0 F9: (=@?4D9! *9<9*90?9S =90D4*
Alternati)el, if neit&er t&e >A*/ table.s primar ke nor its foreign ke &as been designated, ou
can incorporate bot& c&anges at once, using,
AL/9* /A+L9 LI09
ADD >*I%A*: F9: (I0=@08%+9*, LI09@08%+9*!
AL/9* /A+L9 LI09
ADD <4*9IG0 F9: (I0=@08%+9*! *9<9*90?9S I0=4I?9
AL/9* /A+L9 LI09
ADD <4*9IG0 F9: (>*4D@?4D9! *9<9*90?9S >*4D8?/
Deleting /able from Database
A table can be deleted from t&e database using t&e D*4> /A+L9 command.<or e"ample, ou can
delete t&e >A*/ table ou -ust created wit&,
Snta" is , D*4> /A+L9 table0ame
D*4> /A+L9 >A*/
4rdering a Listing
/&e 4*D9* +: clause is especiall useful w&en t&e listing order is important to ou. /&e snta" is,
S9L9?/ columnlist
<*4% tablelist
DWA9*9 conditionlistE
D4*D9* +: columnlist DAS?ZD9S?EE
Suc& a multile)el ordered se#uence is known as a cascading order se#uence, and it can be created
easil b listing se)eral attributes, separated b commas, after t&e 4*D9* +: clause.
/&e cascading order se#uence is t&e basis for an telep&one director. /o illustrate a cascading
order se#uence, use t&e
following SQL command on t&e 9%>L4:99 table,
S9L9?/ 9%>@L0A%9, 9%>@<0A%9, 9%>@I0I/IAL, 9%>@A*9A?4D9, 9%>@>A409
<*4% 9%>L4:99
4*D9* +: 9%>@L0A%9, 9%>@<0A%9, 9%>@I0I/IAL
/&e 4*D9* +: clause is useful in man applications, especiall because t&e D9S? #ualifier can be
in)oked. <or e"ample, listing t&e most recent items first is a standard procedure./picall, in)oice
due dates are listed in descending order.
:ou can use t&e 4*D9* +: clause in con-unction wit& ot&er SQL commands, too. <or e"ample, note
t&e use of restrictions on date and price in t&e following command se#uence,
S9L9?/ >@D9S?*I>/, =@?4D9, >@I0DA/9, >@>*I?9
<*4% >*4D8?/
WA9*9 >@I0DA/9 SL$12Qan2$313L
A0D >@>*I?9SB63.33
4*D9* +: =@?4D9, >@>*I?9 D9S?
Listing 8ni#ue =alues
SQL.s DIS/I0?/ clause produces a list of onl t&ose )alues t&at are different from one anot&er. <or
e"ample, t&e command,
S9L9?/ DIS/I0?/ =@?4D9
<*4% >*4D8?/
Aggregate <unctions
?480/
/&e ?480/ function is used to tall t&e number of non2null )alues of an attribute. ?480/ can be
used in con-unction wit& t&e DIS/I0?/ clause. 9"ample ,
S9L9?/ ?480/(DIS/I0?/ =@?4D9!
<*4% >*4D8?/
%AI and %I0
/&e %AI and %I0 functions &elp ou find answers to problems suc& as t&e,
Aig&est (ma"imum! )alue in t&e table.
Lowest (minimum! )alue in t&e table.
S9L9?/ >@?4D9, >@D9S?*I>/, >@>*I?9
<*4% >*4D8?/
WA9*9 >@>*I?9B%AI(>@>*I?9!
S8%
/&e S8% function computes t&e total sum for an specified attribute, using w&ate)er condition(s!
ou &a)e imposed. <or e"ample, if ou want to compute t&e total amount owed b our customers,
ou could use t&e following command,
S9L9?/ S8%(?8S@+ALA0?9! AS /4/+ALA0?9
<*4% ?8S/4%9*
:ou could also compute t&e sum total of an e"pression. <or e"ample, if ou want to find t&e total
)alue of all items carried in in)entor, ou could use,
S9L9?/ S8%(>@Q4AP >@>*I?9! AS /4/=AL89
<*4% >*4D8?/
A=G
Gets t&e a)erage )alue of a numeric column.9"ample
S9L9?/ A=G(>*I?9!
<*4% >*4D8?/
Grouping Data
/&e G*48> +: clause is generall used w&en ou &a)e attribute columns combined wit& aggregate
functions in t&e S9L9?/ statement. /&e G*48> +: clause is )alid onl w&en used in con-unction
wit& one of t&e SQL aggregate functions, suc& as ?480/, %I0, %AI, A=G, and S8%.
S9L9?/ =@?4D9, ?480/(DIS/I0?/ (>?4D9!!
<*4% >*4D8?/
G*48> +: =@?4D9
G*48> +:.s AA=I0G ?LA8S9
A particularl useful e"tension of t&e G*48> +: feature is t&e AA=I0G clause. /&e AA=I0G clause
operates )er muc& like t&e WA9*9 clause in t&e S9L9?/ statement. Aowe)er, t&e WA9*9 clause
applies to columns and e"pressions for indi)idual rows, w&ile t&e AA=I0G clause is applied to t&e
output of a G*48> +: operation.
S9L9?/ =@?4D9, S8%(>@Q4AP >@>*I?9! AS /4/?4S/
<*4% >*4D8?/
G*48> +: =@?4D9
AA=I0G (S8%(>@Q4AP >@>*I?9!T633!
4*D9* +: S8%(>@Q4AP >@>*I?9! D9S?
Week H
?reating A =iew
A )iew is a )irtual table based on a S9L9?/ #uer. /&e #uer can contain columns, computed
columns, aliases, and aggregate functions from one or more tables. /&e tables on w&ic& t&e )iew is
based are called base tables.
:ou can create a )iew b using t&e ?*9A/9 =I9W command,
?*9A/9 =I9W )iewname AS S9L9?/ #uer
9"ample ,
?*9A/9 =I9W >*4D@S/A/S AS
S9L9?/ =@?4D9, S8%(>@Q4AP>@>*I?9! AS /4/?4S/,
%AI(>@Q4A! AS %AIQ/:, %I0(>@Q4A! AS %I0Q/:,
A=G(>@Q4A! AS A=GQ/:
<*4% >*4D8?/
G*48> +: =@?4D9
Qoining /ables
/&e -oin condition is generall composed of an e#ualit comparison between t&e foreign ke and t&e
primar ke of related tables. <or e"ample, suppose t&at ou want to -oin t&e two tables =90D4*
and >*4D8?/. +ecause =@?4D9 is t&e foreign ke in t&e >*4D8?/ table and t&e primar ke in t&e
=90D4* table, t&e link is establis&ed on =@?4D9.
S9L9?/ >*4D8?/.>@D9S?*I>/, >*4D8?/.>@>*I?9, =90D4*.=@0A%9,
=90D4*.=@?40/A?/,=90D4*.=@A*9A?4D9, =90D4*.=@>A409
<*4% >*4D8?/, =90D4*
WA9*9 >*4D8?/.=@?4D9B=90D4*.=@?4D9
4*D9* +: >*4D8?/.>@>*I?9
Qoining /ables wit& Alias
An alias ma be used to identif t&e source table from w&ic& t&e data are taken. /&e aliases > and
= are used to label t&e >*4D8?/ and =90D4* tables in t&e ne"t command se#uence. An legal
table name ma be used as an alias.
S9L9?/ >@D9S?*I>/, >@>*I?9, =@0A%9, =@?40/A?/, =@A*9A?4D9, =@>A409
<*4% >*4D8?/ >, =90D4* =
WA9*9 >.=@?4D9B=.=@?4D9
4*D9* +: >@>*I?9
*ecursi)e Qoins
An alias is especiall useful w&en a table must be -oined to itself in a recursi)e #uer. 8sing t&e
data in t&e 9%> table, ou can generate a list of all emploees wit& t&eir managers. names b
-oining t&e 9%> table to itself. In t&at case, ou would also use aliases to differentiate t&e table
from itself. /&e SQL command se#uence would look like t&is,
S9L9?/ 9.9%>@%G*, %.9%>@L0A%9, 9.9%>@08%, 9.9%>@L0A%9
<*4% 9%> 9, 9%> %
WA9*9 9.9%>@%G*B%.9%>@08%
4*D9* +: 9.9%>@%G*
4uter Qoins
Gi)en t&e contents of t&e >*4D8?/ and =90D4* tables, t&e following left outer -oin will s&ow all
=90D4* rows and all matc&ing >*4D8?/ rows,
S9L9?/ >@?4D9, =90D4*.=@?4D9, =@0A%9
<*4% =90D4* L9</ Q4I0 >*4D8?/
40 =90D4*.=@?4D9B>*4D8?/.=@?4D9
/&e rig&t outer -oin will -oin bot& tables and s&ow all product rows wit& all matc&ing )endor
rows./&e SQL command for t&e rig&t outer -oin is,
S9L9?/ >*4D8?/.>@?4D9, =90D4*.=@?4D9, =@0A%9
<*4% =90D4* *IGA/ Q4I0 >*4D8?/
40 =90D4*.=@?4D9B>*4D8?/.=@?4D9
80I40
>erfect tool for combining a common list of data [ one t&at e"cludes duplicate records. /&e 80I40
statement combines rows from two or more #ueries wit&out including duplicate rows. /&e snta" of
t&e
80I40 statement is,
#uer 80I40 #uer
In ot&er words, t&e 80I40 statement combines t&e output of two S9L9?/ #ueries. (*emember t&at
t&e S9L9?/ statements must be union2compatible. /&at is, t&e must return t&e same number of
attributes and similar data tpes.!
9"ample
select ck@name,ck@prc from tbl@?ake
80I40
select fd@name,fd@prc from tbl@<oodies
*esult,
tbl@?ake
80I40 B
80I40 ALL
Will keep all t&e rows from t&e gi)en #ueries including t&e duplicates
select ck@name,ck@prc from tbl@?ake
80I40 ALL
select fd@name,fd@prc from tbl@<oodies
*esult,
tbl@?ake
80I40 ALL B
I0/9*S9?/
t&e I0/9*S9?/ statement can be used to combine rows from two #ueries, returning onl t&e
rows t&at appear in bot& sets. /&e snta" for t&e I0/9*S9?/ statement is,
#uer I0/9*S9?/ #uer
9"ample
select ck@name,ck@prc from tbl@?ake
I0/9*S9?/
select fd@name,fd@prc from tbl@<oodies
*esult
SQL Q4I0 4>9*A/4*
/&e relational -oin operation merges rows from two tables and returns t&e rows wit& one of t&e following
conditions,
Aa)e common )alues in common columns (natural -oin!.
%eet a gi)en -oin condition (e#ualit or ine#ualit!.
Aa)e common )alues in common columns or &a)e no matc&ing )alues (outer -oin!.
Qoin operations can be classified as inner -oins and outer -oins./&e inner -oin is t&e traditional -oin in w&ic&
onl rows t&at meet a gi)en criteria are selected. /&e -oin criteria can be an e#ualit condition (also called a
natural -oin or an e#ui-oin! or an ine#ualit condition (also called a t&eta -oin!.An outer -oin returns not onl
t&e matc&ing rows but also t&e rows wit& unmatc&ed attribute )alues for one table or bot& tables to be
-oined. /&e SQL standard also introduces a special tpe of -oin, called across -oin, t&at returns t&e same result
as t&e ?artesian product of two sets or tables.
?*4SS Q4I0
performs a relational product (also known as t&e ?artesian product! of two tables. /&e cross -oin snta" is,
S9L9?/ column2list <*4% table1 ?*4SS Q4I0 table$
select P from tbl@?ake
?*4SS Q4I0 tbl@<oodies
*esult
Q4I0 40
Anot&er wa to e"press a -oin w&en t&e tables &a)e no common attribute names is to use t&e Q4I0
40 operand. /&at #uer will return onl t&e rows t&at meet t&e indicated -oin condition. /&e -oin
condition will tpicall include an e#ualit comparison e"pression of two columns. (/&e columns
ma or ma not s&are t&e same name but, ob)iousl, must &a)e comparable data tpes.! /&e
snta" is,
S9L9?/ column2list <*4% table1 Q4I0 table$ 40 -oin2condition
select c.ck@name,c.ck@prc,f.fd@name,fd@prc from tbl@?ake c
Q4I0 tbl@<oodies f 40 f.fd@id B c.ck@id
result
48/9* Q4I0
An outer -oin returns not onl t&e rows matc&ing t&e -oin condition (t&at is, rows wit& matc&ing
)alues in t&e common columns! but also t&e rows wit& unmatc&ed )alues. /&e A0SI standard
defines t&ree tpes of outer -oins, left, rig&t, and full. /&e left and rig&t designations reflect t&e
order in w&ic& t&e tables are processed b t&e D+%S. *emember t&at -oin operations take place
two tables at a time./&e first table named in t&e <*4% clause will be t&e left side, and t&e second
table named will be t&e rig&t side. If t&ree or more tables are being -oined, t&e result of -oining t&e
first two tables becomes t&e left side, and t&e t&ird table becomes t&e rig&t side.
/&e left outer -oin returns not onl t&e rows matc&ing t&e -oin condition (t&at is, rows wit&
matc&ing )alues in t&e common column! but also t&e rows in t&e left side table wit& unmatc&ed
)alues in t&e rig&t side table. /&e snta" is,
S9L9?/ column2list <*4% table1 L9</D48/9*E Q4I0 table$ 40 -oin2condition
select c.ck@name,c.ck@prc,f.fd@name,fd@prc from tbl@?ake c
left Q4I0 tbl@<oodies f 40 f.fd@id B c.ck@id
result
/&e rig&t outer -oin returns not onl t&e rows matc&ing t&e -oin condition (t&at is, rows wit&
matc&ing )alues in t&e common column! but also t&e rows in t&e rig&t side table wit& unmatc&ed
)alues in t&e left side table. /&e snta" is,
S9L9?/ column2list
<*4% table1 *IGA/D48/9*E Q4I0 table$ 40 -oin2condition
select c.ck@name,c.ck@prc,f.fd@name,fd@prc from tbl@?ake c
rig&t Q4I0 tbl@<oodies f 40 f.fd@id B c.ck@id
result
/&e full outer -oin returns not onl t&e rows matc&ing t&e -oin condition (t&at is, rows wit& matc&ing
)alues in t&e common column! but also all of t&e rows wit& unmatc&ed )alues in eit&er side table.
/&e snta" is,
S9L9?/ column2list
<*4% table1 <8LLD48/9*E Q4I0 table$ 40 -oin2condition
select c.ck@name,c.ck@prc,f.fd@name,fd@prc from tbl@?ake c
<8LL Q4I0 tbl@<oodies f 40 f.fd@id B c.ck@id
*esult
S9L9?/ S8+Q89*:
9"ample ,
Insert
insert into tbl@?ake (ck@name,ck@prc!
select fd@name,fd@prc from tbl@<oodies
update
update tbl@?ake set ck@prc B (select %I0(ck@prc! from tbl@?ake!
w&ere ckt@id in (select fd@id from tbl@<oodies!
delete
delete from tbl@?ake
w&ere ckt@id in (select fd@id from tbl@<oodies!
/o be precise, t&e sub#uer can return,
4ne single )alue(one column and one row!. /&is sub#uer is used anw&ere a single )alue is
e"pected, as in t&e rig&t side of a comparison e"pression (suc& as in t&e preceding 8>DA/9
e"ample w&en ou assign t&e a)erage price to t&e product.s price!. 4b)iousl, w&en ou
assign a )alue to an attribute, t&at )alue is a single )alue, not a list of )alues. /&erefore, t&e
sub#uer must return onl one )alue (one column, one row!. If t&e #uer returns multiple
)alues, t&e D+%S will generate an error.
A list of )alues(one column and multiple rows!. /&is tpe of sub#uer is used anw&ere a list
of )alues is e"pected, suc& as w&en using t&e I0 clause (t&at is, w&en comparing t&e )endor
code to a list of )endors!. Again, in t&is case, t&ere is onl one column of data wit& multiple
)alue instances./&is tpe of sub#uer is used fre#uentl in combination wit& t&e I0 operator
in a WA9*9 conditional e"pression.
A )irtual table (multicolumn, multirow set of )alues!. /&is tpe of sub#uer can be used
anw&ere a table is e"pected, suc& as w&en using t&e <*4% clause.
/&e most common tpe of sub#uer uses an inner S9L9?/ sub#uer on t&e rig&t side of a WA9*9
comparison e"pression.<or e"ample, to find all products wit& a price greater t&an or e#ual to t&e
a)erage product price, ou write t&e following #uer,
S9L9?/ >@?4D9, >@>*I?9 <*4% >*4D8?/
WA9*9 >@>*I?9 TB (S9L9?/ A=G(>@>*I?9! <*4% >*4D8?/!(
/&e output of t&e preceding #uer is s&own in <igure N.1'. 0ote t&at t&is tpe of #uer, w&en used
in aT, S, B, TB, or SB conditional e"pression, re#uires a sub#uer t&at returns onl one single
)alue (one column, one row!./&e )alue generated b t&e sub#uer must be of a JcomparableK data
tpe( if t&e attribute to t&e left of t&e comparison smbol is a c&aracter tpe, t&e sub#uer must
return a c&aracter string. Also, if t&e #uer returns more t&an a single )alue, t&e D+%S will
generate an error.
Sub#ueries can also be used in combination wit& -oins.<or e"ample, t&e following #uer lists all of
t&e customers w&o ordered t&e product J?law &ammerK,
S9L9?/ DIS/I0?/ ?8S@?4D9, ?8S@L0A%9, ?8S@<0A%9 <*4% ?8S/4%9* Q4I0 I0=4I?9 8SI0G
(?8S@?4D9!
Q4I0 LI09 8SI0G (I0=@08%+9*! Q4I0 >*4D8?/ 8SI0G (>@?4D9!
WA9*9 >@?4D9B(S9L9?/ >@?4D9 <*4% >*4D8?/ WA9*9 >@D9S?*I>/B\?law &ammer.!(
I0 sub#ueries
W&en ou want to compare a single attribute to a list of )alues, ou use t&e I0 operator.
W&en t&e >@?4D9 )alues are not known before&and, but t&e can be deri)ed using a #uer, ou
must use an I0
sub#uer. /&e following e"ample lists all customers w&o &a)e purc&ased &ammers, saws, or saw
blades.
S9L9?/ DIS/I0?/ ?8S@?4D9, ?8S@L0A%9, ?8S@<0A%9 <*4% ?8S/4%9* Q4I0 I0=4I?9 8SI0G
(?8S@?4D9!
Q4I0 LI09 8SI0G (I0=@08%+9*! Q4I0 >*4D8?/ 8SI0G (>@?4D9!
WA9*9 >@?4D9 I0 ( S9L9?/ >@?4D9 <*4% >*4D8?/
WA9*9 >@D9S?*I>/ LIF9 LW&ammerWL 4* >@D9S?*I>/ LIF9 LWsawWL!
?orrelated Sub#ueries
is a sub#uer t&at e"ecutes once for eac& row in t&e outer #uer. /&at process is similar to t&e
tpical nested loop in a programming language. <or e"ample,
<4* IB1 /4 $
<4* :B1 /4 '
>*I0/ JIBJI, J:BJ:
90D
90D
will ield t&e output,
IB1 :B1
IB1 :B$
IB1 :B'
IB$ :B1
IB$ :B$
IB$ :B'
0ote t&at t&e outer loop IB1 /4 $ begins t&e process b setting IB1 and t&en t&e inner loop :B1
/4 ' is completed for eac& I outer loop )alue. /&e relational D+%S uses t&e same se#uence to
produce correlated sub#uer results,
1. It initiates t&e outer #uer.
$. <or eac& row of t&e outer #uer result set, it e"ecutes t&e inner #uer b passing t&e outer row
to t&e inner #uer.
/o see t&e correlated sub#uer in action, suppose t&at ou want to know all product sales in w&ic&
t&e units sold )alue is greater t&an t&e a)erage units sold )alue for t&at product(as opposed to t&e
a)erage for all products!.In t&at case,t&e following procedure must be completed,
1. ?ompute t&e a)erage2units2sold )alue for a product.
$. ?ompare t&e a)erage computed in Step 1 to t&e units sold in eac& sale row and t&en select
onl t&e rows in w&ic& t&e number of units sold is greater.
/&e following correlated #uer completes t&e preceding two2step process,
S9L9?/ I0=@08%+9*, >@?4D9, LI09@80I/S
<*4% LI09 LS
WA9*9 LS.LI09@80I/S T (S9L9?/ A=G(LI09@80I/S!
<*4% LI09 LA
WA9*9 LA.>@?4D9BLS.>@?4D9!
?orrelated sub#ueries can also be used wit& t&e 9IIS/S special operator.<or e"ample, suppose t&at
ou want to know all customers w&o &a)e placed an order latel.
S9L9?/ ?8S@?4D9, ?8S@L0A%9, ?8S@<0A%9
<*4% ?8S/4%9*
WA9*9 9IIS/S (S9L9?/ ?8S@?4D9 <*4% I0=4I?9
WA9*9 I0=4I?9.?8S@?4D9B?8S/4%9*.?8S@?4D9!
<or e"ample, suppose t&at ou want to know w&at )endors ou must contact to start ordering
products t&at are approac&ing t&e minimum #uantit2on2&and )alue. In particular, ou want to
know t&e )endor code and name of )endors for products &a)ing a #uantit on &and t&at is less t&an
double t&e minimum #uantit. /&e #uer t&at answers t&at #uestion is as follows,
S9L9?/ =@?4D9, =@0A%9
<*4% =90D4*
WA9*9 9IIS/S (S9L9?/ P
<*4% >*4D8?/
WA9*9 >@Q4AS>@%I0P $
A0D =90D4*.=@?4D9B>*4D8?/.=@?4D9!
1. /&e inner correlated sub#uer runs using t&e first )endor.
$. If an products matc& t&e condition (#uantit on &and is less t&an double t&e minimum
#uantit!, t&e )endor code and name are listed in t&e output.
'. /&e correlated sub#uer runs using t&e second )endor, and t&e process repeats itself until all
)endors are used.
Week '
SQL <unctions
Date and /ime functions
/&e DA/9ADD function produces a date b adding a specified number to a specified part of a
date.
/&e format for t&e DA/9ADD function is,
DA/9ADD(datepart, number, date_field!
datepart would be eit&er dd, mm, or . number would be t&e number t&at ou want to add to
t&e datepart. date_field would be t&e date field t&at ou want to add to.
<or e"ample, to add $ das to t&e birt&date of e)er person in Date/able we would tpe,
S9L9?/ names, LAdd $ das to birt&daL B DA/9ADD(dd, $, birt&date!
<*4% Datetable
:ou can also subtract two das from t&e birt&date of e)er person in Date/able b adding a 2$
(minus or negati)e $! instead of a positi)e $, as s&own b t&e following #uer,
S9L9?/ names, LAdd $ das to birt&daL B DA/9ADD(dd, 2$, birt&date!
<*4% Datetable
/&e DA/9DI<< function returns t&e difference between two parts of a date. /&e format for
t&e DA/9DI<< function is,
DA/9DI<<(datepart, date_field1, date_field2!
Aere again, datepart would be eit&er dd, mm, or . And, date_field1 and date_field2 would be
t&e two date fields t&at ou want to find t&e difference between.
<or e"ample, to find t&e number of mont&s between t&e two fields, birt&date and
sc&ool@date of e)er person in Date/able, we would tpe,
S9L9?/ names, L%ont&s between birt& date and sc&ool dateL B DA/9DI<<(mm, birt&date,
sc&ool@date!
<*4% Datetable
/&e DA/9>A*/ function returns t&e specified part of t&e date re#uested. /&e format for t&e
DA/9>A*/ function is,
DA/9>A*/(datepart, date_field!
Aere too, datepart would be eit&er dd, mm, or . And, date_field would be t&e date field t&at
ou want to re#uest t&e dd, mm, or from.
<or e"ample, to find ear from t&e birt&date of e)er person in Date/able we would tpe,
S9L9?/ names, L:9A*SL B DA/9>A*/(, birt&date!
<*4% Datetable
/&e :9A*(column! function will e"tract t&e ear from a )alue stored as a S%ALLDA/9/I%9 data
tpe. <or e"ample, to e"tract t&e ear from t&e sc&ool@date column of e)er person in
Date/able, tpe,
S9L9?/ names, :9A*(sc&ool@date! AS DFindergarten :earE
<*4% Datetable
/&e %40/A function will e"tract t&e mont& from a date. /&en, to add si" mont&s to t&e birt&
mont& of e)er person in Date/able, we can first e"tract t&e mont& b %40/A(birt&date!, and
t&en add si" to it, as s&own &ere,
S9L9?/ names, birt&date, %40/A(birt&date! AS D+irt& %ont&E, ((%40/A(birt&date!! ] M !
AS DSi"t& mont&E
<*4% Date/able
/&e DA: function e"tracts t&e da of t&e mont& from a date. <or e"ample, to find t&e da
from t&e birt&date of e)er person in Date/able, tpe t&e following #uer,
S9L9?/ names, birt&date, DA:(Dbirt&dateE! AS DDateE
<*4% Date/able
/&e G9tdA/9 function returns t&e current sstem date and time.
<or e"ample,
S9L9?/ L/oda L B G9/DA/9( !
Inserting the current date and time
8sing t&e G9/DA/9( ! function, we can insert or update t&e current date and time into a
column. /o illustrate t&is, we will add a new record (row! to our Date/able, inserting t&e
current date and time into t&e birt&date column of t&is row using t&e G9/DA/9( ! function, and
t&en add fi)e ears to t&e current date for t&e sc&ool@date column of t&is new row. So tpe,
I0S9*/ I0/4 Date/able
=AL89S (G9/DA/9(!, G9/DA/9( !]:9A*(6!, L>iali Sa&aL!
*ow2le)el <unctions
operate on )alues in single rows, one row at a time. A row2le)el ^function^ can be used to
perform an arit&metic operation on a column.
/&e *480D function rounds numbers to a specified number of decimal places. <or e"ample,
in t&e 9mploee table, if ou wanted to di)ide e)er personLs wage b ' (a t&ird of t&e wage!,
ou would tpe (wage7'!. /&en, to round t&is, ou could use *480D(wage7'!, and include t&e
precision (number of decimal places! after t&e comma. In #uer form, t&is would be,
S9L9?/ names, wage, *480D((wage7'!, $! AS Dwage7'E
<*4% 9mploee
<or *480D, t&e rule is if t&e nearest decimal place to be rounded is 6 and up, we round up, if its H
or less we round down.
4t&er e"amples, (tbl@9mploee!
ID 0A%9@ SALA*: +408S
1 %9L 1$33.1$6 11.HH
$ %IF9 1$33.1$H 11.$'6
' 0IF9 1$33.116 11.6H6
select round(salar,'! as A, round(salar,$! as +, round(salar,1! as ?, round(bonus,3! from
tbl@9mploee
4utput,
A + ? D
1$33.1$6 11.HH3 1$33.133 11.333
1$33.1$H 11.$H3 1$33.133 11.333
1$33.116 11.663 1$33.133 1$.333
4t&er )er common numeric functions include,
?9ILI0G(attribute!, w&ic& returns t&e ne"t larger integer )alue w&en a number contains
decimal places.
<L44*(attribute!, w&ic& returns t&e ne"t lower integer )alue w&en a number contains
decimal places.
SQ*/(attribute!, w&ic& returns t&e s#uare root of positi)e numeric )alues.
A+S(attribute!, w&ic& returns t&e absolute )alue of an numeric )alue.
SQ8A*9(attribute!, w&ic& returns a number s#uared.
*emember t&e following,
a. W&en using ?9ILI0G, if it &as a )alue in it.s decimal place, no matter &ow small or big, as
long as it is not 3, t&en round up
b. W&en using <L44*, if it &as a )alue in it.s decimal place, no matter &ow small or big, as long
as it is not 3, t&en round down
Example:
select ceiling(salar@! as salar@?9ILI0G, ceiling(bonus ! as bonus@?9ILI0G,
floor(salar@ ! as salar@<L44*, floor(bonus ! as bonus@<L44* from tbl@9mploee
salary_CEILI! bonus_CEILI! salary_"L##$ bonus_"L##$
%&'% %& %&'' %%
%&'% %& %&'' %%
%&'% %& %&'' %%

c. <or SQ8A*9, SQ*/ and A+S -ust suppl t&e numeric field to get t&e desired )alue. *emember
t&at A+S returns unsigned numeric )alue, meaning if its 2$6 or ]$6 it will -ust return
$6.%inus t&e smbol.
ID 0A%9@ SALA*: +408S
1 %9L $ 2H
$ %IF9 ' N
' 0IF9 C 1$
9"ample,
select abs(bonus! from tbl@9mploee
H.333
N.333
1$.333
select s#uare(salar@! as SQ8A*9D,s#rt(salar@! as SQ*t from tbl@9mploee
SQ8A*9D SQ*t
H 1.H1H$1'6M$'O'1
C 1.O'$363N3O6MNNN
N1 '
Isnull function
/o &andle t&e null issue, SQL Ser)er pro)ides a row2le)el function, IS08LL, w&ic& returns a
)alue if a table )alue is null. /&e IS08LL function &as t&e following form,
IS08LL(e"pression1, =alueIf0ull!
/&e IS08LL function sas t&at if t&e e"pression (or column )alue! is not null, return t&e
)alue, but if t&e )alue is null, return =alueIf0ull. 0ote t&at t&e =alueIf0ull must be compatible
wit& t&e data tpe. <or e"ample, if ou wanted to use a default )alue of 5ero for a null in
t&e pre)ious e"ample, ou could tpe t&is,
D9?LA*9 _a <L4A/, _b <L4A/
S9/ _a B 08LL
S9/ _b B $
S9L9?/ IS08LL(_a, 3! ] IS08LL(_b, 3! AS LA ] + B L
08LLI< function, w&ic& returns a 08LL if expression1 B expression2. If t&e e"pressions are not
e#ual, t&en expression1 is returned. /&e 08LLI< function &as t&e following form,
08LLI<(expression1, expression2!
<or e"ample, if we want to see w&et&er t&e wage is 3, we would tpe,
S9L9?/ names, wage, new@wage B 08LLI<(wage, 3!
<*4% 9mploee
/4> function is used to displa or return from a result set t&e rows t&at fall at t&e top of a
range specified b an 4*D9* +: clause. Suppose ou want t&e names of t&e ^top $^ (first
two! emploees wit& t&e lowest wages from t&e 9mploee table (top $ refers to t&e results in
t&e first two rows!. :ou would tpe,
S9L9?/ /4> $ names, wage
<*4% 9mploee
4*D9* +: wage AS?
if ou want to get t&e ^bottom^ two emploees meaning, t&e emploees wit& t&e &ig&est
wages (t&e )alues in t&e last two ordered rows! instead of t&e top two emploees from t&e
9mploee table, t&e top two emploees (t&e &ig&est wages! would &a)e to be selected from
t&e table ordered in descending order, as follows,
S9L9?/ /4> $ names, wage
<*4% 9mploee
4*D9* +: wage D9S?
/o &andle ties, SQL Ser)er &as a WI/A /I9S option t&at can be used wit& t&e /4> function.
S9L9?/ /4> $ WI/A /I9S names, wage
<*4% 9mploee
4*D9* +: wage AS?
>9*?90/ returns a certain percentage of rows t&at fall at t&e top of a specified range. <or
e"ample, t&e following #uer returns t&e top 13 percent (b count! of t&e student names
from t&e Student table based on t&e order of names,
S9L9?/ /4> 13 >9*?90/ sname
<*4% Student
4*D9* +: sname AS?
Again, t&ere is no +4//4% >9*?90/ function, so in order to get t&e bottom 13 percent, ou
would &a)e to order t&e sname column in descending order and t&en select t&e top 13
percent, as follows,
S9L9?/ /4> 13 >9*?90/ sname
<*4% Student
4*D9* +: sname D9S?
0ote for e"ample t&at ou &a)e ' records and ou get t&e top 13 percent, it will return 1, because 1
to '' W of ' will return 1. W&ereas if we get t&e 'HW to MMW it will return $ records and from MOW
to 133, it will return '.
/&e DIS/I0?/ function omits rows in t&e result set t&at contain duplicate data in t&e selected
columns. /o S9L9?/ all distinct grades from t&e Grade@report table, ou would tpe,
S9L9?/ DIS/I0?/ grade
<*4% Grade@report
DIS/I0?/ can also be used as an option wit& aggregate functions like ?480/, S8% and A=G.
<or e"ample, to count t&e distinct grades from t&e Grade@report table, we can tpe,
S9L9?/ ^?ount of distinct grades^ B ?480/(DIS/I0?/(grade!!
<*4% Grade@report
?on)ersion <unctions
/&e ?AS/ result can t&en be used for,
?oncatenating strings
Qoining columns t&at were not en)isioned as related
>erforming unions of tables
>erforming mat&ematical operations on columns t&at were defined as c&aracter but
w&ic& actuall contain numbers t&at need to be calculated.
In t&is table, names was defined as a 0=A*?AA* column, wage was defined as a
S%ALL%409: column, and &ours was defined as a S%ALLI0/ column. We will use ?AS/ to
c&ange t&e displa of t&e &ours column to a c&aracter column so t&at we can
concatenate a string to it, as s&own in t&e following #uer,
S9L9?/ names, wage, &ours B ?AS/(&ours AS ?AA*($!! ] L &ours worked per weekL
<*4% 9mploee
/&is #uer will gi)e us,
names wage &ours
22222222222222222222 222222222222 222222222222222222222222
Sumon +agui 13.3333 H3 &ours worked per week
Sudip +agui 16.3333 '3 &ours worked per week
>rias&i Sa&a 1N.3333 08LL
9d 9)ans 08LL 13 &ours worked per week
S/* is a speciali5ed con)ersion function t&at alwas con)erts from a number (for e"ample,
float or numeric! to a c&aracter data tpe. It allows ou to e"plicitl specif t&e lengt& and
number of decimal places t&at s&ould be formatted for t&e c&aracter string.
/&e general form of t&e snta" for t&e S/* function is,
S/*(float_expression, character_length, number_of_decimal_places!
In t&is table, t&e &ours column is a S%ALLI0/ column. /o format it to two decimal places, we
can use S/*. 0ote t&at we &a)e to make t&e c&aracter lengt& 6 in t&is case in order to
accommodate t&e .33 (t&e decimal point and 5eros!. <ollowing is t&e #uer s&owing t&is,
S9L9?/ names, wage, &ours B S/*(&ours, 6, $!
<*4% 9mploee
w&ic& produces,
names wage &ours
22222222222222222222 222222222222222222222 22222
Sumon +agui 13.33 H3.33
Sudip +agui 16.33 '3.33
?40=9*/ function is also used to e"plicitl con)ert to a gi)en data tpe. +ut, t&e ?40=9*/
function &as additional limited formatting capabilities.
/&e general snta" for t&e ?40=9*/ function is,
?40=9*/(desired_datatypeD(length!E, original_expression D, styleE!
?40=9*/ &as an optional t&ird parameter, stle, w&ic& is used for formatting. If stle is not
specified, it will use t&e default stle. +ecause t&e ?40=9*/ function &as formatting
capabilities, it is widel used w&en displaing dates in a particular format
String <unctions
0ow, suppose ou would like to concatenate eac& of t&e names wit& ^, 9s#.^ /pe t&e
following,
S9L9?/ names ] L, 9s#.L AS D9mploee 0amesE
<*4% 9mploee
/&is #uer produces,
9mploee 0ames
222222222222222222222
Sumon +agui, 9s#.
Sudip +agui, 9s#.
>rias&i Sa&a, 9s#.
As anot&er e"ample, suppose ou want to add a series of dots (.....! to t&e left side of t&e
names column. :ou would tpe,
S9L9?/ (L.....L] names! AS D9mploee 0amesE
<*4% 9mploee
to produce t&e following result set,
9mploee 0ames
22222222222222222222
.....Sumon +agui
.....Sudip +agui
.....>rias&i Sa&a
SQL &as se)eral string e"tractor functions. /&is section briefl describes some of t&e more
useful string e"tractors, like S8+S/*I0G, L9</, *IGA/, L/*I%, */*I%, and ?AA*I0D9I.
/&e S8+S/*I0G function returns part of a string. <ollowing is t&e format for t&e S8+S/*I0G
function,
S8+S/*I0G(stringexpression, startposition, length!
stringexpression is t&e column t&at we will be using, startposition tells SQL Ser)er w&ere in t&e
stringexpression to start retrie)ing c&aracters from, and length tells SQL Ser)er &ow man
c&aracters to e"tract. All t&ree parameters are re#uired in SQL Ser)er $336Ls S8+S/*I0G
function. <or e"ample, tpe t&e following,
S9L9?/ names, S8+S/*I0G(names,$,H! AS Dmiddle of namesE
<*4% 9mploee
/&is #uer returns,
names middle of names
222222222222222 222222222222222
Sumon +agui umon
Sudip +agui udip
If ou start at position 3, t&e following #uer will s&ow ou w&at ou will get,
S9L9?/ names, ^first letter of names^ B S8+S/*I0G(names,3,$!
<*4% 9mploee
:ou will get,
names first letter of names
222222222222222 222222222222222222222
Sumon +agui S
Sudip +agui S
L9</(stringexpression, n!
4r,
*IGA/(stringexpression, n!
/&e L9</ function starts from t&e L9</ of t&e stringexpression or column and returns n
c&aracters, and t&e *IGA/ function starts from t&e rig&t of t&e stringexpression or column and
returns n c&aracters.
<or e"ample, to get t&e first t&ree c&aracters from t&e names column, tpe,
S9L9?/ names, L9</(names,'! AS DleftE
<*4% 9mploee
/&is #uer produces,
names left
222222222222222 2222
Sumon +agui Sum
Sudip +agui Sud
/o get t&e last t&ree c&aracters from t&e names column (&ere t&e count will start from t&e
rig&t of t&e column, names!, tpe,
S9L9?/ names, *IGA/(names,'! AS Drig&tE
<*4% 9mploee
/&is #uer produces,
names rig&t
222222222222222 2222222
Sumon +agui gui
Sudip +agui gui
L/*I% remo)es blanks from t&e beginning (left! of a string. <or e"ample, if t&ree blank
spaces appear to t&e left of a string suc& as L *anuL, ou can remo)e t&e blank spaces wit&
t&e following #uer,
S9L9?/ L/*I%(L *anuL! AS names
w&ic& produces,
names
2222222
*anu
It does not matter &ow man blank spaces precede t&e non2blank c&aracter. All leading
blanks will be e"cised.
Similarl, */*I% remo)es blanks from t&e end (rig&t! of a string. <or e"ample, if blank
spaces appear to t&e rig&t of *anu in t&e names column, ou could remo)e t&e blank spaces
using t&e */*I%, and t&en concatenate ^Sa&a^ wit& t&e ] sign, as s&own &ere,
S9L9?/ */*I%(L*anu L! ] L Sa&aL AS names
/&is #uer produces,
names
222222222222
*anu Sa&a
/&e ?AA*I0D9I function returns t&e starting position of a specified pattern. <or e"ample, if
we wis& to find t&e position of a space in t&e emploee names in t&e 9mploee table, we
could tpe,
S9L9?/ names, ^>osition of Space in 9mploee 0ames^ B ?AA*I0D9I(L L,names!
<*4% 9mploee
/&is #uer would gi)e,
names >osition of Space in 9mploee 0ames
222222222222222 22222222222222222222222222222222222
Sumon +agui M
Sudip +agui M
/o produce all t&e fields in t&e result set (output! in uppercase or in lowercase, ou can use
t&e 8>>9* or L4W9* functions. <or e"ample, to produce all t&e names in t&e 9mploee table in
uppercase, tpe,
S9L9?/ 8>>9*(names! AS D0A%9S I0 ?A>SE
<*4% 9mploee
/&is #uer produces t&e following output,
0A%9S I0 ?A>S
222222222222222222222222
S8%40 +AG8I
S8DI> +AG8I
/&e L90 function returns t&e lengt& (number of c&aracters! of a desired string e"cluding
trailing blanks. <or e"ample, to list t&e lengt&s of t&e full names (including an spaces! in
t&e 9mploee table, tpe,
S9L9?/ names, L90(names! AS DLengt& of 0amesE
<*4% 9mploee
/&is #uer produces t&e following output,
names Lengt& of 0ames
222222222222222 222222222222222
Sumon +agui 11
Sudip +agui 11
(able o) "unctions
*ggregate "unctions
A=G A)erages a group of row )alues.
?480/ ?ounts t&e total number of rows in a result set.
%AI *eturns t&e &ig&est of all )alues from a column.
%I0 *eturns t&e lowest of all )alues from a column.
S8% Adds all t&e )alues in a column.
*ow2le)el <unctions
A+S *eturns an absolute )alue.
?9ILI0G *eturns t&e ne"t larger integer )alue.
<L44* *eturns t&e ne"t lower integer )alue.
IS08LL *eturns a true )alue if a data item contains a 08LL.
08LLI< *eturns a 08LL if a certain condition is met in an e"pression.
*480D *ounds numbers to a specified number of decimal places.
S/* ?on)erts from a number to a c&aracter data tpe.
SQ*/ *eturns t&e s#uare root of positi)e numeric )alues.
SQ8A*9 *eturns t&e s#uare of a number.
String <unctions
?AA*I0D9I *eturns t&e starting position of a specified pattern.
L9</ *eturns t&e left portion of a string up to a gi)en number of c&aracters.
*ggregate "unctions
L90 *eturns t&e lengt& of a string.
LIF9 4ption t&at matc&es a particular pattern.
L4W9* ?on)erts a string to lower case.
*IGA/ *eturns t&e rig&t portion of a string.
*/*I% *emo)es blanks from t&e rig&t end of a string.
S8+S/*I0G *eturns part of a string.
8>>9* Displas all output in upper case.
Date <unctions
DA/9ADD Adds to a specified part of a date.
DA/9DI<< *eturns t&e difference between two dates.
DA/9>A*/ *eturns t&e specified part of t&e date re#uested.
DA: 9"tracts a da from a date.
G9tdA/9 *eturns t&e current sstem date and time.
%40/A 9"tracts t&e mont& from a date.
S9/ DA/9<4*%A/ ?&anges t&e format in w&ic& SQL Ser)er reads in dates.
:9A* 9"tracts t&e ear from a date.
?on)ersion <unctions
?AS/ ?&anges a data tpe of a column in a result set.
?40=9*/ 9"plicitl con)erts to a gi)en data tpe in a result set.
4t&er <unctions
DIS/I0?/ 4mits rows t&at contain duplicate data.
>9*?90/
*eturn a certain percentage of records t&at fall at t&e top of a range
specified.
/4> *eturns a specified number of records from t&e top of a result set.
Week H
8sing ?AS9
In SQL Ser)er we can simulate a switc& or case statement b using t&e ?AS9 function. 9",
select ck@dte,ck@name,
case w&en ck@fla)or B \+anana. t&en \%onke.
w&en ck@fla)or B \>eanut. t&en \9lep&ant.
w&en ck@fla)or B \Apple. t&en \9agle.
else \8nknown Animal. end AS ck@animal
from tbl@?ake
select ck@name,
case w&en (ck@prc T 3! and (ck@prc S 11! t&en L%urang muraL
w&en (ck@prc T 13! and (ck@prc S 61! t&en LSakto langL
w&en (ck@prc T 63! t&en L%a&al naL
else LDi ko alam RL end AS cake@comment
from tbl@?ake
select "@name,
case
w&en "@name B LADA%A0/I8%L t&en LW4L=9*I09L
w&en "@name B LF*:>/40I/9L t&en LS8>9*%A0L
w&en "@name B L%AG09/L t&en L%AG09/4L
w&en "@name B LWA99L?AAI*L t&en L>*4< IL
else L?9D*I?FL
end as LS8>9*A9*4L,
"@id
from /able@1
select "@name,
case
w&en "@name B L]L t&en "@col1 ] "@col$
w&en "@name B L2L t&en "@col1 2 "@col$
w&en "@name B LPL t&en "@col1 P "@col$
w&en "@name B L7L t&en "@col1 7 "@col$
else 3
end as LA0SW9*L,
"@col1,"@col$
from /able@1
/rigger
a procedural SQL code t&at is automaticall in)oked b t&e *D+%S upon t&e occurrence of a gi)en
data manipulation e)ent. It is useful to remember t&at,
A trigger is in)oked before or after a data row is inserted, updated, or deleted.
A trigger is associated wit& a database table.
9ac& database table ma &a)e one or more triggers.
A trigger is e"ecuted as part of t&e transaction t&at triggered it.

/riggers are critical to proper database operation and management. <or e"ample,
/riggers can be used to enforce constraints t&at cannot be enforced at t&e D+%S design and
implementation le)els.
/riggers add functionalit b automating critical actions and pro)iding appropriate warnings
and suggestions for remedial action. In fact, one of t&e most common uses for triggers is to
facilitate t&e enforcement of referential integrit.
/riggers can be used to update table )alues, insert records in tables, and call ot&er stored
procedures
A /*IGG9* is created using t&e ?*9A/9 /*IGG9* command.
9"amples
?ode,
?*9A/9 /*IGG9* trigAddStudents
40 Students
<4* I0S9*/
AS
D9?LA*9 _0ewname =A*?AA*(133!
S9L9?/ _0ewname B(S9L9?/ 0ame <*4% I0S9*/9D!
>*I0/ L/A9 S/8D90/ L ] _0ewname ] L IS ADD9D.L(
9"planation,
9"ecuting t&is creates a new trigger named trigAddStudents, w&ic& is attac&ed to t&e LStudentsL
table. W&ene)er a new record is added to t&e LStudentsL table, SQL Ser)er will automaticall
e"ecute our trigger.
LetLs look at t&e abo)e e"ample in detail,
?*9A/9 /*IGG9* trigAddStudents
40 Students
22A new trigger ob-ect, trigAddStudents, s&ould be attac&ed to t&e LStudentsL table.
<4* I0S9*/
22/&e trigger will be fired w&en an I0S9*/ command is e"ecuted on t&e LStudentsL table
(If we would like to &andle t&e I0S9*/ and 8>DA/9 e)ents, we would &a)e to use <4* I0S9*/,
8>DA/9!.
AS
D9?LA*9 _0ewname =A*?AA*(133!
S9L9?/ _0ewname B (S9L9?/ 0ame <*4% Inserted!
22W&en t&e trigger is called t&e #ueries after t&e AS keword is e"ecuted.
S9L9?/ 0ame <*4% I0S9*/9D
22/&e SQL command retrie)es t&e L0ameL field from t&e inserted table. /&e inserted table, w&ic&
contains all t&e )alues we inserted using t&e I0S9*/ command.
(Similarl for 8>DA/9 and D9L9/9 command we can use I0S9*/9D (update and insert bot& use
I0S9*/9D table! and D9L9/9D.!
>*I0/ L/A9 S/8D90/ L ] _0ewname ] L IS ADD9D.L
22>rints t&e name selected from t&e I0S9*/9D table
9"ample,
I0S9*/ I0/4 Students =AL89S (M,LGeorge %at&ewL, 1, $66H$, 1!(
4utput,
/A9 S/8D90/ George %at&ew IS ADD9D.
(1 row(s! affected!
9"planation,
W&en t&e abo)e I0S9*/ statement is e"ecuted, t&e new record is added to t&e LStudentsL table and
automaticall calls t&e trigger.
0ote,
/&e name of a trigger s&ould follow t&e rules for identifiers.
/&e ?*9A/9 /*IGG9* must be t&e first statement in t&e batc&.
/riggers cannot be created on a )iew, temporar table or sstem table, but t&e can
reference )iews or temporar tables.
/&e sstem tables s&ould not be referenced in a trigger. 8se t&e Information Sc&ema =iews
instead.
We will use t&e following table structure,
create trigger trg@Imen
on /able@1
for insert
as
begin
declare _name )arc&ar(133! 22)ariable for name
declare _id int 22)ariable for id
declare _col1 decimal(1$,H! 22)ariable for col1
declare _col$ decimal(1$,H! 22)ariable for col$
select _name B "@name,
_id B "@id,
_col1B "@col1,
_col$ B "@col$
from I0S9*/9D
print _name ] L &as id of L ] cast(_id as )arc&ar(133!!
] L and )alue of L ]
cast(_col1 as )arc&ar(633!! ] L and L
] cast(_col$ as )arc&ar(633!!(
end
W&en we e"ecute t&e statement ,
insert into /able@1
)alues (L>I04F:AL,1H',MC!
t&e output will be,
9"ample $, 22 t&is will add t&e newl added )alues of /able@1 to /able@$
<or /able@$ we will use t&e following structure ,
/&en we create t&e trigger ,
create trigger trg@Imen$
on /able@1
for insert
as
begin
declare _name )arc&ar(133! 22)ariable for name
declare _col1 decimal(1$,H! 22)ariable for col1
select _name B "@name,
_col1B "@col1 from I0S9*/9D
insert into /able@$
)alues (_name,_col1!
end
w&en we e"ecute,
insert into /able@1
)alues (L%A%40L,1H',MC!
%A%40 &as id of 13 and )alue of 1H'.3333 and MC.3333
(1 row(s! affected!
(1 row(s! affected!
/able $ will be ,
Deleted trigger e"ample
create trigger trg@ImenDelete
on /able@1
for delete 22[2we replace insert wit& delete
as
begin
declare _name )arc&ar(133! 22)ariable for name
declare _col1 decimal(1$,H! 22)ariable for col1
select _name B (select "@name from D9L9/9D!,
_col1B (select "@col1 from D9L9/9D!
insert into /able@$
)alues (LD9L9/9D %9%+9* ,L ] _name,_col1!
end
2222update
create trigger trg@Imen8pdate
on /able@1
for update 222[we use 8>DA/9 to because t&is trigger is for update
as
begin
declare _name )arc&ar(133! 22)ariable for name
declare _col1 decimal(1$,H! 22)ariable for col1
select _name B "@name,
_col1B "@col1 from I0S9*/9D 22we use I0S9*/9D because in t&is table, all updated data will be sa)ed
insert into /able@$
)alues (L8>DA/9D L ] _name,_col1!
end
/pes of /riggers
Data %anipulation Language (D%L! trigger
29"ecutes w&en I0S9*/, 8>DA/9, and D9L9/9 commands modif data in a table or )iew.
Data Definition Language (DDL! trigger
29"ecutes in response to a DDL statement t&at is often used to make database sc&ema c&anges.
9"amples include t&e ?*9A/9, AL/9*, and D*4> statements.
9"ample ,
create trigger tgr?ake
on
tbl@?ake
for insert
as
declare _name )arc&ar(163!
select _name B (select ck@name from inserted!
print Lt&e cake is L ] _name(
222222anot&er e"ample
drop trigger tgr?ake
go
create trigger tgr?ake
on
tbl@?ake
for insert
as
declare _name )arc&ar(163!,_prc decimal(1$,H!,_ck int
select _name B (select ck@name from inserted!,_prc B (select ck@prc from inserted!,_ck B (select
ck@id from inserted!
insert into tbl@<oodies (fd@name,fd@prc,ck@id!
)alues (_name,_prc,_ck!
222222anot&er e"ample using delete
drop trigger tgr?akeDel
go
create trigger tgr?akeDel
on
tbl@?ake
for delete
as
declare _ck int
select _ck B (select ck@id from deleted!
delete from tbl@<oodies
w&ere ck@id B _ck
Stored >rocedure
A stored procedure is a set of /ransact2SQL (/2SQL! statements t&at is compiled and stored
as a single database ob-ect for later repetiti)e use. It is t&e e#ui)alent of a subroutine and
a function in ot&er programming languages.
Anatomy of a Stored Procedure
We can describe a stored procedure in terms of
?omposition
<unctionalit
Snta"
Composition
Logicall, a stored procedure consists of
A header t&at defines t&e name of t&e stored procedure, t&e input and output
parameters, and some miscellaneous processing options. :ou can t&ink of it as an A>I
(application programming interface! or declaration of t&e stored procedure.
A body t&at contains one or more /ransact2SQL statements to be e"ecuted at
runtime.
Creating Stored +rocedures
LetLs look at t&e simplified snta" for implementing t&e core functionalit of stored
procedures,
?*9A/9 >*4?9D8*9 procedure_name
D X@parameter data_typeY DB defaultE D48/>8/E E D,...nE
AS
sql_statement [...n]
/&e following is an e"ample of a stored procedure,
?reate >rocedure ap@9#uipment@Get
_c&)%ake )arc&ar(63!
As
begin
Select P
from dbo.9#uipment
w&ere %ake B _c&)%ake
end
/&is /ransact2SQL statement creates a stored procedure named ap@9#uipment@Get wit&
one input parameter. During e"ecution, ap@9#uipment@Get returns a result set containing
all records from t&e 9#uipment table &a)ing a %ake column e#ual to t&e input parameter.
If ou tr to create a stored procedure t&at alread e"ists in t&e database, SQL Ser)er will
report an error. :ou can reproduce suc& an error if ou run t&e same statement for creating
a stored procedure twice. <or e"ample,
%sg $O1H, Le)el 1M, State ', >rocedure ap@9#uipment@Get, Line H
/&ere is alread an ob-ect named Lap@9#uipment@GetL in t&e database.
4ne wa to c&ange a stored procedure is to drop and re2create it. /&ere are two was to pre)ent t&e error
-ust described. 4ne wa is to use an Alter >rocedure statement to c&ange t&e stored procedure. /&e
traditional wa to pre)ent t&is error is to delete a stored procedure (using t&e Drop >rocedure statement! and
t&en create it again,
,rop +rocedure ap_E-uipment.yE-(ypeI,_!et
go
Create +rocedure ap_E-uipment.yE-(ypeI,_!et
_int9#/peId int
as
Select P
from 9#uipment
w&ere 9#/peId B _int9#/peId
G4
If ou are not sure w&et&er a stored procedure e"ists, ou can write a piece of code to
c&eck for its e"istence. If ou do not, SQL Ser)er will report an error w&en ou tr to drop
a stored procedure t&at does not e"ist. /&is code takes ad)antage of t&e fact t&at SQL
Ser)er records eac& database ob-ect in ss.ob-ects sstem )iew.
if e"ists (select P from ss.ob-ects w&ere ob-ect@id B ob-ect@id(0LDdboE.
Dap@9#uipment+9#/peID@GetEL!
and tpe in (0L>L, 0L>?LYY
D*4> >*4?9D8*9 ap@9#uipment+9#/peID@Get
G4
?*9A/9 >*4?9D8*9 ap@9#uipment+9#/peID@Get
_int9#/peId int
AS
Select P from 9#uipment
w&ere 9#/peId B _int9#/peId
G4
It could also be written as ,
I< ob-ect@id(Lap@9#uipment+9#/peID@GetL! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it
e"ists, we delete it
+egin
drop >*4?9D8*9 ap@9#uipment+9#/peID@Get
end
Example :
create procedure pr@Get@0ame
_name )arc&ar(1333! 22parameter
as
begin
select P from /able@1
w&ere "@name B _name
end
22to e"ecute t&e procedure,
e"ec pr@Get@0ame L]L [2 \]. is our parameter
results:
*ltering Stored +rocedures
/&e ot&er wa to c&ange a stored procedure is to use t&e Alter >rocedure statement,
*lter +rocedure ap_E-uipment_!et
_c&)%ake )arc&ar(63!
as
Select P
from 9#uipment
w&ere %ake B _c&)%ake
go
/&e snta" of t&is statement is identical to t&e snta" of t&e ?reate >rocedure statement
(e"cept for t&e keword!. /&e main reason for using t&is statement is to a)oid undesirable
effects on permissions and dependent database ob-ects.
/&e Alter >rocedure statement preser)es all aspects of t&e original stored procedure. /&e
ob-ect identification number (id column! of t&e procedure from t&e ss.ob-ects sstem )iew
remains t&e same, and all references to t&e stored procedure are intact. /&erefore, it is
muc& better to use t&e Alter >rocedure statement t&an to drop and re2create t&e
procedure.
Limits
W&en ou are creating or c&anging a stored procedure, ou s&ould keep in mind t&e
following limits,
/&e name of t&e procedure is a standard /ransact2SQL identifier. /&e ma"imum
lengt& of an identifier is 1$N c&aracters.
Stored procedures ma contain up to $,133 input and output parameters.
/&e bod of t&e stored procedure consists of one or more /ransact2SQL statements.
/&e ma"imum si5e of t&e bod of t&e stored procedure is 1$N%+.
"unctionality
Stored procedures can be used to
*eturn information to t&e caller
%odif data in databases
Implement business logic in data tier
?ontrol access to data
Impro)e performance of t&e sstem
*educe network traffic
>erform ot&er actions and operations (suc& as process e2mail, e"ecute operating
sstem commands and processes, and manage ot&er SQL Ser)er ob-ects!
/&ere are four was to recei)e information from a stored procedure,
*eturning result sets
8sing input and output parameters
8sing return )alues
Global cursor
/&e first t&ree will be e"plained in t&is c&apter, w&ile t&e fourt& one will be skipped as not
recommended.
$eturning $esult Sets
/o obtain a result set from a stored procedure, insert a /ransact2SQL statement t&at
returns a result set into t&e bod of t&e stored procedure. /&e simplest wa is b using a
Select statement, but ou could also call anot&er stored procedure.
It is also possible to return se)eral result sets from one stored procedure. Suc& a stored
procedure will simpl contain se)eral Select statements. :ou s&ould note t&at some client
data2access met&ods (suc& as AD4.09/! can access all result sets, but ot&ers will recei)e
-ust t&e first one or possibl e)en report an error.
/sing Input and #utput +arameters
LetLs add a new procedure to t&e Asset6 database,
?reate procedure ap@9#Id+%ake%odel@List
_c&)%ake )arc&ar(63!,
_c&)%odel )arc&ar(63!
as
select 9#Id
from 9#uipment
w&ere %ake B _c&)%ake
and %odel B _c&)%odel
G4
/&is is a )er simple stored procedure. It uses two input parameters to recei)e t&e make
and model, and returns identifiers of e#uipment t&at matc&es t&e specified make and
model.
>&sicall, t&e stored procedure encapsulates -ust one Select statement. /&e &eader and
bod of t&e procedure are di)ided b t&e keword As. /&e &eader of t&e stored procedure
contains a list of parameters delimited wit& a comma (,! c&aracter. 9ac& parameter is
defined wit& an identifier and a data tpe. >arameter identifiers must begin wit& t&e at sign
(_!.
:ou can use t&e following statement to e"ecute t&e stored procedure,
9"ecute ap@9#Id+%ake%odel@List L/os&ibaL, L>ortege O3$3?/L
/&e keword 9"ecute is followed b t&e name of t&e stored procedure. Since t&e stored
procedure re#uires two parameters, t&e are pro)ided in t&e form of a comma2delimited
list. In t&is case t&e are strings, so t&e must be delimited wit& single #uotation marks.
/&e keword 9"ecute is not needed if t&e stored procedure is e"ecuted in t&e first
statement of a batc&,
ap@9#Id+%ake%odel@List L/os&ibaL, L>ortege O3$3?/L
Aowe)er, I recommend ou use it. It is a good &abit t&at leads to clean code. :ou can use
its s&orter )ersion (9"ec! to sa)e kestrokes,
9"ec ap@9#Id+%ake%odel@List L/os&ibaL, L>ortege O3$3?/L
In an case, t&e e"ecution will return a result set containing -ust one )alue in one record,
9#uipmentId
22222222222
1
(1 row(s! affected!
9"ample,
create procedure pr@Get@0ame
_name )arc&ar(1333! 22parameter
as
begin
select "@id,"@name from /able@1
w&ere "@name B _name
end
22if we e"ecute,
e"ec pr@Get@0ame L>4F9%40L
it will return,
22if we tr to return onl 1 column t&en,
drop procedure pr@Get@0ame
go
create procedure pr@Get@0ame
_name )arc&ar(1333! 22parameter
as
begin
select "@name from /able@1
w&ere "@name B _name
end
22and e"ecute it,
e"ec pr@Get@0ame L>4F9%40L
22we get,
Stored procedures can return output parameters to t&e caller. /o illustrate, we will create a
stored procedure similar to t&e pre)ious one, but &a)ing one critical difference, /&is new
stored procedure contains an additional parameter. /&e direction of t&e parameter is
controlled b including t&e keword 4utput after t&e data tpe,
?reate procedure ap@9#Id+%ake%odel@List@$
_c&)%ake )arc&ar(63!,
_c&)%odel )arc&ar(63!,
0intE-Id int output
as
select 0intE-Id 1 E-uipmentId
from 9#uipment
w&ere %ake B _c&)%ake
and %odel B _c&)%odel
/&e Select statement does not return a result set, as t&e pre)ious one did. Instead, it
assigns an output parameter, _9#Id, wit& t&e selected )alue.
In t&is case, we re#uire a more complicated batc& of /ransact2SQL statements to e"ecute
t&e stored procedure. We must define t&e )ariable t&at will recei)e t&e output )alue. /&e
parameter must be followed b t&e 4utput keword to indicate t&at a )alue for t&e
parameter will be returned b t&e procedure. At t&e end of t&e batc&, t&e result of t&e
stored procedure is displaed using t&e Select statement,
Declare _int9#Id int
9"ecute ap@9#Id+%ake%odel@List@$ L/os&ibaL,
L>ortege O3$3?/L,
0intE-Id #/(+/(
Select _int9#Id L9#uipment IdentifierL
/&e batc& returns t&e )alue of t&e )ariable as an output parameter,
9#uipment Identifier
22222222222222222222
1
9"ample using output parameter ,
create procedure pr@Get@ID
_name )arc&ar(1333!, 22parameter
_id int 48/>8/
as
begin
select _id B "@id from /able@1
w&ere "@name B _name
end
222222222222222222222222222222222222222222222222
22in order to use our output parameter, we must declare a )ariable to store t&e )alue from 48/>8/ )ariable
declare _IDI int 22 declare our )ariable for storing )alue
e"ec pr@Get@ID L%A%40L, _IDI 48/>8/ 22 we use _IDI to store t&e )alue of our 48/>8/ )ar
select _IDI 22 return t&e )alue of our _IDI
t&e output will be,
/sing $eturn 2alues
An alternati)e wa to send )alues from a stored procedure to t&e caller is to use a return
alue. 9ac& stored procedure can end wit& a *eturn statement. /&e statement can be
followed b an integer )alue t&at can be read b t&e caller. If t&e return )alue is not
e"plicitl set, t&e ser)er will return t&e default )alue, 5ero (3!.
+ecause return )alues are limited to int data tpes, t&e are most often used to signal an
error status or error code to t&e caller. We will e"amine t&is use later. <irst, letLs e"plore its
functionalit in some unort&odo" e"amples.
In t&e following e"ample, t&e )alue returned b t&e procedure will be assigned to t&e local
)ariable and finall returned to t&e caller,
?reate >rocedure ap@9#Id+%ake%odel@List@'
_c&)%ake )arc&ar(63!,
_c&)%odel )arc&ar(63!
as
,eclare 0intE-Id int
Select 0intE-Id 1 E-uipmentId
from 9#uipment
w&ere %ake B _c&)%ake
and %odel B _c&)%odel
$eturn 0intE-Id
/&e same functionalit could be ac&ie)ed e)en wit&out a local )ariable, since a *eturn
statement can accept an integer e"pression instead of an integer )alue,
?reate >rocedure ap@9#Id+%ake%odel@List@H
_c&)%ake )arc&ar(63!,
_c&)%odel )arc&ar(63!
as
*eturn (select 9#Id
from dbo.9#uipment
w&ere %ake B _c&)%ake
and %odel B _c&)%odel!
/o e"ecute t&e stored procedure and access t&e returned )alue, we re#uire t&e following
lines of code,
Declare _int9#Id int
Execute 0intE-Id B ap@9#Id+%ake%odel@List@' L/os&ibaL, L>ortege O3$3?/L
Select _int9#Id L9#uipment IdentifierL
0otice t&e difference in assigning a )alue. /&e local )ariable must be inserted before t&e
name of t&e stored procedure. /&e result of t&e batc& is t&e returned )alue,
9#uipment Identifier
22222222222222222222
1
(1 row(s! affected!
/&is solution, &owe)er, is not a perfect wa to transfer information from a stored procedure
to a caller. In t&e first place, it is limited b data tpe. 4nl integers can be returned t&is
wa (including int, smallint, and tinint!. /&is met&od was often used in old )ersions of SQL
Ser)er to return status information to t&e caller,
?reate >rocedure dbo.ap@9#Id+%ake%odel@List@6
_c&)%ake )arc&ar(63!,
_c&)%odel )arc&ar(63!,
_int9#Id int output
as
select _int9#Id B 9#Id
from dbo.9#uipment
w&ere %ake B _c&)%ake
and %odel B _c&)%odel
$eturn 00error
In t&is e"ample, t&e stored procedure will potentiall return an error code. __error is a
scalar function t&at contains an error number in t&e case of failure or a 5ero in t&e case of
success. /o e"ecute t&e stored procedure, use t&e following code,
Declare _int9#Id int,
_int9rror?ode int
9"ecute _int9rror?ode B dbo.ap@9#Id+%ake%odel@List@6
L/os&ibaL,
L>ortege O3$3?/L,
_int9#Id output
Select _int9#Id result, _int9rror?ode 9rror?ode
/&e result will look like t&is,
result 9rror?ode
22222222222 2222222222
1 3
(1 row(s! affected!
An 9rror?ode of 3 indicates t&e stored procedure was e"ecuted successfull wit&out errors.
9"amples for return ,
22<irst we tr an e"ample t&at will return t&e total numbers of rows found in t&e /able@1
drop procedure pr@Get@/otal*ows
go
create procedure pr@Get@/otal*ows
as
begin

return (select count("@id! from /able@1!
end
22if we e"ecute it, we need to declare a )aribale to &old t&e )alue of our return )alue,
declare _int int 22_int will &old our return for int
e"ecute _int B pr@Get@/otal*ows
select _int
it will output,
0e"t e"ample we will use __rowcount, __rowcount returns t&e number of affacted rows from t&e pre)ious
s#l statement
drop procedure pr@Get@/otal*ows$
go
create procedure pr@Get@/otal*ows$
as
begin
declare _row int
declare _)al int

select _)al B "@id from /able@1 [2w& did we use _)al; _)al is used in order to &ide 22t&e results
obtained from t&e select statement, if t&is is not used, our stored procedure 22will return $ results
set _row B __rowcount [2 return t&e result of our select statement
return _row
end
to e"ecute t&e command we use,
declare _int int
e"ecute _int B pr@Get@/otal*ows$
select _int
it will return,
,e)ault 2alues
If t&e stored procedure statement &as parameters, ou must suppl )alues for t&e
parameters in our 9"ec statement. If a user fails to suppl t&em, t&e ser)er reports an
error. It is possible, &owe)er, to assign default )alues to t&e parameters so t&at t&e user is
not re#uired to suppl t&em. Default )alues are defined at t&e end of a parameter
definition, be&ind t&e data tpes. All t&at is needed is an assignment (B! and a )alue,
create >rocedure dbo.ap@9#Id+%ake%odel@List@M
0ch34a5e 3archar67'8 1 9:9, ch34odel 3archar67'8 1 9:9
as
Select P
from 9#uipment
w&ere %ake Like _c&)%ake
and %odel Like _c&)%odel
/&e procedure is designed as a small searc& engine t&at accepts /2SQL wild cards. :ou can
e"ecute t&is stored procedure wit& normal )alues,
9"ecute ap@9#Id+%ake%odel@List@M L/WL , L>ortegeWL
/&e result set will consist of records t&at matc& t&e criteria,
9#Id %ake %odel 9#/peId
22222222222 22222222222222222222 22222222222222222222 22222222
1 /os&iba >ortege O3$3?/ 1
'H /os&iba >ortege O3$1?/ 1
($ row(s! affected!
If one parameter is omitted, as follows, t&e procedure will be&a)e, since t&e )alue t&at was
defined as a default &as been supplied,
9"ecute ap@9#Id+%ake%odel@List@M L/WL
/&e ser)er will return t&e following result set,
9#Id %ake %odel 9#/peId
22222222222 222222222222222222222 2222222222222222222 22222222
1 /os&iba >ortege O3$3?/ 1
'H /os&iba >ortege O3$1?/ 1
($ row(s! affected!
9)en bot& parameters ma be skipped,
9"ecute ap@9#Id+%ake%odel@List@M
/&e ser)er will return all records t&at matc& t&e default criteria,
9#Id %ake %odel 9#/peId
222222222222 22222222222222222222 222222222222222222 22222222
1 /os&iba >ortege O3$3?/ 1
$ Son /rinitron 1OI9 '
...
+assing +arameters by ame
:ou do not &a)e to follow parameter order if ou pass parameters b name. :ou must tpe
t&e name of t&e parameter and t&en assign a )alue to it. /&e parameter name must matc&
its definition, including t&e _ sign.
/&is met&od is sometimes called passing parameters by name. /&e original met&od can be
referred to as passing parameters by position. In t&e following e"ample, t&e ser)er will use
/W for t&e second parameter and a default )alue, W, for t&e first one,
9"ecute ap@9#Id+%ake%odel@List@M _%odel B L/WL
/&e result of t&e searc& will be t&e following,
9#Id %ake %odel 9#/peId
22222222222 222222222222222222 2222222222222222222222222222 2222222
HHC ?ompa# /> D/ A?%S ALL L>S >ers 8se '
N66 ?ompa# /> D/ +?%S ALL L>S >ers 8se '
...
/&e opportunit to skip parameters is -ust one reason for passing parameters b name.
9)en more important is t&e opportunit to create a met&od t&at makes code more readable
and maintainable. And, if a de)eloper makes a mistake and assigns a )alue to a
none"istent parameter, t&e error will be picked up b SQL Ser)er.
/i
p
Alt&oug& passing parameters b position can &e a little faster, passing parameters b
name is preferable.
Types of Stored Procedures
/&ere are man tpes of stored procedures,
1. 8ser2defined
$. Sstem
'. 9"tended
H. /emporar
6. Global temporar
M. *emote
O. ?L*
/&ere are also database ob-ects, w&ic& are )er similar in nature,
/riggers
=iews
8ser2defined functions
As ou can infer from t&e name, user!defined stored procedures are simpl plain, stored
procedures assembled b administrators or de)elopers for later use.
Stored procedures e"amples
We will use t&e following table structure,
<irst we will create a stored procedure t&at will return all records from t&e gi)en table ,
?reate procedure pr@Get9mploee
AS
+egin
Select P from tbl@9mploee
end
We will e"ecute t&e command,
e"ec pr@Get9mploee
It will return ,
0e"t we will en&ance t&e gi)en e"ample and use a parameter, t&is parameter will be called _intID, take note
we use _ smbol to denote t&at t&is will be our )ariable for our /2SQL
I< ob-ect@id(Lpr@Get9mploeeL! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it e"ists,
we delete it
begin
drop >*4?9D8*9 pr@Get9mploee
end
go 22 we use go to indicate t&at we will e"ecutre t&e ne"t line of code
?reate procedure pr@Get9mploee
_intId int 22declare our integer parameter (I0>8/!
AS
+egin
Select P from tbl@9mploee
w&ere ID B _intId
end
We e"ecute it using,
e"ec pr@Get9mploee $ 22 we use $ to set )alue for our parameter
/&e output will be,
0e"t we will use $ parameters t&is time, an int and )arc&ar parameter, if t&e int parameter is greater t&an
5ero, we will use it but if not, we will use t&e )alue in t&e string parameter to find t&e data in t&e w&ere
clause.
I< ob-ect@id(Lpr@Get9mploeeL! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it e"ists,
we delete it
begin
drop >*4?9D8*9 pr@Get9mploee
end
go 22 we use go to indicate t&at we will e"ecutre t&e ne"t line of code
?reate procedure pr@Get9mploee
_intId int,_nme )arc&ar(633! 22declare our integer and )arc&ar parameter
AS
+egin
if _intId T 3 22if int is greater t&an 5ero
begin
Select P from tbl@9mploee
w&ere ID B _intId
end
else 22 if int is 5ero we will use our string7)arc&ar )alue
begin
select P from tbl@9mploee
w&ere 0A%9@ like _nme
end
end
we will tr to e"ecute t&e following,
e"ec pr@Get9mploee ',LL 22 we use ' to set )alue for our int parameter and LL as )alue for our name
it will output,
e"ec pr@Get9mploee 3,L%IF9L 22 we use %IF9 to set )alue for our name
will result to
Adding DA/A using stored procedure
I< ob-ect@id(Lpr@9mploeeAddL! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it e"ists,
we delete it
begin
drop >*4?9D8*9 pr@9mploeeAdd
end
go 22 we use go to indicate t&at we will e"ecutre t&e ne"t line of code
?reate procedure pr@9mploeeAdd
_nme )arc&ar(633!,_amt decimal(1$,H!,_bonus decimal(1$,H!
AS
+egin
insert into tbl@9mploee
)alues (_nme,_amt,_bonus!
end
if we e"ecute it ,
e"ec pr@9mploeeAdd LD4/9`L,1H'.HH,MC.CM
it will return,
Impro)ing t&e code, w&at if we want to c&eck if user alread e"ists. W&at we can do is update t&e data if user
alread e"ists.
I< ob-ect@id(Lpr@9mploeeAddL! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it e"ists,
we delete it
begin
drop >*4?9D8*9 pr@9mploeeAdd
end
go 22 we use go to indicate t&at we will e"ecutre t&e ne"t line of code
?reate procedure pr@9mploeeAdd
_nme )arc&ar(633!,_amt decimal(1$,H!,_bonus decimal(1$,H!
AS
+egin
declare _intID int 22 declare intID for passing )alues
select _intID B ID 22 searc&es for ID of e"isting name
from tbl@9mploee
w&ere 0A%9@ B _nme
if _intID T 3 22 if ID e"ists, 8>DA/ else I0S9*/
begin
update tbl@9mploee set 0A%9@ B _nme, SALA*: B _amt,
+408S B _bonus
w&ere ID B _intID
end
else
begin
insert into tbl@9mploee
)alues (_nme,_amt,_bonus!
end
end
we will e"ecute using ,
e"ec pr@9mploeeAdd L>4/4:L,1H'.HH,OO.OO
22note t&at if users e"ists, it will update, if not it will insert t&e emploee
/o furt&er impro)e t&e code, we will use __rowcount w&ic& returns t&e mnumber of affacted rows per SQL
statement(
I< ob-ect@id(Lpr@9mploeeAdd$L! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it
e"ists, we delete it
begin
drop >*4?9D8*9 pr@9mploeeAdd$
end
go 22 we use go to indicate t&at we will e"ecutre t&e ne"t line of code
?reate procedure pr@9mploeeAdd$
_nme )arc&ar(633!,_amt decimal(1$,H!,_bonus decimal(1$,H!
AS
+egin
declare _intID int 22 declare intID for passing )alues
select _intID B ID 22 searc&es for ID of e"isting name
from tbl@9mploee
w&ere 0A%9@ B _nme
if __*4W?480/ T 3 22 if ID e"ists, 8>DA/ else I0S9*/
22__rowcount is used to return t&e number of rows affected
22from t&e pre)ious command
begin
update tbl@9mploee set SALA*: B _amt,
+408S B _bonus
w&ere 0A%9@ B _nme
end
else
begin
insert into tbl@9mploee
)alues (_nme,_amt,_bonus!
end
end
to e"ecute ,
e"ec pr@9mploeeAdd$ L>4/4:L,$6M.C6,ON.NO
to delete data from tbl@9mploee, we will use _id to delete b id, and _nme to delete b name
I< ob-ect@id(Lpr@9mploeeDelL! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it e"ists,
we delete it
begin
drop >*4?9D8*9 pr@9mploeeDel
end
go 22 we use go to indicate t&at we will e"ecutre t&e ne"t line of code
?reate procedure pr@9mploeeDel
_nme )arc&ar(633!,_id int
AS
+egin

if _id T 3 22 if ID e"ists,
begin
delete from tbl@9mploee
w&ere ID B _id
end
else
begin
delete from tbl@9mploee
w&ere 0A%9@ B _nme
end
end
/o create a stored procedure t&at can do all operations, t&is is an e"ample
I< ob-ect@id(Lpr@9mploee4ptL! is not null 22 we c&eck if t&eres an ob-ect called pr@Get9emploee, if it e"ists,
we delete it
begin
drop >*4?9D8*9 pr@9mploee4pt
end
go 22 we use go to indicate t&at we will e"ecutre t&e ne"t line of code
?reate procedure pr@9mploee4pt
_opt int,_nme )arc&ar(633!,_sal decimal(1$,H!,_bonus decimal(1$,H!,_id int
AS
+egin

if _opt B 1
begin
insert into tbl@emploee
)alues (_nme,_sal,_bonus!
end
if _opt B $
begin
update tbl@emploee
set 0A%9@ B _nme, SALA*: B _sal, +408S B _bonus
w&ere ID B _id
end
if _opt B '
begin
delete from tbl@9mploee
w&ere ID B _id
end
if _opt B H
begin
select P from tbl@9mploee
end

end
to e"ecute,
e"ec pr@9mploee4pt 1,L+90I/`L,1H',$3,3
e"ec pr@9mploee4pt $,L+A0G8SL,1H',$3,'
e"ec pr@9mploee4pt ',LL,3,3,'
e"ec pr@9mploee4pt H,LL,3,3,3
<unctions *e)iew and Summar
Alwas remember t&at programming in SQL re#uires ou to pro)ide t&e s&ortest possible code for a specific
problem. Alt&oug& t&ere are numerous was to sol)e a problem or pro)ide t&e output, we must remember
t&at t&e s&ortest means is almost alwas t&e best approac&.
Substring, Left and *ig&t
o /&e substring can be interc&anged wit& left or rig&t. Aowe)er remember t&is rule, use substring to
get results from t&e middle of t&e string. Somet&ing t&at will be &ard if we are onl to use left or
rig&t. And use t&e functions left or rig&t to get strings found in t&e left or rig&t part.
9",
/&e string J%A%A%40D9K lets sa is stored in column 0A%9@ in tbl@<ood.
<irst we e"tract t&e world J%A%40K, w&ic& is best to use; substring, because t&e word is located in t&e
middle.
Solution,
select substring(0A%9@,',6! from tbl@<ood
select substring(J%A%A%40D9K,',6!
<irst we tell w&at column or string we will use. 0e"t indicate t&e starting inde", we start using 1 w&ic&
will represent t&e first letter, in t&is case t&e start of % for %A%40 is found in t&e '
rd
c&aracter, t&en
we tell &ow man c&aracters we will e"tract. %A%40 &as 6 c&aracters so we e"tract 6.
4utput, %A%40
0e"t problem get t&e world J%A%AK and J%40D9. We can sol)e it using left and rig&t or substring.
Aowe)er, left and rig&t re#uires onl $ parameters unlike substring w&ic& uses ' parameters. So we
use left and rig&t
Solution,
select left(0A%9@,H! from tbl@<ood
select left(J%A%A%40D9K,H!
select rig&t(0A%9@,6! from tbl@<ood
select rig&t(J%A%A%40D9K,6!
In using left or rig&t, first we pro)ide t&e column name or string, t&en t&e ne"t parameter represents
&ow man c&aracters we are e"tracting.
4utput,
%A%A [using left
%40D9 [ using rig&t
cast and con)ert
o /&e issue is w&at is t&e best con)ersion function, cast or con)ert. ?on)ert is a SQL ser)er onl
function and ?ast is more generic(can be used in ot&er dbms or database management!. ?on)ert pro)ides
more fle"ibilit t&an ?ast because it supports specific formatting to data. So if ou are tring to c&oose w&ic&
one to use, I would suggest ?ast unless ou &a)e a specific reason to use ?on)ert. As a suggestion,
Dates, time , ?on)ert
Decimals, numeric , ?ast
9",
We will con)ert t&e number '.$6 into string and append t&e word JAiK.
8sing cast,
select LAi L ] cast('.$6 as )arc&ar(63!!
4utput,
Ai '.$6
8sing con)ert,
select LAi L ] con)ert()arc&ar(63!, '.$6!
4utput,
Ai '.$6
?on)ert e"amples,
?40=9*/(=A*?AA*(1C!,G9/DA/9(!!
?40=9*/(=A*?AA*(13!,G9/DA/9(!,13!
?40=9*/(=A*?AA*(13!,G9/DA/9(!,113!
?40=9*/(=A*?AA*(11!,G9/DA/9(!,M!
?40=9*/(=A*?AA*(11!,G9/DA/9(!,13M!
?40=9*/(=A*?AA*($H!,G9/DA/9(!,11'!
4utput,
0o) 3H $311 11,H6 >%
1123H211
1123H2$311
3H 0o) 11
3H 0o) $311
3H 0o) $311 11,H6,'H,$H'
/&e table below represent t&e stle )alues for datetime or smalldatetime con)ersion to c&aracter data,
2alue
6century yy8
2alue
6century yyyy8
Input;#utput Standard
2 3 or 133 mon dd &&,miA% (or >%! Default
1 131 mm7dd7 8SA
$ 13$ .mm.dd A0SI
' 13' dd7mm7 +ritis&7<renc&
H 13H dd.mm. German
6 136 dd2mm2 Italian
M 13M dd mon
O 13O %on dd,
N 13N &&,mm,ss
2 C or 13C mon dd &&,mi,ss,mmmA% (or >%! Default]millisec
13 113 mm2dd2 8SA
11 111 7mm7dd Qapan
1$ 11$ mmdd IS4
2 1' or 11' dd mon &&,mi,ss,mmm ($H&!
1H 11H &&,mi,ss,mmm ($H&!
2 $3 or 1$3 2mm2dd &&,mi,ss ($H&!
2 $1 or 1$1 2mm2dd &&,mi,ss.mmm ($H&!
2 1$M 2mm2dd/&&,mi,ss.mmm (no spaces! IS4NM31
2 1'3 dd mon &&,mi,ss,mmmA% Ai-iri
2 1'1 dd7mm7 &&,mi,ss,mmmA% Ai-iri
"oops
Looping structures allow a single command, or a group of statements, to be e"ecuted repeatedl. W&en using t&e /2SQL
WAIL9 loop, a +oolean condition is c&ecked e)er time t&e code wit&in t&e loop is about to start. If t&e condition is true,
t&e loop is e"ecuted. If not, control passes to t&e statement following t&e loop.
WAIL9 loops are commonl used wit& cursors to process a set of data one row at a time.
#sing $%&"' "oops
/&e snta" for creating a w&ile loop is as follows,
WAIL9 condition statement
/&is snta" is t&e same as t&e basic snta" for t&e I< statement .
/&e condition element specifies a )alue, )ariable or e"pression t&at e)aluates as
eit&er true or false. If t&e )alue is true, t&e statement part of t&e command is
e"ecuted. 4nce completed, t&e condition is c&ecked again and t&e process
continues until t&e condition is false. (a)e note that the statement element can
contain multiple commands if they appear bet*een +',&- and '-. commands.
/&e following script declares a )ariable and initialises its )alue to 5ero. /&e loopLs
condition specifies t&at t&e contained statements will be e"ecuted w&ilst t&e
)ariableLs )alue is less t&an or e#ual to ten. Wit&in t&e loop, t&e )ariableLs )alue
is incremented and printed. /&e end result is t&at t&e integers between one and
ten are outputted.
D9?LA*9 _Iteration I0/
S9/ _Iteration B 3
WAIL9 _Iteration SB 13
+9GI0
S9/ _Iteration B _Iteration ] 1
>*I0/ _Iteration
90D
4utput,
1
$
'
H
6
M
O
N
C
13
11
9"iting a Loop 9"plicitl
Sometimes ou will wis& to terminate a loop e)en w&en t&e condition part is
true. /&is can be ac&ie)ed using t&e +/'A0 command. /&is command specifies
t&at t&e control s&ould pass to t&e command immediatel following t&e current
loop.
In t&e following sample script, t&e loop is calculating t&e s#uares of t&e )alues
between one and ninet2nine. /&e I< statement c&ecks to see if t&e result of t&e
s#uare is greater t&an one t&ousand.
D9?LA*9 _/oS#uare I0/
D9?LA*9 _S#uare I0/
S9/ _/oS#uare B 3
WAIL9 _/oS#uare S 13
+9GI0
S9/ _/oS#uare B _/oS#uare ] 1
S9/ _S#uare B _/oS#uare P _/oS#uare
I< _S#uare T $33
+*9AF
>*I0/ _S#uare
90D
4utput,
1
H
C
1M
$6
'M
HC
MH
N1
133
restarting a Loop
If ou wis& to terminate a single iteration of a loop ou can use
t&e 12-(&-#' command. /&is command immediatel stops t&e current iteration
and rec&ecks t&e loopLs condition. If t&e condition is still true, t&e loop is
restarted. In t&e ne"t e"ample t&e ?40/I089 statement and +*9AF statement
are combined so t&at t&e s#uares t&at are between one &undred and one
t&ousand are outputted.
D9?LA*9 _/oS#uare I0/
D9?LA*9 _S#uare I0/
S9/ _/oS#uare B 3
WAIL9 _/oS#uare S 133
+9GI0
S9/ _/oS#uare B _/oS#uare ] 1
S9/ _S#uare B _/oS#uare P _/oS#uare
I< _S#uare S 133
?40/I089
I< _S#uare T $33
+*9AF
>*I0/ _S#uare
90D
4utput,
133
1$1
1HH
1MC
1CM
0esting
Loops can be nested to pro)ide more comple" looping structures. W&en nesting
loops, +*9AF and ?40/I089 commands affect onl t&e loop t&at t&e appear
wit&in. ie. w&en breaking out of an inner loop, control passes to t&e ne"t
statement after t&e inner loop, w&ic& will be wit&in t&e outer loop.
In t&e following e"ample one loop is nested wit&in anot&er to output t&e
multiplication tables for t&e numbers 1 to '.
D9?LA*9 _=al1 I0/
D9?LA*9 _=al$ I0/
S9/ _=al1 B 1
WAIL9 _=al1 SB '
+9GI0
S9/ _=al$ B 1
WAIL9 _=al$ SB '
+9GI0
>*I0/ ?40=9*/(=A*?AA*, _=al1! ] L P L ] ?40=9*/(=A*?AA*, _=al$!
] L B L ] ?40=9*/(=A*?AA*, _=al1 P _=al$!
S9/ _=al$ B _=al$ ] 1
90D
S9/ _=al1 B _=al1 ] 1
90D
4utput,
1 P 1 B 1
1 P $ B $
1 P ' B '
$ P 1 B $
$ P $ B H
$ P ' B M
' P 1 B '
' P $ B M
' P ' B C
SQL Ser)er ?ursors
A cursor is a database ob-ect t&at permits t&e data set generated b a #uer to be processed one row at a time. /&e
cursor pro)ides a pointer to a single row and allows t&e information in t&at row to be e"tracted and processed. 4nce t&at
processing is complete, t&e cursor can be mo)ed to anot&er row. /&is allows row2b2row processing t&at ma be difficult
to accomplis& using ot&er tec&ni#ues.
?ommonl a cursor is combined wit& a WAIL9 loop to enable row2b2row processing of an entire data set. In suc& cases,
t&e WAIL9 loop uses a cursor status function to determine w&et&er t&e end of t&e data &as been reac&ed. If it &as, t&e
loop e"its. If not, t&e ne"t row is retrie)ed, or fetched, from t&e cursor and t&e loop restarts.
?onsiderations
Some de)elopers and database administrators dislike database cursors. /&is is because cursors use resources w&ilst t&e
are open and read data from t&e database eac& time a new row is fetc&ed. /&is can increase network traffic, lower t&e
a)ailable resources of t&e SQL Ser)er instance and lead to poor performance. Aowe)er, cursors can be useful w&en row2
b2row processing is re#uired, particularl wit&in stored procedures t&at do not return t&e data and so do not generate
e"cessi)e network traffic. As wit& all de)elopment tec&ni#ues, ou s&ould consider all a)ailable options and select t&e
most appropriate for t&e situation.
As a rule, w&ene)er a certain process uses a cursor and takes up a long period of time before e"ecuting, tr to make use
of ot&er looping tec&ni#ues and see if it will impro)e t&e sstem performance.
<irst, we create a )iew w&ic& will create a billing data
?*9A/9 =I9W )w@+illing AS
S9L9?/
Q.QobId,
Q.?ontract0umber,
Q.Duration,
Q.Duration P 9.Aourl*ate AS 9ngineer?ost,
(S9L9?/ IS08LL(S8%(/otal?ost!,3! <*4% 8sed>arts WA9*9 QobId B Q.QobId!
AS >arts?ost
<*4%
Qobs Q
I009* Q4I0
9ngineers 9
40
Q.9ngineerId B 9.9ngineerId
0e"t we declare our cursor using t&e snta",
D9?LA*9 cursor!name ?8*S4* <4* query
D9?LA*9 +illing?ursor ?8*S4*
<4* S9L9?/ QobId, ?ontract0umber, Duration, 9ngineer?ost, >arts?ost
<*4% )w@+illing
4pening a ?ursor
A cursor cannot be used until it &as been opened using t&e 4>90 statement. 4n opening, t&e #uer is e"ecuted and t&e
cursor is populated. /o open t&e billing cursor, use t&e following,
4>90 +illing?ursor
4nce a cursor is opened ou can determine t&e number of rows it &as using t&e __?8*S4*@*4WS function. /&is
function returns t&e number of rows of t&e latest cursor to be opened.
>*I0/ __?8*S4*@*4WS 22 4utputs ^H^
<etc&ing t&e 0e"t Data *ow
/&e cursor declared abo)e is a forward2onl cursor. /&is means t&at it is onl possible to ad)ance t&roug& t&e rows one b
one. It is not possible to -ump to a specific position, skip rows or to re)erse t&roug& t&e data. As suc&, t&ere is onl one
a)ailable command t&at can be used to obtain a row from t&e cursor. /&is command is ^<9/?A 09I/^.
<9/?A 09I/ <*4% +illing?ursor
If ou e"ecute t&is command from SQL Ser)er %anagement Studio ou will see t&e first row of data displaed in t&e
results area. 9ac& subse#uent e"ecution of t&e fetc& returns t&e ne"t row until t&e cursor is e"&austed.
?losing a ?ursor
4nce ou &a)e finis&ed working wit& a cursor it must be closed to free t&e resources associated wit& it and to clear an
locks t&at t&e cursor &as created. /o close t&e cursor, e"ecute t&e following,
?L4S9 +illing?ursor
Deallocating a ?ursor
A closed cursor can be reopened and reused multiple times. /&is is because t&e data structures of t&e cursor are not
released w&en t&e cursor is closed. /o release t&ese structures and destro t&e cursor after closing ou s&ould deallocate
it. /o deallocate t&e sample cursor, e"ecute t&e following,
D9ALL4?A/9 +illing?ursor
*etrie)ing ?ursor Data into =ariables
/&e e"ample abo)e is interesting as it s&ows t&e use of a cursor. Aowe)er, in a real2world situation it would not be
particularl useful. Generall, ou will wis& to fetc& t&e row data into )ariables t&at can t&en be used for furt&er
processing. <or our e"ample we re#uire fi)e )ariables for t&e fi)e columns in t&e #uer. Declare t&e fi)e )ariables as
follows,
D9?LA*9 _QobID 80IQ89ID90/I<I9*
D9?LA*9 _?ontract0umber I0/
D9?LA*9 _Duration D9?I%AL(H,$!
D9?LA*9 _9ngineer?ost %409:
D9?LA*9 _>arts?ost %409:
/o fetc& t&e data from t&e cursor into t&e )ariables, use t&e I0/4 clause. /&is clause is followed b a comma2separated
list of t&e )ariables to be populated. /&e first )ariable will recei)e t&e )alue of t&e first column in t&e #uer, t&e second
from t&e second column and so on. 4ne )ariable must be supplied for eac& of t&e #uerLs columns.
<9/?A 09I/ <*4% +illing?ursor
I0/4 _QobID, _?ontract0umber, _Duration, _9ngineer?ost, _>arts?ost
Looping /&roug& All Data in a ?ursor
?ursors are commonl used wit& WAIL9 loops to process e)er row returned b t&e #uer indi)iduall. /&e first fetc&
operation is performed outside of t&e loop. /&is obtains t&e first row, if one is present, and sets a flag t&at specifies
w&et&er t&e cursor is e"&austed or if furt&er rows are present. /&e flag is accessed using t&e __<9/?A@S/A/8S function.
If t&e fetc& successfull found a row, t&e return )alue will be 5ero. A WAIL9 loop can use t&is function to determine
w&et&er furt&er iterations are re#uired.
/o demonstrate, e"ecute t&e following batc&. /&is loops t&roug& all of t&e billing data. /o simulate t&e integration to t&e
t&ird part sstem, information from eac& row is outputted to t&e %essages window.
D9?LA*9 _QobID 80IQ89ID90/I<I9*
D9?LA*9 _?ontract0umber I0/
D9?LA*9 _Duration D9?I%AL(H,$!
D9?LA*9 _9ngineer?ost %409:
D9?LA*9 _>arts?ost %409:

D9?LA*9 +illing?ursor ?8*S4*
<4* S9L9?/ QobId, ?ontract0umber, Duration, 9ngineer?ost, >arts?ost
<*4% )w@+illing

4>90 +illing?ursor

<9/?A 09I/ <*4% +illing?ursor
I0/4 _QobID, _?ontract0umber, _Duration, _9ngineer?ost, _>arts?ost

WAIL9 __<9/?A@S/A/8S B 3
+9GI0
>*I0/ LSending -ob L ] ?40=9*/(=A*?AA*('M!, _QobID! ] L to billing sstem.L
<9/?A 09I/ <*4% +illing?ursor
I0/4 _QobID, _?ontract0umber, _Duration, _9ngineer?ost, _>arts?ost
90D

?L4S9 +illing?ursor
D9ALL4?A/9 +illing?ursor
Insensiti)e ?ursors
+ default, cursors read eac& row of data from database tables as re#uired, according to t&e #uer t&at is specified. If t&e
data is modified after t&e cursor is opened, t&e modified data will be presented w&en fetc&ed. If a user &as deleted rows,
t&ese will not be accessible )ia t&e cursor. In some situations t&is is undesirable.
An insensitie cursor is not affected b c&anges to t&e underling data. W&en t&e cursor is opened, a temporar table is
created in t&e tempdb database. /&is table is populated wit& t&e results of t&e #uer immediatel. 4nce populated, eac&
fetc& retrie)es information from t&e temporar table, rat&er t&an t&e li)e data.
/o specif t&at a cursor is insensiti)e, add t&e I0S90SI/I=9 clause immediatel after t&e cursor name in t&e declaration.
<or e"ample,
D9?LA*9 +illing?ursor I0S90SI/I=9 ?8*S4*
<4* S9L9?/ QobId, ?ontract0umber, Duration, 9ngineer?ost, >arts?ost
<*4% +illingSstem4utputData
SQL Ser)er /emporar /ables
$hat are (emporary (ables3
(emporary tables are a special tpe of table t&at, as t&e name suggests, are used to &old data temporaril. /&is can be
useful w&en performing )er comple" operations t&at, if e"ecuted against li)e data, could affect performance for ot&er
users or could lock rows for an unacceptable lengt& of time. /emporar tables are often created and populated wit& a cop
of t&e data to be processed. 4nce t&e acti)ities t&at re#uire t&em are completed, t&e are dropped.
/emporar tables can be local or global. A local table is )isible onl to t&e session t&at it is created from and is dropped
automaticall w&en t&e connection is closed. 4t&er users cannot access t&e table, alt&oug& t&e ma create t&eir own
temporar wit& t&e same name. In suc& situations t&e two temporar tables are in no wa linked. ,lobal temporar tables
are a)ailable to all users and are automaticall dropped w&en t&e last user accessing t&e table disconnects from t&e
database. Alt&oug& bot& tpes of table will be automaticall dropped, it is common practice to delete t&em manuall w&en
no longer re#uired.
W&en a temporar table is created, a p&sical table is created in t&e tempdb database. /&is table &as a name t&at is
similar to t&at specified but t&at is modified slig&tl to ensure t&at it is uni#ue. /&is allows two users to apparentl create
temporar tables of t&e same name. W&en information is added to t&e table, it is added to t&e p&sical table in tempdb
and written to disk. /&e performance of a temporar table is, t&erefore, similar to an ot&er table.
#sing (emporary (ables
/o demonstrate t&e use of temporar tables a stored procedure will be used to obtain t&e contract )alue for eac&
customer and t&e total costs of an repair work undertaken. /&e information will be gat&ered from t&e ?ontracts, Qobs,
>arts8sed and 9ngineers tables. 4nce compiled, t&e information will be used to calculate a profit or loss )alue for e)er
customer. /&is information could be e"tracted using a comple" #uer but for demonstration purposes we will use a
temporar table and a cursor.
?reating t&e Stored >rocedure
/&e stored procedure re#uires no parameters as it retrie)es information for all customers wit& no filtering of data. /&e
declaration is t&erefore simple,
?*9A/9 >*4?9D8*9 Get>rofit>er?ustomer AS
Some )ariables are re#uired to temporaril &old t&e customer number, total contract )alue, total cost of engineer time and
total cost of parts used for eac& customer. /&ese s&ould be declared immediatel after t&e pre)ious code, as follows,
D9?LA*9 _?ustomer0umber I0/
D9?LA*9 _/otal?ontract=alue %409:
D9?LA*9 _9ngineer?ost %409:
D9?LA*9 _>arts?ost %409:
?reating t&e /emporar /able
/&e ne"t step in t&e stored procedure is to create t&e temporar table. /&e table will &old t&e contract )alue, costs and
profit for e)er customer. /&is information will be populated in furt&er steps before being selected as t&e procedureLs
returned data set.
?reating a temporar table uses t&e same snta" used to create a standard table. /o signif t&at t&e table is a local
temporar table, a &as& (or pound! smbol (a! is used as a prefi" to t&e table name. /&e name ma be up to 11M
c&aracters in lengt&.
Add t&e following temporar table creation statement to t&e stored procedure code,
?*9A/9 /A+L9 a?ustomer=alue
(
?ustomer0umber I0/,
/otal?ontract=alue %409:,
9ngineer?ost %409:,
>arts?ost %409:,
>rofit %409:
!
>opulating t&e Initial Data
/o initialise t&e data in t&e temporar table we will cop all of t&e customer numbers from t&e li)e data. All ot&er columns
in t&e will contain null )alues at t&is point. We can cop t&e customer numbers using an I0S9*/ statement t&at sources
its information from a #uer as follows,
I0S9*/ I0/4 a?ustomer=alue (?ustomer0umber!
S9L9?/ ?ustomer0umber <*4% ?ustomers
Declaring t&e ?ursor
/&e ne"t step is to populate t&e contract )alue and costs columns. /o ac&ie)e t&is we will use a cursor to allow us to
process t&e data one row at a time. /&e cursor is simple, being based upon selecting t&e onl populated column from t&e
temporar table wit& no filtering of rows.
Add t&e following to t&e stored procedure to declare t&e cursor.
D9?LA*9 ?ustomer?ursor ?8*S4* <4*
S9L9?/ ?ustomer0umber <*4% a?ustomer=alue
4>90 ?ustomer?ursor
/o open t&e cursor and define t&e start of a WAIL9 loop, add t&e following code,
<9/?A 09I/ <*4% ?ustomer?ursor
I0/4 _?ustomer0umber

WAIL9 __<9/?A@S/A/8S B 3
+9GI0

>opulating t&e ?ontract =alue and ?osts
Inside t&e loop we need to retrie)e t&e monetar )alues for t&e contract )alue, engineer cost and parts cost. 9ac& of
t&ese will be &eld in a )ariable t&at will be used in a subse#uent 8>DA/9 statement to appl t&e )alues to t&e appropriate
columns in t&e temporar table. 0ote t&at t&e 8>DA/9 statement c&ecks to see if an of t&e )alues is null. If an are, t&e
are replaced wit& 5eroes.
S9L9?/ _/otal?ontract=alue B sum(?ontract=alue! <*4% ?ontracts ?
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

S9L9?/ _9ngineer?ost B sum(Q.Duration P 9. Aourl*ate! <*4% Qobs Q
I009* Q4I0 9ngineers 9 40 Q.9ngineerId B 9.9ngineerId
I009* Q4I0 ?ontracts ? 40 Q.?ontract0umber B ?.?ontract0umber
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

S9L9?/ _>arts?ost B sum(/otal?ost! <*4% 8sed>arts >
I009* Q4I0 Qobs Q 40 >.QobId B Q.QobId
I009* Q4I0 ?ontracts ? 40 Q.?ontract0umber B ?.?ontract0umber
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

8>DA/9
a?ustomer=alue
S9/
/otal?ontract=alue B isnull(_/otal?ontract=alue, 3!,
9ngineer?ost B isnull(_9ngineer?ost, 3!,
>arts?ost B isnull(_>arts?ost, 3!
WA9*9
?ustomer0umber B _?ustomer0umber
We can now end t&e loop and close and deallocate t&e cursor,
<9/?A 09I/ <*4% ?ustomer?ursor
I0/4 _?ustomer0umber
90D

?L4S9 ?ustomer?ursor
D9ALL4?A/9 ?ustomer?ursor
?alculating t&e >rofits
/&e cursor completed all of t&e column data e"cept t&e >rofit column. /&is can be calculated from t&e costs and t&e
contract )alue after t&e loop &as concluded. 4nce calculated, a #uer is e"ecuted to return t&e data from t&e temporar
table,
8>DA/9 a?ustomer=alue
S9/ >rofit B /otal?ontract=alue 2 9ngineer?ost 2 >arts?ost

S9L9?/ P <*4% a?ustomer=alue 4*D9* +: ?ustomer0umber
Dropping t&e /emporar /able
Alt&oug& a temporar table will be dropped automaticall once t&e connection using it is closed, it is ad)isable to remo)e
it manuall w&en it is no longer re#uired. As our stored procedure &as completed processing t&e data, t&e table ma be
dropped using t&e same snta" as for a standard table,
D*4> /A+L9 a?ustomer=alue
SQL Ser)er /able =ariables
$hat are (able 4ariables3
A table ariable pro)ides functionalit similar to a standard )ariable and a local temporar table combined. Standard
)ariables are used to temporaril &old a single )alue wit&in t&e scope of a script or stored procedure. /emporar tables
are used to define an entire table, stored in t&e tempdb database, for t&e period of some process. /able )ariables are
)ariables t&at &a)e a specific scope and permit a table2like structure to be constructed and populated wit& man rows of
data.
/able )ariables are often used w&ere a temporar table would be utilised ot&erwise. /&eir primar use is for storing
information t&at is to be returned from user2defined functions. Aowe)er, it is not uncommon to see table )ariables used
wit&in stored procedures, triggers, etc. In suc& cases, t&e )ariable e"ists onl wit&in t&e scope of t&e procedure. W&en t&e
process terminates, t&e table )ariable is automaticall destroed. It cannot be passed into an input parameter of anot&er
procedure or returned as an output parameter. If data needs to be returned b a stored procedure, t&e )ariable would
need to be #ueried before t&e procedure ends.
/able )ariables ma be stored partiall wit&in memor or in t&e tempdb database if enoug& *A% is not a)ailable. /&e use
fewer resources for locking and logging t&an temporar tables and are not included in transactions. /&is can pro)ide
impro)ed performance w&en compared to a temporar table but does mean t&at table )ariables are not affected w&en a
transaction is rolled back. Aowe)er, as table )ariables cannot &a)e e"plicitl declared inde"es, do not &a)e parallel
e"ecution plans and are e"cluded from statistics gat&ering, performance can be lower t&an t&e e#ui)alent temporar
table. /able )ariables tend to be better for small sets of data or w&en t&e #ueries e"ecuted against t&em are not comple".
/emporar tables often increase t&e performance for large data sets and comple" ad2&oc operations. /o determine w&ic&
to use for a gi)en scenario, ou s&ould implement bot& and measure t&e performance before selecting an approac&.
Declaring a /able =ariable
/&e snta" for declaring a table )ariable is similar to t&at of creating a table. /&e D9?LA*9 statement is used to name t&e
table )ariable and t&e columns names and tpes are included as a comma2separated list wit&in parent&eses. /&e following
sample code declares a new table )ariable wit& two columns.
D9?LA*9 _/= /A+L9
(
ID I0/,
0ame =A*?AA*($3!
!
Adding Data to a /able =ariable
4nce a table )ariable is declared, information can be inserted, updated, deleted and #ueried as if t&e )ariable w&ere a
true table. /&e following script inserts two rows, updates one of t&ose rows and t&en e"ecutes a #uer against t&e table
)ariable. /&is script must be e"ecuted in t&e same batc& as t&e pre)ious declaration to operate successfull. If t&e
declaration is e"ecuted alone, t&e )ariable will be out of scope before t&e data can be manipulated.
I0S9*/ I0/4 _/= =AL89S (1, L=alue 1L!
I0S9*/ I0/4 _/= =AL89S ($, L=alue 'L!
8>DA/9 _/= S9/ 0ame B L=alue $L WA9*9 IDB$
S9L9?/ P <*4% _/=
Adding 4t&er /able <eatures
/able )ariables can include man table features including primar kes, uni#ue kes, c&eck constraints, identit
columns and default )alues. 9ac& is declared using t&e same snta" as for a true table. In t&e following e"ample t&e table
includes a primar ke. If ou run t&e script, ou will see t&at t&e second insert fails because it would re#uire t&e creation
of a duplicate primar ke )alue.
D9?LA*9 _/= /A+L9
(
ID I0/ >*I%A*: F9:,
0ame =A*?AA*($3!
!

I0S9*/ I0/4 _/= =AL89S (1, L=alue 1L!
I0S9*/ I0/4 _/= =AL89S (1, L=alue $L!
8pdating t&e Get>rofit>er?ustomer Stored >rocedure
In t&e pre)ious lesson we created a stored procedure t&at used a cursor and a temporar table w&ilst determining t&e
profit generated for eac& customer in t&e database. /&is stored procedure could &a)e used a table )ariable instead of t&e
temporar table. /o c&ange t&e stored procedure to use a table )ariable would re#uire se)eral minor modifications,
/&e creation of t&e temporar table would be replaced wit& t&e declaration of a table )ariable, ^_?ustomer=alue^.
All references to a?ustomer=alue would be c&anged to _?ustomer=alue.
/&e commands used to drop t&e temporar table would no longer be needed.
/o modif t&e stored procedure, ou can e"ecute t&e following script.
AL/9* >*4?9D8*9 Get>rofit>er?ustomer AS

D9?LA*9 _?ustomer0umber I0/
D9?LA*9 _/otal?ontract=alue %409:
D9?LA*9 _9ngineer?ost %409:
D9?LA*9 _>arts?ost %409:

D9?LA*9 _?ustomer=alue /A+L9
(
?ustomer0umber I0/,
/otal?ontract=alue %409:,
9ngineer?ost %409:,
>arts?ost %409:,
>rofit %409:
!

I0S9*/ I0/4 _?ustomer=alue (?ustomer0umber!
S9L9?/ ?ustomer0umber <*4% ?ustomers

D9?LA*9 ?ustomer?ursor ?8*S4* <4*
S9L9?/ ?ustomer0umber <*4% _?ustomer=alue

4>90 ?ustomer?ursor

<9/?A 09I/ <*4% ?ustomer?ursor
I0/4 _?ustomer0umber

WAIL9 __<9/?A@S/A/8S B 3
+9GI0

S9L9?/ _/otal?ontract=alue B sum(?ontract=alue! <*4% ?ontracts ?
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

S9L9?/ _9ngineer?ost B sum(Q.Duration P 9. Aourl*ate! <*4% Qobs Q
I009* Q4I0 9ngineers 9 40 Q.9ngineerId B 9.9ngineerId
I009* Q4I0 ?ontracts ? 40 Q.?ontract0umber B ?.?ontract0umber
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

S9L9?/ _>arts?ost B sum(/otal?ost! <*4% 8sed>arts >
I009* Q4I0 Qobs Q 40 >.QobId B Q.QobId
I009* Q4I0 ?ontracts ? 40 Q.?ontract0umber B ?.?ontract0umber
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

8>DA/9
_?ustomer=alue
S9/
/otal?ontract=alue B isnull(_/otal?ontract=alue, 3!,
9ngineer?ost B isnull(_9ngineer?ost, 3!,
>arts?ost B isnull(_>arts?ost, 3!
WA9*9
?ustomer0umber B _?ustomer0umber

<9/?A 09I/ <*4% ?ustomer?ursor
I0/4 _?ustomer0umber
90D

?L4S9 ?ustomer?ursor
D9ALL4?A/9 ?ustomer?ursor

8>DA/9
_?ustomer=alue
S9/
>rofit B /otal?ontract=alue 2 9ngineer?ost 2 >arts?ost

S9L9?/ P <*4% _?ustomer=alue 4*D9* +: ?ustomer0umber
#ser!.efined 5unctions
8ser2defined functions are similar to t&ose pro)ided b SQL Ser)er as standard. /&e are gi)en a name and, optionall, a
set of parameters. 8ser2defined functions are created for a database and can be used in scripts, stored
procedures, triggers and ot&er user2defined functions t&at are defined wit&in t&e database. As wit& stored procedures,
t&e &elp to modularise our /ransact2SQL (/2SQL! code and impro)e maintainabilit b allowing ou to centralise logic.
<or e"ample, ou could create a function t&at returns a standard ta" rate. If t&e ta" rules c&ange, t&e function can be
modified and all /2SQL t&at utilises t&e function would use t&e new ta" rate automaticall.
8ser2defined functions can be separated into two main categories. /&ese are scalar functions and table!alued functions.
Scalar <unctions
Scalar functions are similar to t&e functions we &a)e used in earlier articles. /&e can optionall accept one or more
parameters and return a single )alue. /&e return )alue is a standard data tpe but cannot be a /e"t, 0/e"t, Image or
/imestamp.
/able2=alued <unctions
/&e second tpe of user2defined function is t&e table!alued function. As t&e name suggests, a table2)alued function
returns a table )ariable. /able2)alued functions are often used as ^parameterised )iews^ as t&e can be included in place
of tables in a #uer and can accept arguments. Suc& #ueries select from t&e rows pro)ided in t&e functionLs result.
/able2)alued functions can be furt&er categorised into inline and multi!function )ariations. /&ese determine t&e snta"
used w&en creating t&e function but do not c&ange t&e wa in w&ic& it is called. Inline functions contain a single
statement, w&ic& must be a S9L9?/. /&e results of t&e #uer become t&e return )alue of t&e function.
%ulti2function table2)alued functions can include man statements, similar to t&ose in a stored procedure. /&e table
structure to be returned is defined wit&in t&e function, rat&er t&an being implicitl created to &old a #uerLs results. A
batc& of statements is used to populate t&e table )ariable before it is returned.
?reating a Simple Scalar <unction
/&e first function t&at we will create will be a simple scalar function t&at returns a ta" rate. /&is could be used t&roug&out
a database w&en calculating t&e ta" on sales. If t&e go)ernment c&anges t&e ta" rate, it would re#uire a single c&ange to
modif all of t&e functionalit in t&e database t&at uses t&e percentage. As t&e rate is fi"ed, no parameters are re#uired
for t&is function.
/&e snta" for creating a function wit& no parameters is as follows,
?*9A/9 <80?/I40 function!name(!
*9/8*0S return!type
AS
+9GI0
statement!1
statement!2
.
.
statement!6
*9/8*0 return!alue
90D
/&e signature of t&e function contains two ke elements. /&e function!name is a uni#ue name for t&e new function
and return!type defines t&e data tpe t&at will be returned. /&e functionLs bod appears between +9GI0 and 90D
kewords and can include multiple statements. /&e return!alue is t&e )alue t&at t&e function returns to its caller and
must be of t&e tpe declared in t&e signature.
/o create t&e simple (ax/ate function and set t&e )alue t&at it returns to 1O.6, e"ecute t&e following,
?*9A/9 <80?/I40 /a"*ate(!
*9/8*0S 08%9*I?(6,$!
AS
+9GI0
*9/8*0 1O.6
90D
?alling a <unction
8ser2defined scalar functions can be used in t&e same places ou mig&t use built2in functions. /&ese include wit&in
scripts, #ueries, I0S9*/ and 8>DA/9 commands and stored procedures. /o simpl s&ow t&e )alue returned b t&e
/a"*ate function, we can use t&e >*I0/ command as follows,
>*I0/ dbo./a"*ate(!
0ote t&e inclusion of ^dbo.^ as a prefi" to t&e function name. /&is is t&e schema name and must be pro)ided for scalar
functions. Sc&ema names are used to separate elements of a database and pro)ide different sc&emas for different users.
In t&is e"ample we &a)e onl used t&e default sc&ema, named ^dbo^.
%odifing a <unction
/o modif an e"isting function ou can use t&e AL/9* <80?/I40 command. /&e snta" for t&e command is identical to
t&at of t&e ?*9A/9 <80?/I40 command. <or e"ample, if t&e ta" rate were to increase from 1O.6W to 1N.O6W, t&e
function could be updated as follows,
AL/9* <80?/I40 /a"*ate(!
*9/8*0S 08%9*I?(6,$!
AS
+9GI0
*9/8*0 1N.O6
90D
Adding >arameters
%ost functions will include parameters t&at determine t&e operation of t&e function and t&e e)entual return )alue.
>arameters can be added as a comma2separated list wit&in t&e parent&eses t&at follow t&e function name. /&e snta" is
)er similar to t&at of stored procedures.
/&e following function adds a single parameter t&at accepts a monetar )alue. It performs a calculation t&at adds t&e ta"
rate, defined in t&e earlier function, and returns t&e result.
?*9A/9 <80?/I40 =alueWit&/a" (_=alue %409:!
*9/8*0S %409:
AS
+9GI0
*9/8*0 _=alue ] (_=alue P dbo./a"*ate(! 7 133!
90D
/o demonstrate t&e new function, e"ecute t&e following #uer. /&is returns all of t&e contracts from t&e database,
s&owing t&e contract number, contract )alue and t&e )alue wit& t&e ta" rate added.
S9L9?/ ?ontract0umber, ?ontract=alue, dbo.=alueWit&/a"(?ontract=alue! AS Wit&/a"
<*4% ?ontracts
8sing Data
/&e bod of a user2defined function can include statements t&at read data from tables, )iews or ot&er functions. /&is
allows t&e creation of )er powerful, reusable functions for a database. In t&e following e"ample, t&e function accepts
t&ree parameters. /&e first parameter is used to specif t&e ID of an engineer, w&ic& must matc& t&e primar ke )alue of
a row in t&e 9ngineers table. /&e ne"t two parameters allow t&e specification of a number of &ours of normal and
o)ertime working. /&e function reads t&e engineerLs pa rates and calculates t&e amount earned accordingl.
?*9A/9 <80?/I40 9ngineer?ost
(
_9ngineerId I0/,
_0ormalAours 08%9*I?(H, $!,
_4)ertimeAours 08%9*I?(H, $!
!
*9/8*0S %409:
AS
+9GI0
D9?LA*9 _Aourl*ate %409:
D9?LA*9 _4)ertime*ate %409:

S9L9?/
_Aourl*ate B Aourl*ate,
_4)ertime*ate B 4)ertime*ate
<*4%
9ngineers
WA9*9
9ngineerId B _9ngineerId

*9/8*0 (_Aourl*ate P _0ormalAours! ] (_4)ertime*ate P _4)ertimeAours!
90D
In our database, 9ngineer 1 earns b1C.O6 per standard &our and b$C.M' per &our at t&e o)ertime rate. 9"ecute t&e
following t&ree statements to see t&is data used to calculate sample paments.
>*I0/ dbo.9ngineer?ost(1, 13, 3!
>*I0/ dbo.9ngineer?ost(1, 3, 13!
>*I0/ dbo.9ngineer?ost(1, 13, 13!
?reating an Inline /able2=alued <unction
Inline table2)alued functions are generall used to create ^parameterised )iews^. /&e do not include statements in a
+9GI0 7 90D block. Instead, t&e bod of t&e function is a S9L9?/ statement t&at ma use t&e )alues passed in as
arguments. /&e snta" for an inline table2)alued function is as follows,
?*9A/9 <80?/I40 function!name
(
param!1
param!2
.
.
param!6
!
*9/8*0S /A+L9
AS
*9/8*0
query
We can create a simple inline function using t&e following script. /&is function retrie)es a list of -obs t&at &a)e t&e same
name. /&e name of -ob to locate is supplied using t&e parameter.
?*9A/9 <80?/I40 QobList+Qob0ame (_Qob0ame =A*?AA*(133!!
*9/8*0S /A+L9
AS
*9/8*0
S9L9?/ P <*4% QobList
WA9*9 Qob0ame B _Qob0ame
4nce created, a table2)alued function can be used as t&e data source in a S9L9?/ statement. <or e"ample, t&e following
#uer retrie)es all of t&e -obs w&ere t&e Qob0ame column contains ^9lectrical Socket <ailure^. (a)e note, 7ou do not need
to include the schema name prefix for table!alued functions.
S9L9?/ P <*4% QobList+Qob0ame(L9lectrical Socket <ailureL!
As t&e function is simpl replacing a table or )iew in t&e #uer, ot&er clauses can be added. /&e following e"ample
retrie)es -obs t&at are electrical socket failures repaired on $ <ebruar $33N.
S9L9?/ P <*4% QobList+Qob0ame(L9lectrical Socket <ailureL!
WA9*9 =isitDate B L$33N23'23$L
?reating a %ulti2Statement /able2=alued <unction
%ulti2statement table2)alued functions can be used to create )er powerful functions t&at return table data. /&e include
a set of statements contained between +9GI0 and 90D kewords. /&e bod can read information from t&e database and
perform man ot&er tasks t&at ou could include in stored procedures.
W&en defining a multi2statement function, t&e return )alue is declared as a table )ariable and includes t&e full structure of
t&e table t&at will be returned. /&e bod of t&e function performs actions t&at fill t&e table )ariable wit& data. At t&e end
of t&e processing, t&e *9/8*0 statement is used wit&out a )alue and t&e pre)iousl declared table )ariable is returned.
9arlier in t&e tutorial we created a stored procedure t&at used a cursor and a temporar table to build a list of customers
and t&e profit t&at eac& &ad pro)ided to t&e compan. /&e stored procedure returned data but in a format t&at would be
difficult to process furt&er wit& /2SQL. We can gain fle"ibilit b recreating t&is stored procedure as a function,
?*9A/9 <80?/I40 >rofit>er?ustomer(!
*9/8*0S _?ustomer=alue /A+L9
(
?ustomer0umber I0/,
/otal?ontract=alue %409:,
9ngineer?ost %409:,
>arts?ost %409:,
>rofit %409:
!
AS
+9GI0
D9?LA*9 _?ustomer0umber I0/
D9?LA*9 _/otal?ontract=alue %409:
D9?LA*9 _9ngineer?ost %409:
D9?LA*9 _>arts?ost %409:

I0S9*/ I0/4 _?ustomer=alue (?ustomer0umber!
S9L9?/ ?ustomer0umber <*4% ?ustomers

D9?LA*9 ?ustomer?ursor ?8*S4* <4*
S9L9?/ ?ustomer0umber <*4% _?ustomer=alue

4>90 ?ustomer?ursor

<9/?A 09I/ <*4% ?ustomer?ursor
I0/4 _?ustomer0umber

WAIL9 __<9/?A@S/A/8S B 3
+9GI0

S9L9?/ _/otal?ontract=alue B sum(?ontract=alue! <*4% ?ontracts ?
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

S9L9?/ _9ngineer?ost B sum(Q.Duration P 9. Aourl*ate! <*4% Qobs Q
I009* Q4I0 9ngineers 9 40 Q.9ngineerId B 9.9ngineerId
I009* Q4I0 ?ontracts ? 40 Q.?ontract0umber B ?.?ontract0umber
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

S9L9?/ _>arts?ost B sum(/otal?ost! <*4% 8sed>arts >
I009* Q4I0 Qobs Q 40 >.QobId B Q.QobId
I009* Q4I0 ?ontracts ? 40 Q.?ontract0umber B ?.?ontract0umber
I009* Q4I0 ?ustomerAddresses A 40 ?.?ustomerAddressId B A.AddressId
WA9*9 A.?ustomer0umber B _?ustomer0umber

8>DA/9
_?ustomer=alue
S9/
/otal?ontract=alue B isnull(_/otal?ontract=alue, 3!,
9ngineer?ost B isnull(_9ngineer?ost, 3!,
>arts?ost B isnull(_>arts?ost, 3!
WA9*9
?ustomer0umber B _?ustomer0umber

<9/?A 09I/ <*4% ?ustomer?ursor
I0/4 _?ustomer0umber
90D

?L4S9 ?ustomer?ursor
D9ALL4?A/9 ?ustomer?ursor

8>DA/9
_?ustomer=alue
S9/
>rofit B /otal?ontract=alue 2 9ngineer?ost 2 >arts?ost

*9/8*0
90D
Wit& t&e function created, t&e data can be used as if it were in a table. /&e statement below returns t&e data from t&e
function. We could add furt&er clauses to filter, sort, group andsummarise t&is information.
S9L9?/ P <*4% >rofit>er?ustomer(!
Sample for /emporar /ables,and <unctions
We will use t&is table structure ,
Aa)ing t&is data,
1. 8sing temporar table and cursor to cop table data
create procedure pr_CopytoTemp
as
begin
declare @cola varchar(50), --declare variable for cursor
@colb decimal(!,")
create table #tmp --create tmp table named #tmp
(
id$ int identity(,),
col_a varchar(50),
col_b decimal(!,")
)
declare cur%o cursor for --create cursor
select a_cola,a_colb from tbl_&
open cur%o --open cursor
fetch ne$t from cur%o --fetch data from cursor
into @cola,@colb
'hile @@fetch_status ( 0 --chec) for status if may laman
begin
insert into #tmp values (@cola,@colb) --insert into temp table
fetch ne$t from cur%o --fetch ne$t record
into @cola,@colb
end
close cur%o --close cursor
deallocate cur%o --deallocate from memory
select * from #tmp --return our data from tmp using select
drop table #tmp --drop temp table
end
to e"ecute,
e$ec pr_CopytoTemp
output+
$.! temporar table using 4DD79=90
create procedure pr_CopytoTemp,dd-ven
@opt varchar(50)
as
begin
declare @cola varchar(50), --declare variable for cursor
@colb decimal(!,")
create table #tmp --create tmp table named #tmp
(
id$ int identity(,),
col_a varchar(50),
col_b decimal(!,")
)
declare cur%o cursor for --create cursor
select a_cola,a_colb from tbl_&
open cur%o --open cursor
fetch ne$t from cur%o --fetch data from cursor
into @cola,@colb
'hile @@fetch_status ( 0 --chec) for status if may laman
begin
if @opt ( .-/-0.
begin
if @colb 1 ! ( 0
begin
insert into #tmp values (@cola,@colb) --insert into temp table
end
end
else
begin
if @colb 1 ! 23 0
begin
insert into #tmp values (@cola,@colb) --insert into temp table
end
end
fetch ne$t from cur%o --fetch ne$t record
into @cola,@colb
end
close cur%o --close cursor
deallocate cur%o --deallocate from memory
select * from #tmp --return our data from tmp using select
drop table #tmp --drop temp table
end
to e"ecute,
e$ec pr_CopytoTemp,dd-ven .-/-0.
45 8sing table )ariable
create procedure pr_Copyto/ar,dd-ven
@opt varchar(50)
as
begin
declare @cola varchar(50), --declare variable for cursor
@colb decimal(!,")
declare @tmp table --create table variable named @tmp
(
id$ int identity(,),
col_a varchar(50),
col_b decimal(!,")
)
declare cur%o cursor for --create cursor
select a_cola,a_colb from tbl_&
open cur%o --open cursor
fetch ne$t from cur%o --fetch data from cursor
into @cola,@colb
'hile @@fetch_status ( 0 --chec) for status if may laman
begin
if @opt ( .-/-0.
begin
if @colb 1 ! ( 0
begin
insert into @tmp values (@cola,@colb) --insert into temp table
end
end
else
begin
if @colb 1 ! 23 0
begin
insert into @tmp values (@cola,@colb) --insert into temp table
end
end
fetch ne$t from cur%o --fetch ne$t record
into @cola,@colb
end
close cur%o --close cursor
deallocate cur%o --deallocate from memory
select * from @tmp --return our data from tmp using select

end
to e"ecute ,
e$ec pr_Copyto/ar,dd-ven .,66.
"5 7sing scalar function (remember to use dbo 8hen accessing or using functions, it indicates
database ob9ect: database o'ner)
--scalar function returns only value
create function fn_get;a$()
returns decimal(!,")
as
begin
declare @ma$/al decimal(!,")
select @ma$/al ( ma$(a_colb) from tbl_&
return @ma$/al
end
to e$ecute+
select dbo5fn_get;a$()
55 7sing scalar function 'ith parameter
create function fn_getCol&(@id int)
returns varchar(50)
as
begin
declare @string/al varchar(50)
select @string/al ( a_cola from tbl_&
'here a_id ( @id
return @string/al
end
to e"ecute,
select dbo5fn_getCol&(!) --remeber if scalar function is e$ecuted use dbo
--to indicate database ob9ect and note that
--the function is tored inside the current database
<5 =nline table valued (it doesn>t need ?-@=0 and -06)5 Aemember for table valued functions
if 'e are to e$ecute it, 'e must use select statement5 Aemember 'e can only use select
statement for inline table valued
create function fn_inlineTable&()
returns table
as
return select * from tbl_&
to e$ecute+
select * from dbo5fn_inlineTable&() B- use select statement

22if we are to use definite columns
select a_cola,a_colb from dbo5fn_inlineTable&()
C5 Inline tabled )alue wit& parameter (parameters are placed inside parent&eses!
create function fn_inlineTable&!(@id int)
returns table
as
return select * from tbl_& 'here a_id ( @id
output,
select * from dbo5fn_inlineTable&!(!)
D5 %ulti )alued table function (&ere we can onl use table )ariable and it must be declare in t&e &eader!. /ake note t&at
return is placed before t&e last 90D, we do not need to place select statement because t&e returned table is alread
specified.
create function fn_multi,dd-ven(@opt varchar(50))
returns @tmp table --create variable table ('e cannot use temp table inside function)
(
id$ int identity(,),
col_a varchar(50),
col_b decimal(!,5)
)
as
begin
declare @cola varchar(50), --declare variable for cursor
@colb decimal(!,")

declare cur%o cursor for --create cursor
select a_cola,a_colb from tbl_&
open cur%o --open cursor
fetch ne$t from cur%o --fetch data from cursor
into @cola,@colb
'hile @@fetch_status ( 0 --chec) for status if may laman
begin
if @opt ( .-/-0.
begin
if @colb 1 ! ( 0
begin
insert into @tmp values (@cola,@colb) --insert into temp table
end
end
else
begin
if @colb 1 ! 23 0
begin
insert into @tmp values (@cola,@colb) --insert into temp table
end
end
fetch ne$t from cur%o --fetch ne$t record
into @cola,@colb
end
close cur%o --close cursor
deallocate cur%o --deallocate from memory
return
end
output,
select * from dbo5fn_multi,dd-ven(.,66.)
select * from dbo5fn_multi,dd-ven(.-/-0.)
8ee) D
Summary o) Concepts
1. ?reating our tables
Gi)en a specific problem, we &a)e to go back to t&e basic concepts we &ad learned, creation of t&e 9* (entit2
relations&ip model! and normali5ation (atleast up to t&e t&ird normal form!. So for e"ample fi)en t&e following
problems or ideas, w&at tables can be created upon t&em.*emember t&at our tables represent li)ing or non2li)ing
ob-ects,
a. Sc&ool Grading could &a)e t&e following tables7entities ,
i. Instructor (instructor@id int primar ke, instructor@name )arc&ar(633!!
ii. Sub-ect (sub-ect@id int primar ke,sub-ect@name )arc&ar(63!!
iii. Grade (grade@id int primar ke, semester )arc&ar(63!, ear int,instructor@id int foreign
ke,sub-ect@id int foreign ke!
b. <arm could &a)e t&e following tables7entities ,
i. <armer (farmer@id int primar ke,farmer@name )arc&ar(63!!
ii. /pe(tpe@id int primar ke,tpe@name )arc&ar(63!!
iii. >roduct(product@id int primar ke,tpe@id int foreign ke, product@name )arc&ar(63!!
i). Sale(sale@id int >F, product@id <F, #uantit int, price decimal(1$,H!, sale@date datetime!
c. Supermarket could &a)e t&e following ,
i. >roducts (product@id int >F, product@name )arc&ar(63!!
ii. ?as&ier (cas&ier@id int >F, cas&ier@name )arc&ar(63!!
iii. ?ustomer(customer@id int >F, customer@name )arc&ar(63!!
i). >urc&ase(purc&ase@id int >F, product@id int <F,cas&ier@id int <F, customer@id int <F,
purc&ase@amount decimal(1$,H!, purc&ase@date datetime,cas& bit!
0otice t&at we &a)e to &a)e at least 1 table t&at will link t&e ot&er tables to eac& ot&er t&roug& t&e use of foreign kes.
$. ?reating database ob-ects in %SSQL Ser)er
a. %ake sure to name our database according to t&e work or pro-ect to be done.A)oid spaces, if ou are to
use spaces, replace it wit& underscore. In t&is e"ample I will make use of t&e name S%DepartmentStore.
b. ?reate our tables for >roducts, ?as&ier and ?ustomer first (because t&e >urc&ase table re#uires us to use
<oreign Fes!
c. ?reate our >urc&ase table t&at will allow us to link t&e ot&er t&ree tables toget&er using <oreign Fes
0e"t we create our foreign ke relations&ips. *ig&t2click an column. Select *elations&ip
?lick ADD to add all t&e relations&ips t&at we want to create. In t&is instance we will create ' relations&ip
for ?as&ier, >roducts and ?ustomer. After clicking ADD, it will automaticall pro)ide a name, kindl pro)ide
a rele)ant name t&at describe t&e tables to be linked. <or e"ample I will use t&e name
<F@tbl@>urc&ase@tbl@?ustomer for connecting t&e column customer@id.
0e"t ?lick t&e ] sign in t&e /ables and ?olumns Specification and click t&e c button. In t&is window, we
can c&ange t&e <F name and specif t&e >rimar ke table, in t&is case tbl@?ustomer. /&en select t&e column to be set as
t&e primar ke.
?lick 4F. And t&en click ?L4S9.
0ote, If ou want to create an I0S9*/ or 8>DA/9 ?AS?AD9, meaning if ou delete a >*I%A*: F9: in one
table all t&e ot&er related columns in t&e ot&er table will be deleted, ou can use t&e I0S9*/ and 8>DA/9 Specification.
Qust click t&e ] sign and select t&e 8>DA/9 or D9L9/9 rule. :ou can select 0o Action [ not&ing will be done( ?ascade [ all
linked columns will also be 8>DA/9D or D9L9/9D, Set 0ull [ all related columns. )alue will be set to 0ull( Set Default [all
related columns )alue will be set to Default )alue. Afterwards, click ?L4S9.
Set all t&e foreign kes for ?as&ier and >roducts.

d. ?reate t&e )iews t&at will &elp us render data. In t&is e"ample I will create a )iew called )w@>urc&ase t&at
list all purc&ased items b customers toget&er wit& t&eir respecti)e cas&iers. *ig&t click =iews,select 0ew
=iewc

In t&e Add /able window, select all t&e tables to be used for our )iew. In t&is case, all tables will be added.
8suall all t&e realtions&ip will be automatic depending on t&e column name and t&e setup of >F and <F. 0e"t,
tr to use ALIAS in order for us to &a)e a s&orter column name.
Select t&e columns to be selected. 9it&er b clicking or selecting t&e desired columns.
?lose t&e )iew and sa)e it as )w@>urc&ase.
CA-&T- /=-8 v'_Eurchase
&F
F-G-CT s5customer_name, p5purchase_date, p5purchase_amount, p5cash, d5product_name,
c5cashier_name, p5product_id, p5cashier_id, p5customer_id
HA,; dbo5tbl_Cashier &F c =00-A I,=0
dbo5tbl_Eurchase &F p ,0 c5cashier_id ( p5cashier_id =00-A I,=0
dbo5tbl_Customer &F s ,0 p5customer_id ( s5customer_id =00-A I,=0
dbo5tbl_Eroduct &F d ,0 p5product_id ( d5product_id
e. After creating our )iew, we can now proceed to creating stored procedures for our Database. In order to
manipulate data, we can create a stored procedure to &andle all t&e insert or update and delete of data.
We must do t&ese for all our tables. In t&is e"ample, I will make a stored procedure to add7edit data using
one stored procedure. It will accept t&e needed parameters and it will accept a parameter called _opt to
indicate if it.s an add or edit operation.
*ig&t2click >rogrammbilit, and click 0ew Stored >rocedure. Alwas remember t&e skeleton7blue2print for
our stored procedure ,
create procedure procedure_name [22a)oid spaces on all database ob-ect names
as
begin
end
if we will use parameters, it s&ould start wit& _ followed b t&e name and t&e datatpe.
create procedure procedure_name [22a)oid spaces on all database ob-ect names
0param% 3archar67'8,0param& int
as
begin
end
Did ou notice t&e command S9/ 04?480/ 40( -- F-T 0,C,70T ,0 added to prevent e$tra result sets
from interfering 'ith F-G-CT statements5=f 'e are to mna)e use of select statements in our
stored procedures, it should be included in our first line after begin5

CA-&T- EA,C-67A- pr_Eurchase
@opt int,@product int,@cashier int,@customer int,@amt decimal(!,"),@date datetime,@cash bit,@purchase int
&F
?-@=0
-- F-T 0,C,70T ,0 added to prevent e$tra result sets from
-- interfering 'ith F-G-CT statements5
F-T 0,C,70T ,0J

if @opt ( 0 --if Kero then add
begin
insert into tbl_Eurchase values (@product ,@cashier ,@customer ,@amt ,@date ,@cash )
end
else --if any other number, consider as an update statement
begin
update tbl_Eurchase set product_id ( @product ,cashier_id ( @cashier ,customer_id (@customer ,
purchase_amount(@amt ,purchase_date(@date ,cash(@cash
'here purchase_id ( @purchase
end
-06
@,
To add data for e$ample, 'e call+
e$ec pr_Eurchase 0,5,,, !!55<5,.L:C:!04 4+!5 E;.,,0
Aere, we inserted a 3 to represent t&at we will ADD data. /&e product id is 6, t&e cas&ier id is 1, t&e customer id
is 1, t&e amount is $$6.M6, t&e date is .C71O7$31' ',$6 >%., it was boug&t as 1 w&ic& means /rue as cas& and we &a)e 3 as t&e
purc&ase id because we are adding data and it is not needed.
4utput is ,
/&e =iew output is ,
/o update we -ust do t&e following ,
e$ec pr_Eurchase ,5,,, !!55,.L:C:!04 4+!5 E;.,,!
Aere, we inserted a 1 to represent t&at we will 9DI/ data. /&e product id is 6, t&e cas&ier id is 1, t&e customer id
is 1, t&e amount was c&anged to $1$.16, t&e date is .C71O7$31' ',$6 >%., it was boug&t as 1 w&ic& means /rue as cas& and we
&a)e $ as t&e purc&ase id t&at we need to update.
f. 0e"t we will create a function t&at will get t&e 1$ W )at of all purc&ased product. We will use t&is in stored procedure
to return a report of t&e )at.
*emember t&e blueprint for a scalar function w&ic& returns a single )alue.
create function function_name(@param datatype) ---don>t forget to put () after the name
returns datatype
as
begin
return datatype
end
In t&is instance t&e snta" will be,
create function fn_get/&T(@value decimal(!,"))
returns decimal(!,")
as
begin
return (@value * 05!)
end
in order to use t&is, we can make use of a select statement. 9"ample,
select customer_name,purchase_date,purchase_amount, dbo5fn_get/&T(purchase_amount) as
/&T,product_name from v'_Eurchase

it outputs+
W&at if we want our function to return t&e total items boug&t b a customer for a particular da,
create function fn_getTotal?ought(@customer int,@date datetime)
returns decimal(!,")
as
begin
declare @tot?ought decimal(!,")
select @tot?ought ( sum(purchase_amount) from tbl_Eurchase
'here customer_id ( @customer and month(purchase_date) ( month(@date) and
day(purchase_date) ( day(@date) and year(purchase_date) ( year(@date)

return (@tot?ought)
end
Gi)en t&is table data for tbl@>urc&ase,
We will use t&is SQL statement,
select customer_name,purchase_date,purchase_amount,dbo5fn_get/&T(p5purchase_amount) as
/&T,product_name, dbo5fn_getTotal?ought(p5customer_id,p5purchase_date)
from v'_Eurchase p
&nd arrive at this output+
0e"t is I will create a stored procedure t&at will output a temporar table7table )ariable and displa our data for a particular
mont& and ear.

(using temporar table!,
?reate procedure pr@getSales/emp
_mont& int,_r int
as
begin
set nocount on
declare _cust )arc&ar(63!,
_tot decimal(1$,H!,
create table #tmp --create tmp table named #tmp
(
id$ int identity(,),
customer_name varchar(50),
amount_bought decimal(!,")
)
D9?LA*9 rpt?ursor ?8*S4*
<4* S9L9?/ customer@name,S8%(purc&ase@amount!
<*4% )w@>urc&ase
w&ere mont&(purc&ase@date! B _mont& and ear(purc&ase@date! B _r
group b customer@id, customer@name
open rpt?ursor --open cursor
fetch ne$t from rpt?ursor --fetch data from cursor
into _cust,_tot
'hile @@fetch_status ( 0 --chec) for status if may laman
begin
insert into #tmp values (_cust,_tot)
fetch ne$t from rpt?ursor --fetch data from cursor
into _cust,_tot
end
close rpt?ursor
deallocate rpt?ursor
select P from atmp
drop table atmp
end
to e"ecute ,
pr_getFalesTemp L,!04
'e 'ill get the output+
(using table )ariable!,
Create procedure pr_getFales/ar
@month int,@yr int
as
begin
set nocount on
declare @cust varchar(50),
@tot decimal(!,")
declare @tmp table --create table variable named @tmp
(
id$ int identity(,),
customer_name varchar(50),
amount_bought decimal(!,")
)
6-CG&A- rptCursor C7AF,A
H,A F-G-CT customer_name,F7;(purchase_amount)
HA,; v'_Eurchase
'here month(purchase_date) ( @month and year(purchase_date) ( @yr
group by customer_id, customer_name
open rptCursor --open cursor
fetch ne$t from rptCursor --fetch data from cursor
into @cust,@tot
'hile @@fetch_status ( 0 --chec) for status if may laman
begin
insert into @tmp values (@cust,@tot)
fetch ne$t from rptCursor --fetch data from cursor
into @cust,@tot
end
close rptCursor
deallocate rptCursor
select * from @tmp
end
to e"ecute ,
pr_ getSales=ar L,!04
'e 'ill have the output+
/ransaction reco)er
Database transaction reco)er uses data in t&e transaction log to reco)er a database from an inconsistent state to a
consistent state.
<our important concepts,
/&e write2a&ead2log protocol ensures t&at transaction logs are alwas written before an database data are
actuall updated. /&is protocol ensures t&at, in case of a failure, t&e database can later be reco)ered to a
consistent state, using t&e data in t&e transaction log.
*edundant transaction logs(se)eral copies of t&e transaction log! ensure t&at a p&sical disk failure will not impair
t&e D+%S.s abilit to reco)er data.
Database buffers are temporar storage areas in primar memor used to speed up disk operations. /o impro)e
processing time, t&e D+%S software reads t&e data from t&e p&sical disk and stores a cop of it on a JbufferK in
primar memor.
Database c&eckpoints are operations in w&ic& t&e D+%S writes all of its updated buffers to disk. W&ile t&is is
&appening, t&e D+%S does not e"ecute an ot&er re#uests. A c&eckpoint operation is also registered in t&e
transaction log.
/&e database reco)er process in)ol)es bringing t&e database to a consistent state after a failure. /ransaction reco)er
procedures generall make use of deferred2write and write2t&roug& tec&ni#ues.
W&en t&e reco)er procedure uses a deferred2write tec&ni#ue (also called a deferred update!, t&e transaction operations
do not immediatel update t&e p&sical database. Instead, onl t&e transaction log is updated. /&e database is p&sicall
updated onl after t&e transaction reac&es its commit point, using information from t&e transaction log.
If t&e transaction aborts before it reac&es its commit point, no c&anges (no *4LL+A?F or undo! need to be made to
W&en t&e reco)er procedure uses a write2t&roug& tec&ni#ue (also called an immediate update!, t&e database is
immediatel updated b transaction operations during t&e transaction.s e"ecution, e)en before t&e transaction reac&es its
commit point. If t&e transaction aborts before it reac&es its commit point, a *4LL+A?F or undo operation needs to be
done to restore t&e database to a consistent state.
Database +ackup
We s&ould use master database so t&at all databases we created can access t&e code. /&e master database ser)es as t&e
blueprint for all user databases.
9"ample code,
?*9A/9 >*4?9D8*9 DdboE.Dpr@+ackupDatabaseE
_database0ame ssname, _backup/pe ?AA*(1!
AS
+9GI0
S9/ 04?480/ 40(
D9?LA*9 _s#l?ommand 0=A*?AA*(1333!
D9?LA*9 _date/ime 0=A*?AA*($3!
S9L9?/ _date/ime B ?AS/(:9A*(G9/DAte(!! AS =A*?AA*(H!! ] L@L ] ?AS/(mont&(G9/DAte(!! AS =A*?AA*($!!
] L@L ] ?AS/(da(G9/DAte(!! AS =A*?AA*($!!
I< _backup/pe B L<L
S9/ _s#l?ommand B L+A?F8> DA/A+AS9 L ] _database0ame ]
L /4 DISF B LL<,d+Ackup@SQLd+ackupdL ] _database0ame ] L@<ull@L ] _date/ime ] L.+AFLLL

I< _backup/pe B LDL
S9/ _s#l?ommand B L+A?F8> DA/A+AS9 L ] _database0ame ]
L /4 DISF B LL<,d+Ackup@SQLd+ackupdL ] _database0ame ] L@Diff@L ] _date/ime ] L.+AFLL WI/A
DI<<9*90/IALL

I< _backup/pe B LLL
S9/ _s#l?ommand B L+A?F8> L4G L ] _database0ame ]
L /4 DISF B LL<,d+Ackup@SQLd+ackupdL ] _database0ame ] L@Log@L ] _date/ime ] L./*0LLL

9I9?8/9 sp@e"ecutes#l _s#l?ommand
90D

Das könnte Ihnen auch gefallen