Programming Microsoft SQL Server 2000

Document Sample
Programming Microsoft SQL Server 2000 Powered By Docstoc
					Program m ing Microsoft ® SQL Server™ 2000 wit h Micr osoft Visual
Basic® .NET

Foreword

Acknow ledgm ent s

I nt roduct ion
   Who’s t he Book For?
   What ’s Special About This Book?
   How’s t he Book Organized?
   Syst em Requirem ent s
   Sam ple Files
   Support

1. Get t ing St art ed w it h Visual Basic .NET for SQL Serv er 2000
  Visual St udio .NET, t he Visual Basic .NET I DE
  An Overv iew of ADO.NET Capabilit ies
  A St art er ADO.NET Sam ple
  Using Query Analyzer

2. Tables and Dat a Types
  Chapt er Resources
  Dat a Types for Tables
  Scr ipt ing Tables

3. Pr ogram m ing Dat a Access wit h T- SQL
  I nt r oduct ion t o Dat a Access wit h T- SQL
  Aggregat ing and Grouping Rows
  Processing Dat es
  Joins and Subquer ies

4. Pr ogram m ing Views and St ored Procedures
  I nt r oduct ion t o Views
  Creat ing and Using Views
  Views for Rem ot e and Het erogeneous Sources
  I nt r oduct ion t o St ored Procedur es
  Creat ing and Using St or ed Procedures
  Processing St or ed Procedur e Out put s
  I nsert ing, Updat ing, and Delet ing Rows
  Program m ing Condit ional Result Set s

5. Pr ogram m ing User - Defined Funct ions and Tr iggers
  I nt r oduct ion t o User - Defined Funct ions
  Creat ing and I nv ok ing Scalar UDFs
  Creat ing and I nv ok ing Table- Valued UDFs
  I nt r oduct ion t o Tr iggers
  Creat ing and Managing Tr iggers

6. SQL Serv er 2000 XML Funct ionalit y
  Overv iew of XML Support
  XML Form at s and Schem as
  URL Access t o SQL Serv er
  Tem plat e Access t o SQL Server

7. SQL Serv er 2000 Secur it y
  Overv iew of SQL Serv er Secur it y
  I nt r oduct ion t o Special Securit y I ssues
  Sam ples for Logins and Users
  Sam ples for Assigning Perm issions

8. Overv iew of t he .NET Fram ework
  An I nt r oduct ion t o t he .NET Fram ework
  An Overv iew of ASP.NET
  XML Web Ser v ices

9. Cr eat ing Windows Applicat ions
  Get t ing St art ed w it h Windows For m s
  Creat ing and Using Class References
  I nher it ing Classes
  Program m ing Event s
  Except ion Handling for Run- Tim e Err ors

10. Progr am m ing Windows Solut ions w it h ADO. NET
  An Overv iew of ADO.NET Obj ect s
  Making Connect ions
  Wor k ing w it h Com m and and Dat aReader Obj ect s
  Dat aAdapt ers , Dat a Set s, Form s, and Form Cont rols
  Modify ing, I nsert ing, and Delet ing Rows

11. Progr am m ing ASP.NET Solut ions
  Rev iew of ASP.NET Design I ssues
  Creat ing and Running ASP.NET Solut ions
  Session St at e Managem ent
  Dat a on Web Pages
  Validat ing t he Dat a on a Web Page

12. Managing XML wit h Visual Basic .NET
  SQL Ser ver Web Releases
  Overv iew of XML Technologies
  Generat ing XML Docum ent s wit h t he .NET Fram ework
  Dy nam ically Set t ing an XML Result Set
  The I nt erplay Bet w een XML and Dat a Set s
  Creat ing HTML Pages wit h XSLT

13. Cr eat ing Solut ions wit h XML Web Ser v ices
  Overv iew of Web ser v ices
  A Web Serv ice t o Ret ur n a Com put ed Result
  A Web Serv ice t o Ret ur n Values from Tables
  The SQL Ser ver 2000 Web Ser v ices Toolk it
  Mor e on Populat ing Cont rols wit h Web Ser vices

About t he Aut hor
For e w or d
During m y five years at Micr osoft , I ’v e been helping developers underst and
t echnologies such as Microsoft Visual St udio, Microsoft SQL Ser ver, and Micr osoft
Office Developer. Dur ing t he past t wo years, I hav e w orked on t he Microsoft
Office XP Visual Basic Language Refer ence, and now, t he MSDN Office Dev eloper
Cent er. I n t he m ont hly colum n on MSDN, Office Talk, I have wr it t en art icles t o
help Office developers underst and t he .NET plat for m and how it affect s t heir
curr ent and fut ure developm ent effort s.
As I wr it e t his for ew ord t o Rick Dobson’s book on program m ing Microsoft SQL
Ser ver solut ions wit h Microsoft Visual Basic .NET, I t hink back t o m y own
experiences dev eloping soft war e applicat ions w it h Visual Basic. My first
experience wit h Visual Basic was lear ning t he language using v ersion 3.0. I
rem em ber pick ing up m y first Visual Basic beginner’s book and being excit ed as I
dev eloped m y first few “ Hello, Wor ld” applicat ions. I couldn’t believ e how quick
and easy it was t o dev elop soft ware applicat ions t hat operat ed sim ilar ly t o ot her
popular sharewar e program s of t hat t im e.
Howev er, dur ing t hat t im e I also discov er ed som e of t he short com ings of Visual
Basic as an ent erpr ise- lev el developm ent language. I t was t hen t hat I t ur ned m y
at t ent ion t o C+ + . I r em em ber being v ery frust rat ed at t r y ing t o lear n t he
language, t ry ing t o underst and concept s such as point ers, m em ory allocat ion,
and t rue obj ect - or ient ed program m ing. I t ook classes on C+ + at t he local
universit y , but I got even m or e fr ust rat ed hav ing t o wait m ont hs unt il I was
t aught how t o cr eat e t he sim plest Micr osoft Windows form , som et hing I did in
j ust a couple of m inut es using Visual Basic. I n m y frust rat ion, I gave up t ry ing t o
lear n C+ + and hav e been using Visual Basic t o dev elop soft ware applicat ions ever
since.
As each new v ersion of Visual Basic was r eleased, I readied m yself t o learn new
soft war e developm ent t echnologies. First it was Act iveX cont rol developm ent .
Then it was calling t he Windows API . Next it was DHTML Applicat ions. Then it was
dat abase dev elopm ent using Micr osoft SQL Ser ver. I t alw ays seem ed as t hough I
had t o lear n a new language and a new developm ent paradigm for ev er y new
t echnology t hat cam e along. I kept t hink ing t hat t her e had t o be an easier and
m or e unified appr oach.
Well, now w e’ve r eached t he adv ent of t he Micr osoft .NET plat form , and wit h it , a
revolut ion in t he Visual Basic language, Microsoft Visual Basic .NET. I believ e t hat
Visual Basic .NET will pr ov ide soft ware dev elopers wit h new opport unit ies for
quickly and easily designing int egrat ed soft war e applicat ions t hat connect
businesses and indiv iduals anyt im e, anyw her e, and on v irt ually any soft ware
dev ice. Wit h advances in t he Visual Basic .NET language, Visual Basic . NET
dev elopers will finally be on a par w it h t heir C+ + and C# count erpart s,
part icipat ing in m any high- end dev elopm ent pr oj ect s. Wit h Visual St udio .NET
feat ur es such as cross- language debugging, along w it h Visual Basic .NET
conform ance t o t he com m on t ype syst em and t he com m on language r unt im e,
organizat ions can drive down t heir developm ent cost s by t apping int o t he w ide
range of sk ills t hat Visual Basic .NET dev eloper s now possess.
Tr ue obj ect - orient ed pr ogram m ing is now available in Visual Basic .NET, including
feat ur es such as inher it ance and m et hod ov er loading. I t ’s now sim pler t o call t he
Windows API by using t he .NET Fram ew or k Class Libraries. Web applicat ion
dev elopm ent is now as easy as dev eloping Windows form s–based applicat ions.
Dat abase applicat ion developm ent is m ade easier by unit ing disparat e dat a obj ect
libraries such as DAO, RDO, OLE DB, and ADO under ADO. NET, ut ilizing t he
power of XML t o consum e and t ransm it r elat ional dat a ov er com put er net w orks.
And a new t echnology, XML Web serv ices, allows Visual Basic .NET developers t o
host t heir soft ware applicat ions’ logic ov er t he Web. Addit ionally , a big issue for
soft war e developers t oday is t hat of soft war e applicat ion deploym ent and
versioning. I f y ou don’t agree, j ust ask any soft ware dev eloper about “ DLL hell,”
and y ou’re bound t o get an earful. For m any .NET applicat ions, t he .NET plat form
feat ur es “ copy and past e” or XCOPY deploym ent . ( Users sim ply copy y our
applicat ion files from t he source m edia t o any single direct ory and r un t he
applicat ion. ) And because .NET no longer r elies on t he r egist ry , virt ually all DLL
com pat ibilit y issues go away.
Wit h t his book, Rick aim s t o give you t he sk ills y ou need t o pr ogram SQL Serv er
solut ions wit h Visual Basic .NET. I k now y ou w ill find Rick’s book helpful. Rick
brings his exper ience t o bear from t hree prev ious books: Pr ogram m ing Micr osoft
Access Version 2002 ( Microsoft Press, 2001) , Pr ogram m ing Micr osoft Access 2000
( Micr osoft Press, 1999) , and Pr ofessional SQL Serv er Developm ent wit h Access
2000 ( Wr ox Pr ess I nc., 2000) . Rick also br ings his exper ience of leading a
successful nat ionwide sem inar t our. Mor e im port ant , I know y ou w ill enj oy Rick ’s
book because of his deep int erest in Visual Basic .NET and SQL Ser ver, and in
helping y ou, t he pr ofessional dev eloper, underst and and apply t hese t echnologies
in y our daily soft ware applicat ion dev elopm ent proj ect s.
Paul Cornell MSDN Office Dev eloper Cent er
ht t p: / / m sdn.m icr osoft .com / officeMicrosoft Corporat ion February 2002
Ack now le dgm e nt s
This sect ion offers m e a chance t o say t hank you t o all w ho helped m ak e t his
book possible. I wish t o offer special recognit ion t o five support r esources.
First , t he folks at Microsoft Press have been fant ast ic. Dave Clar k, an acquisit ions
edit or , select ed m e t o w rit e t he book j ust m ont hs aft er I com plet ed anot her book
for Microsoft Press. Dick Br ow n, m y pr oj ect edit or, st aunchly st ood up for his
percept ion of how t o m ake t he book ’s organizat ion and cont ent clear t o y ou
wit hout being pet t y or bor ing t o m e. Dick also light ened m y load subst ant ially by
show ing a real k nack for edit ing m y t ext w it hout dist ort ing t he or iginal int ent .
When Dick was especially busy, he handed off som e of his load t o Jean Ross, who
also did an adm irable j ob. Ot hers at Micr osoft Press who cont r ibut ed t o m y w ell-
being in one way or anot her include Aar on Lavin and Anne Ham ilt on.
Second, I had excellent wor k ing r elat ions wit h sev eral professionals w it hin
Micr osoft . Paul Cor nell, a widely k now n t echnical edit or at Micr osoft , w as kind
enough t o share his insight s on how t o pr esent .NET concept s com pellingly. I
want t o t hank Paul especially for writ ing t he For eword t o t his book. Kart hik
Rav indran serv ed as t he MSXML Bet a Pr oduct Lead Engineer at Microsoft Pr oduct
Support Serv ices dur ing t he t im e t hat I wrot e t his book. He provided valuable
t echnical cont ent about t he SQL Serv er 2000 Web releases. Ot her Microsoft
represent at iv es pr ov iding m oral and t echnical support for t his book include
Richard Waym ir e and Jan Shanahan.
Third, I want t o express m y appreciat ion t o t he m any r eaders, sem inar
at t endees, and sit e v isit ors w ho t ook t he t im e t o t ell m e what I did right or wrong
for t hem , and also t o t hose w ho shared t heir t echnical support quest ions wit h m e.
I t is t hr ough t his k ind of feedback t hat I am able t o k now w hat ’s im port ant t o
pract icing developers. I encourage y ou t o visit m y m ain Web sit e
( ht t p: / / www .pr ogram m ingm saccess.com ) and sign t he guest book. The ent ry
for m includes space for you t o leave your evaluat ion of t his book or y our quest ion
about a t opic cov er ed in t he book . I prom ise t o do m y best t o r eply per sonally. I n
any ev ent , I definit ely r ead all m essages and use t hem so t hat I can serv e y ou
bet t er w it h fut ur e edit ions of t his, and ot her, books.
Fourt h, I want t o t ell t he w orld how grat eful I am t o m y w ife, Virginia. Wit hout
Virginia’s warm support , lov e, and care, t his book w ould be less professional. She
reliev es m e of near ly ev er y r esponsibilit y around t he house w hen I undert ak e a
book proj ect . I n addit ion, she offers st rat egic advice on t he issues t o address and
t heir st yle of cov erage. When I r un out of t im e, she ev en pit ches in w it h t he
proofreading.
Fift h, it is im port ant for m e t o give praise and glory t o m y Lord and Sav ior, Jesus
Chr ist , w ho I believe gave m e t he st rengt h and wisdom t o w r it e t his book. I n
addit ion, He gav e m e healt h dur ing t he long gest at ion per iod t hat result ed in t he
birt h of t his book . I t is m y prayer t hat t he book pr ov e t o be a blessing t o y ou.
I nt r odu ct ion
Any one w ho buys a book —or considers buy ing it —want s t o k now w ho t he book is
for , w hat set s it apart fr om ot hers lik e it , and how t he book is organized. This
int r oduct ion cov ers t hose t hr ee quest ions, and it also discusses syst em
requir em ent s, sam ple files, and support .

    •   First , w h o is t h e b ook for ? Ther e ar e at least t wo answers t o t his
        quest ion. One answ er is t hat t he book t arget s professional dev elopers
        ( and ot hers aspir ing t o be pr ofessional dev elopers) . The second group t he
        book addr esses is t hose who want t o build full- feat ured, secure SQL
        Serv er solut ions wit h Visual Basic .NET.
    •   Se con d, w h a t ’s sp ecia l a bou t t h e b ook ? I hope you com e t o believ e
        t hat t he m ost im port ant answer t o t his quest ion is t hat t he book
        consider ed qualit y and dept h of coverage m or e im port ant t han r ushing t o
        m arket . The book w ill arr iv e on bookshelv es m or e t han t hr ee m ont hs aft er
        t he official release of t he . NET Fram ew ork. I t is m y w ish t hat you der iv e
        value from t he ext ra t im e t ak en t o develop t he m any code sam ples and
        t he in- dept h discussions of advanced t opics, such as class inher it ance,
        ASP.NET, and XML Web serv ices.
    •   Th ird , h ow is t h e b ook org an iz e d? The short answer is t hat t her e ar e
        t wo m ain sect ions. One sect ion int roduces SQL Ser ver concept s as it
        dem onst rat es T- SQL ( Tr ansact SQL) pr ogram m ing t echniques. Aft er
        conv ey ing SQL Ser ver basic building blocks in t he first part , t he second
        part rev eals how t o put t hose part s t oget her w it h Visual Basic .NET and
        relat ed t echnologies int o SQL Ser ver solut ions for handling com m on
        dat abase chores.

The t hr ee support it em s include a br ief descr ipt ion of t he book’s com panion CD
and how t o use it , Micr osoft Pr ess Support I nfor m at ion for t his book, and a
sum m ary of syst em and soft war e requirem ent s for t he sam ple code pr esent ed in
t he book.




W ho’s t h e Book For ?
This book t arget s pr ofessional Visual Basic and Visual Basic for Applicat ions
dev elopers. From m y sem inar t ours and Web sit es
( ht t p: / / www .pr ogram m ingm saccess.com and ht t p: / / www.cabinc.net ) , I know
t hat t hese professionals ar e dr iven by a passion t o deliv er solut ions t o t heir
client s t hrough applying t he m ost innov at iv e t echnologies t heir client s w ill accept .
I n- house dev elopers are t he go- t o persons for get t ing result s fast — part icular ly for
cust om in- house sy st em s and dat abases. I ndependent developers specialize in
serv ing niche sit uat ions t hat can include under - ser ved business needs and w or k
ov erflows. I n bot h cases, t hese pr ofessionals need t raining m at erials t hat addr ess
pract ical business requir em ent s w hile showcasing innov at ive t echnologies wit hout
wast ing t heir t im e. This book st rives t o ser ve t his broad need in t w o specific
areas.
This book is for developers look ing for code sam ples and st ep- by - st ep inst ruct ions
for building SQL Ser ver 2000 solut ions wit h Visual Basic .NET. The book focuses
on t he int egrat ion of SQL Serv er 2000 w it h .NET t echnologies t apped v ia Visual
Basic .NET. I t is m y fir m belief t hat y ou cannot creat e gr eat SQL Ser v er solut ions
in any program m ing language w it hout k nowing SQL Server. Therefore, t his book
goes beyond t radit ional coverage of SQL Serv er for Visual Basic dev elopers. You’ll
lear n T- SQL pr ogram m ing t echniques for dat a access, dat a m anipulat ion, and
dat a definit ion. A whole chapt er equips you t o secur e your SQL Ser ver solut ions.
I n addit ion, t her e’s plent y of cont ent in t his book on Visual Basic .NET and relat ed
t echnologies, such as ADO.NET, ASP.NET, XML ( Ex t ensible Mark up Language) ,
and XML Web serv ices. The present at ion of t hese t echnologies dem onst rat es
coding t echniques and ex plor es concept s t hat equip y ou t o build bet t er solut ions
wit h SQL Ser ver 2000 dat abases. I n addit ion, t he book highlight s innovat ions
int r oduced t hrough t he Web releases for SQL Serv er 2000 t hat int egrat e SQL
Ser ver 2000 t ight ly w it h Visual Basic .NET.
This isn’t a book about XML, but t hr ee of t he book ’s 13 chapt ers focus in w hole or
in part on XML. Therefore, t hose seek ing pract ical dem onst rat ions of how t o use
XML w it h SQL Ser ver and Visual Basic .NET w ill deriv e value fr om t his book . I f
you hav e look ed at any of t he com put er m agazines ov er t he past couple of y ears,
you k now t hat XML is com ing t o a solut ion near you. However, t he rapid pace of
XML innovat ion m ay have dissuaded som e fr om j um ping on t he bandwagon w hile
t hey wait t o see w hat ’s going t o last and what ’s j ust a fad. I n t he book’s t hr ee
chapt ers on XML t echnology, you’ll learn about XML docum ent s, fragm ent s, and
for m at t ing as w ell as r elat ed t echnologies, such as XPat h ( XML Pat h Language)
quer ies, XSLT ( Ext ensible St y lesheet Language Transform at ion) , and WSDL ( Web
Ser vices Descript ion Language) .




W ha t ’s Spe cia l Abou t Th is Book ?
Ther e ar e sev eral feat ur es t hat m ake t his book st and apart from t he flood of
books on .NET. One of t he m ost im port ant of t hese is t hat t his book didn’t rush t o
m ark et but rat her shipped m ont hs aft er t he r elease of t he .NET Fram ew ork . This
allowed m e enough t im e t o filt er, exam ine, and uncov er w hat w er e t he m ost
useful and innovat iv e feat ur es for Visual Basic .NET developers building SQL
Ser ver solut ions. For ex am ple, t he book includes a whole chapt er on creat ing
solut ions wit h XML Web serv ices. That chapt er includes t wo m aj or sect ions on t he
SQL Ser ver 2000 Web Serv ices Toolk it , w hich didn’t ship unt il t he day of t he .NET
Fram ew ork release.
The .NET Fram ew ork cont ent is at a professional lev el, but it isn’t j ust for t echies.
This book doesn’t assum e any pr ior know ledge of t he .NET Fr am ew ork . I t does
assum e t hat you get paid for building solut ions program m at ically and t hat at least
som e of t hose solut ions are for SQL Serv er dat abases. Ther efor e, t he book
explains basic .NET concept s and dem onst rat es how t o achiev e pract ical result s
wit h t hose concept s t hr ough a huge collect ion of .NET code sam ples.
This book is about building solut ions for SQL Ser ver 2000. I include coverage of
t he m any special feat ur es t hat t ie Visual Basic .NET and SQL Serv er 2000 closely
t o one anot her. Alt hough t here is coverage of general .NET dat abase t echniques,
t his book div es deeply int o T- SQL pr ogr am m ing t echniques so t hat y ou can creat e
your own cust om dat abase obj ect s, such as t ables, st or ed pr ocedur es, views,
t riggers, and user - defined funct ions. I n addit ion, t her e is separat e cov erage of
t he XML feat ures released w it h SQL Serv er 2000 as well as separat e coverage of
t he XML feat ures in t he first t hr ee Web releases t hat shipped for SQL Ser ver
2000. There ar e num er ous code sam ples t hroughout t he book. These will equip
you t o build solut ions w it h Visual Basic .NET, T- SQL, and com binat ions of t he t wo.
Finally, t his book is special because of t he unique exper iences of it s aut hor, Rick
Dobson. I have t rained professional dev elopers in Aust ralia, England, Canada,
and t hr oughout t he Unit ed St at es. This is m y fourt h book in four years, and you
can find m y art icles in popular publicat ions and Web sit es, such as SQL Serv er
Magazine and MSDN Online. As a Webm ast er , m y m ain sit e
( ht t p: / / www .pr ogram m ingm saccess.com ) serv es hundr eds of t housands of
sessions t o dev elopers each y ear. I const ant ly ex am ine t heir v iewing habit s at t he
sit e t o det erm ine w hat int erest s t hem . I n addit ion, m y sit e feat ures scores of
answers t o t echnical support quest ions subm it t ed by professional developers. My
goal in offer ing answers t o t hese quest ions is t o st ay in t ouch w it h pract icing
dev elopers wor ldw ide so t hat m y new book s address t he needs of pract icing,
professional dev elopers.




H ow ’s t h e Book Or ga n ized?
Ther e ar e t wo m ain part s t o t his book t ied t oget her by an int roduct ory part . Part
I I , t he first m ain part , dwells on SQL Ser ver t echniques. Part I I I builds on t he
SQL Ser ver background as it lays a firm foundat ion in .NET t echniques for Visual
Basic .NET dev elopers. Part I , t he int r oduct ory part , dem onst rat es way s t o use
SQL Ser ver and Visual Basic .NET t oget her.

Pa r t I , I nt r odu ct ion

Part I , w hich includes only Chapt er 1, has t hree m ain goals. First , it acquaint s y ou
wit h t he basics of Visual Basic .NET w it hin Visual St udio .NET. You can t hink of
Visual Basic .NET as a m aj or upgrade t o t he Visual Basic 5 or 6 t hat you are
probably using cur rent ly . This first sect ion int r oduces som e concept s t hat you w ill
find useful as y ou init ially learn t he landscape of Visual Basic .NET. The second
goal of Chapt er 1 is t o int r oduce ADO.NET. I f y ou t hink of Visual Basic .NET as a
m aj or upgrade t o Visual Basic 6, ADO. NET is m or e lik e a m aj or overhaul of ADO.
I n t wo sect ions, you get an int roduct ion t o ADO.NET classes— part icular ly as t hey
relat e t o SQL Serv er— and y ou get a chance t o see a couple of beginner sam ples
of how t o creat e SQL Serv er solut ions w it h Visual Basic .NET and ADO.NET. The
t hird goal of t he int roduct ory part is t o ex pose y ou t o Query Analy zer . This is a
SQL Ser ver client t ool t hat ships w it h all com m ercial edit ions of SQL Ser ver 2000.
You can t hink of it as an I DE for T- SQL code. Most of t he book’s first par t relies
heav ily on T- SQL, and t her efor e hav ing a conv enient env ir onm ent for debugging
and running T- SQL code is helpful. The final sect ion of Chapt er 1 addresses t his
goal.

Pa r t I I , SQL Se r v e r

Part I I consist s of six r elat iv ely short chapt ers t hat focus subst ant ially on
program m ing SQL Serv er 2000 w it h T- SQL. Chapt er 2 and Chapt er 3 int r oduce T-
SQL and SQL Serv er dat a t ypes. I f y ou ar e going t o program SQL Ser ver and
creat e efficient , fast solut ions, y ou m ust lear n SQL Ser ver dat a t ypes, which is
one of t he m ain point s conveyed by Chapt er 2. Many r eaders w ill grav it at e t o
Chapt er 3 because it int roduces cor e T- SQL pr ogram m ing t echniques for dat a
access. You’ll apply t he t echniques covered in t his chapt er oft en as y ou select
subset s of r ows and colum ns in dat a sources, group and aggregat e row s from a
t able, pr ocess dat es, and j oin dat a fr om t w o or m or e t ables. Chapt er 3 also
considers special dat a access t opics, such as out er j oins, self j oins and
subquer ies.
The next pair of chapt er s in Part I I , Chapt er 4 and Chapt er 5, t ak e a look at
program m ing dat abase obj ect s t hat you w ill use for dat a access and dat a
m anipulat ion, such as v iews, st ored procedures, user - defined funct ions, and
t riggers. These dat abase obj ect s are im port ant for m any reasons, but one of t he
m ost im port ant is t hat t hey bundle T- SQL st at em ent s for t heir easy r euse. I t is
widely k now n t hat t he best code is t he code t hat you don’t hav e t o wr it e.
Howev er, if y ou do have t o w rit e code, y ou should definit ely wr it e it j ust onc, and
t hen reuse it w henev er you need it s funct ionalit y. St or ed pr ocedur es are
part icular ly desirable dat abase obj ect s because t hey save com piled T- SQL
st at em ent s t hat can deliv er significant speed advant ages ov er r esubm it t ing t he
sam e T- SQL st at em ent for com pilat ion each t im e y ou want t o perform a dat a
access or dat a m anipulat ion t ask. Chapt er 4 and Chapt er 5 ar e also im port ant
because t hey conv ey T- SQL sy nt ax for using param et ers and condit ional logic
t hat support dy nam ic r un- t im e behav ior and user int eract iv it y.
One of t he m ost im port ant feat ur es of SQL Ser ver 2000 is it s XML funct ionalit y .
Because XML as a t opic is changing so rapidly, Micr osoft adopt ed a st rat egy of
upgrading t he SQL Serv er 2000 XML funct ionalit y t hrough Web releases. Alt hough
t hose w it h SQL Serv er 2000 can dow nload t he Web releases w it hout charge from
t he Microsoft Web sit e, t he Web r eleases ar e fully support ed. Chapt er 6
int r oduces core XML funct ionalit y int roduced w it h SQL Ser ver 2000 as w ell as
funct ionalit y fr om t he fir st t wo Web r eleases. I n part icular, y ou can learn in t his
chapt er about I I S v irt ual direct ories as well as form at s for XML docum ent s and
schem as. You also learn about t em plat es in virt ual dir ect or ies t hat facilit at e dat a
access and dat a m anipulat ion t asks over t he Web.
Chapt er 7 closes out t he SQL Ser ver part of t he book w it h an in- dept h look at
program m ing SQL Serv er secur it y . I n t hese t im es, secur it y has grown int o a
m onum ent al t opic, and t his chapt er can k eep y ou out of t rouble by blocking
hackers from get t ing int o or corr upt ing y our dat abase. You learn such t opics as
how t o creat e and m anage differ ent t y pes of login and user account s and how t o
cont r ol t he perm issions available t o indiv idual account s as well as gr oups of
account s. By learning how t o script account s and perm issions w it h T- SQL, y ou
sim plify r ev ising and updat ing secur it y as condit ions change ( for exam ple, w hen
users leav e t he com pany or w hen new , sensit iv e dat a get s added t o a t able) .

Pa r t I I I , .N ET

Chapt er 8 st art s t he .NET part of t he book w it h a r ev iew of select ed .NET t opics
t hat ar e cover ed in t he init ial look Chapt er 1 offer ed at t he .NET Fram ewor k. This
chapt er pr ov ides an ov erv iew of t he archit ect ur e for .NET solut ions, and it dr ills
down on t wo t opics: ASP.NET and XML Web ser vices. The general purpose of t his
chapt er is t he sam e as Chapt er 1, w hich is t o int r oduce concept s. The em phasis
in Chapt er 8 isn’t how y ou do som et hing, but rat her w hat are t he m aj or
t echnologies enabling y ou t o do som et hing. Chapt er 1 and Chapt er 8 are bot h
relat iv ely short chapt ers, but you m ay find t hem invaluable if y ou are t he k ind of
person w ho benefit s from high- lev el ov er views of a collect ion of t opics.
Chapt er 9 st art s wit h a close exam inat ion of how t o use Windows Form s wit h
Visual Basic .NET. I t t hen shift s it s focus t o a review of t radit ional class
processing concept s via Visual Basic .NET as an int r oduct ion t o class inherit ance,
a new obj ect - or ient ed feat ure t hat m ak es it s fir st appearance in Visual Basic w it h
Visual Basic .NET. Next t he t r eat m ent of classes progr esses t o t he handling of
built - in ev ent s as w ell as t he raising of cust om ev ent s. Finally t he chapt er closes
wit h an exam inat ion of t he new except ion handling t echniques for pr ocessing r un-
t im e errors.
Chapt er 10 is a how - t o guide for solut ions t o t y pical pr oblem s w it h ADO.NET.
Befor e launching int o it s progr ession of sam ples show ing how t o perform all k inds
of t asks, t he chapt er st art s wit h an ov er v iew of t he ADO.NET obj ect m odel t hat
covers t he m ain obj ect s along w it h select ed propert ies and m et hods for each
obj ect . The how - t o guide focuses on dat a access t asks, such as select ing rows
and colum ns fr om SQL Ser ver dat abase obj ect s, as well as dat a m anipulat ion
t asks, such as insert ing, updat ing, and delet ing rows in a t able. Work ing t hr ough
t he sam ples in t he how - t o guide offers a hands- on feel for using t he
Syst em .Dat a.SqlClient nam espace elem ent s t o per form t ypical t asks.
Chapt er 11 swit ches t he focus t o t he Web by addressing t he cr eat ion and use of
ASP.NET solut ions. This chapt er st art s by int r oducing basic elem ent s t hat you
need t o k now in order t o use ASP.NET t o cr eat e great Web solut ions wit h Visual
Basic .NET. These include lear ning w hat happens as a page does a r ound- t r ip
from a browser t o a Web serv er and back t o t he br owser— part icularly for dat a
associat ed wit h t he page. Ot her pr elim inary t opics t hat equip y ou for building
professional Web solut ions include running t he sam e page in m ult iple br owser
t ypes and sniffing t he browser for cases in w hich y ou want t o send a page
opt im ized for a specific kind of browser t ype. Managem ent of session st at e is a
m aj or t opic in t he chapt er , and y ou lear n how t o use enhancem ent s t o Session
variables for Web farm s as well as t he new v iew st at e var iables, a non- ser ver -
based t echnique for m anaging st at e in ASP.NET solut ions. The last t wo sect ions in
t he chapt er deal w it h ADO.NET t opics in ASP.NET solut ions and t he new
aut om at ic dat a validat ion feat ur es built r ight int o ASP.NET.
The last t wo chapt ers in t he book explor e how XML int erplays wit h Visual St udio
.NET and SQL Ser ver 2000. For exam ple, Chapt er 12 exam ines special t ools in
Visual St udio .NET t o facilit at e t he design and edit ing of XML docum ent s and
schem as. I n addit ion, y ou learn how t o designat e XPat h queries t hat accept run-
t im e input for r et ur ning SQL Ser ver result set s inside Visual Basic .NET program s.
The chapt er dem onst rat es t echniques for processing t he XML docum ent
associat ed wit h all ADO. NET dat a set obj ect s. I n t he chapt er’s last sect ion, I
present a couple of code sam ples t hat illust rat e how t o pr ogram st at ic HTML
pages based on XML docum ent s wit h XSLT.
Ch a pt e r 1 3 dr ills dow n on XML Web serv ices by dem onst rat ing several differ ent
approaches for cr eat ing Web serv ices as well as consum ing XML out put from Web
serv ices. Web serv ices behave som ewhat like COM obj ect s in t hat y ou can set up
serv er applicat ions for client applicat ions. The ser ver applicat ions expose m et hods
t o w hich t he client applicat ions can pass param et ers. XML com es int o play wit h
Web serv ices in a couple of areas. First , Web ser vices repr esent t heir input s and
out put s v ia WSDL, an XML- based language t hat form ally describes an XML Web
serv ice. Second, Web ser vices ret urn dat a t o t heir client s as XML docum ent s or
docum ent fragm ent s.




Syst e m Re qu ir e m en t s
The requir em ent s for t his book var y by chapt er. I developed and t est ed all
sam ples t hroughout t his book on a com put er equipped wit h Windows 2000
Ser ver, SQL Serv er Ent erprise Edit ion, and t he Ent erprise Dev eloper Edit ion of
Visual St udio .NET, w hich includes Visual Basic .NET. To use t his book, y ou’ll need
t o have Visual Basic .NET or Visual St udio .NET inst alled on your com put er . ( See
Chapt er 1 for m or e inform at ion on v ersions of Visual Basic .NET and Visual St udio
.NET.) I n addit ion, y ou’ll need SQL Serv er 2000, and for som e of t he chapt ers,
you’ll need SQL Serv er 2000 updat ed wit h Web r eleases 1, 2, and 3. Chapt er 6
giv es t he URLs for downloading Web r eleases 1 and 2. Chapt er 12 giv es t wo
different URLs for downloading Web Release 3— one w it h t he SQL Serv er 2000
Web Ser v ices Toolk it and t he ot her wit hout it .
For select ed chapt ers, y ou can run t he sam ples wit h less soft ware or different
operat ing syst em s t han t he one t hat I used. For exam ple, chapt ers 2 t hrough 5
will run on any operat ing syst em t hat support s a com m ercial version of SQL
Ser ver 2000, such as Windows 98 or a m or e recent Windows operat ing syst em .
Chapt er 7 r equires an operat ing syst em t hat support s Windows NT secur it y , such
as Windows 2000 or Windows XP Professional. Chapt er 6, Chapt er 11, and
Ch a pt e r 1 3 r equir e Microsoft I nt ernet I nform at ion Serv ices ( I I S) . I n addit ion,
Chapt er 6 r equires t he inst allat ion of Web r eleases 1 and 2. For Chapt er 11, your
syst em needs t o m eet t he m inim um requirem ent s for ASP.NET. ( See a not e in t he
“How Does ASP.NET Relat e t o ASP?” sect ion of Chapt er 8.) Several of t he
sam ples in Ch ap t er 1 3 require Web Release 3 and it s associat ed SQL Ser ver
2000 Web Serv ices Toolkit .




Sa m ple File s
Sam ple files for t his book can be found at t he Microsoft Press Web sit e, at
ht t p: / / www .m icrosoft .com / m spress/ books/ 5792.asp. Click ing t he Com panion
Cont ent link t ak es you t o a page fr om w hich y ou can dow nload t he sam ples.
Supplem ent al cont ent files for t his book can also be found on t he book’s
com panion CD. To access t hose files, insert t he com panion CD int o y our
com put er’s CD- ROM dr ive and m ake a select ion fr om t he m enu t hat appears. I f
t he Aut oRun feat ure isn’t enabled on y our sy st em ( if a m enu doesn’t appear when
you insert t he disc in y our com put er ’s CD- ROM drive) , r un St art CD.ex e in t he r oot
folder of t he com panion CD. I nst alling t he sam ple files on y our hard disk requir es
approx im at ely 15.3 MB of disk space. I f y ou have t rouble r unning any of t hese
files, r efer t o t he t ext in t he book t hat describes t hese pr ogr am s.
Aside from t he sam ple files t hat t his book discusses, t he book ’s supplem ent al
cont ent includes a st and- alone eBook inst allat ion t hat w ill allow y ou t o access an
elect ronic v ersion of t he pr int book direct ly from your deskt op.




Su ppor t
Ev er y effort has been m ade t o ensure t he accur acy of t his book and t he cont ent s
of t he com panion CD. Microsoft Press pr ov ides cor rect ions for books t hr ough t he
World Wide Web at t he follow ing address:
ht t p: / / www .m icrosoft .com / m spress/ support
To connect dir ect ly t o t he Micr osoft Pr ess Know ledge Base and ent er a query
regarding a quest ion or an issue t hat you m ay have, go t o:
ht t p: / / www .m icrosoft .com / m spress/ support / search.asp
I f you have com m ent s, quest ions, or ideas r egarding t his book or t he com panion
cont ent , or quest ions t hat are not answered by query ing t he Know ledge Base,
please send t hem t o Microsoft Pr ess via e- m ail t o:
m spinput @m icrosoft .com
Or v ia post al m ail t o:
Micr osoft Pr ess At t n: Pr ogram m ing Micr osoft SQL Ser ver 2000 w it h Microsoft
Visual Basic .NET Edit or One Microsoft Way Redm ond, WA 98052- 6399
Please not e t hat product support is not offer ed t hr ough t he above m ail address.
For product support inform at ion, please visit t he Microsoft Support Web sit e at :
ht t p: / / support .m icr osoft .com
Cha pt e r 1 . Ge t t ing St a r t e d w it h Visua l
Ba sic .N ET for SQL Se r v e r 2 0 0 0
This book aim s t o giv e professional dev elopers t he background t hat t hey need t o
program SQL Ser ver applicat ions w it h Micr osoft Visual Basic .NET. This ov erall
goal im plies t hree guidelines:

   •   First , t he book t arget s pract icing dev elopers. I n m y exper ience, t hese ar e
       busy pr ofessionals who need t he det ails fast . These indiv iduals alr eady
       know how t o build applicat ions. They buy a book t o lear n how t o build
       t hose applicat ions wit h a specific set of t ools.
   •   Second, t he book is about building applicat ions for SQL Ser ver 2000. This
       focus j ust ifies in- dept h coverage of SQL Serv er program m ing t opics— in
       part icular, T- SQL, Micr osoft ’s ext ension of t he St ruct ured Query Language
       ( SQL) .
   •   Third, t he book illust rat es how t o pr ogr am in Visual Basic .NET, but w it h
       part icular em phasis on dat abase issues for SQL Ser ver 2000. Special
       at t ent ion goes t o relat ed .NET t echnologies, such as t he .NET Fram ew ork,
       ADO.NET, ASP.NET, and XML Web ser vices.

My goal in t his chapt er is t o equip y ou concept ually for t he r est of t he book .
Ther efor e, t his chapt er includes m at er ial t hat acquaint s y ou w it h applicat ion
dev elopm ent t echniques and t opics for SQL Serv er 2000 and Visual Basic .NET.
The discussion of t he sam ples in t his chapt er generally aim s t o convey broad
approaches inst ead of how t o r un t he sam ple. All t he r em aining chapt ers except
for Chapt er 8, anot her concept ual chapt er , hav e sam ples w it h inst ruct ions aim ed
at professional dev elopers.
I believe t hat t he overw helm ing m aj or it y of pr ofessional Visual Basic developers
hav e no hands- on fam iliarit y wit h Visual Basic .NET and it s relat ed t echnologies.
I f you already knew Visual Basic .NET, it wouldn’t m ake any sense t o buy a book
describing how t o use it . This chapt er t herefore focuses on how t o get st art ed
wit h Visual Basic .NET and one of it s cor e r elat ed t echnologies for t hose building
SQL Ser ver applicat ions— ADO. NET. I also believ e t hat m ost Visual Basic
dev elopers don’t have an int im at e know ledge of SQL Serv er — especially for
creat ing user - defined obj ect s, such as t ables, v iews, and st or ed procedur es. This
capabilit y can em pow er you t o build m or e pow erful and m or e secure applicat ions.
As y ou lear n about dat abase obj ect s and how t o creat e t hem in Chapt er 2
t hr ough Chapt er 7, reflect back on t he Visual Basic .NET cov erage in t his chapt er
and how t o m ar ry dat abase creat ion t echniques and Visual Basic .NET
dev elopm ent t echniques. One of t he best t ools t o build dat abase obj ect s is SQL
Ser ver 2000 Query Analyzer . This chapt er’s closing sect ion conveys t he basics of
Query Analyzer t hat you need t o follow t he sam ples in Chapt er 2 t hrough Chapt er
7.




Visua l St u dio .N ET, t h e V isu a l Ba sic .N ET I D E
Visual St udio .NET is t he new m ult ilanguage int egrat ed developm ent env ir onm ent
( I DE) for Visual Basic, C# , C+ + , and JScr ipt developers. I f you are dev eloping
solut ions for Visual Basic .NET, I definit ely r ecom m end t hat you use Visual St udio
.NET as y our dev elopm ent envir onm ent . This sect ion dem onst rat es how t o get
st art ed using Visual St udio .NET for dev eloping solut ions wit h Visual Basic .NET.
Visual Basic .NET is available as part of Visual St udio .NET in four edit ions:

    •   Professional
    •   Ent erpr ise Dev eloper
    •   Ent erpr ise Archit ect
    •   Academ ic

All four edit ions of Visual St udio .NET include Visual Basic .NET, Micr osoft Visual
C# .NET, Microsoft Visual C+ + .NET, and support for ot her languages. I n
addit ion, Microsoft offer s Visual Basic .NET St andard, w hich doesn’t include Visual
C# .NET or Visual C+ + .NET.
Because t his book t arget s professional Visual Basic dev elopers creat ing SQL
Ser ver applicat ions, it uses t he Ent erpr ise Developer Edit ion of Visual St udio
.NET. You m ay not ice som e differ ences if y ou’r e using anot her edit ion.
Visual St udio .NET can be inst alled on com put ers r unning one of five operat ing
syst em s: Windows 2000, Windows NT, Window s XP, Windows ME, and Windows
98. Not all t he .NET Fram ework feat ures are av ailable for each operat ing syst em .
For exam ple, Windows 98, Windows Me, and Windows NT don’t support
dev eloping ASP.NET Web applicat ions or XML Web serv ices applicat ions. The
sam ples for t his book ar e t est ed on a com put er running Windows 2000 Ser ver,
which does support all .NET Fram ew or k feat ur es.

St a r t ing V isu a l St udio .N ET

To open Visual St udio .NET, click t he St art but t on on t he Windows t ask bar,
choose Program s, and t hen choose Micr osoft Visual St udio .NET. Visual St udio
displays it s int egrat ed dev elopm ent env ironm ent , including t he St art Page ( unless
you prev iously configur ed Visual St udio t o open different ly ) . Fr om t he St art Page,
you can configure Visual St udio t o w ork according t o y our dev elopm ent
preferences, and y ou can st art new solut ions as well as open ex ist ing pr oj ect s.

Con figu r ing V isu a l St udio .N ET f or Visua l Ba sic .N ET

Use t he links on t he left side of t he St art Page t o begin configur ing Visual St udio
.NET for developing solut ions in Visual Basic .NET. Click t he My Pr ofile link t o
open a pane in w hich you can specify an overall profile as w ell as indiv idually
indicat e y our preferences for Keyboard Schem e, Window Lay out , and Help Filt er.
You also can designat e t he init ial page t hat Visual Basic .NET displays. When y ou
are beginning, it m ay be part icular ly conv enient t o choose Show St art Page. As a
Visual Basic dev eloper who has work ed w it h Visual Basic 6, y ou m ight feel m ost
fam iliar w it h a lay out t hat reflect s y our pr ior developm ent env ir onm ent . Figure 1-
1 shows t hese My Pr ofile select ions.

   Figu re 1 - 1 . M y Profile se le ct ion s for st a r t in g V isu al St u dio .N ET for a
                               V isu a l Ba sic de velop e r.
Usin g t h e St a r t Pa ge

Aft er set t ing your pr ofile, you can r et urn t o t he init ial St art Page pane by
choosing t he Get St art ed link from t he m enu on t he left border. I f you had
creat ed pr ev ious solut ions, t he last four m odified proj ect s would appear on t he
Proj ect s t ab of t he St art Page. The t ab shows pr oj ect nam es along w it h dat e last
m odified. I f a pr oj ect y ou want t o v iew doesn’t appear on t he list , you can click
t he Open Proj ect link t o display t he Open Proj ect dialog box and t hen navigat e t o
a direct ory cont aining t he pr ev iously cr eat ed solut ion. Select t he proj ect ’s folder
t hat y ou want t o open in t he I DE, and double- click t he solut ion file ( .sln) for t he
proj ect . The next sect ion illust rat es t his pr ocess in t he cont ext of a sam ple
proj ect .
To cr eat e a new solut ion, click t he New Pr oj ect link t o open t he New Pr oj ect
dialog box . I f y ou saved prefer ences such as t hose show n in Figure 1- 1, t he
dialog w ill aut om at ically select Visual Basic Proj ect s in t he Proj ect Types pane of
t he New Proj ect dialog box. On t he r ight , y ou can select a t em plat e for launching
a proj ect . Table 1- 1 shows t he pr oj ect t em plat e nam es along w it h a br ief
descript ion av ailable from t he Ent erpr ise Dev eloper Edit ion of Visual St udio .NET.
Choosing a t em plat e ( by clicking OK aft er select ing a t em plat e) opens a proj ect
ready for creat ing t he t ype of solut ion t hat y ou want t o dev elop. When Visual
St udio .NET sav es t he t em plat e t o st art a new proj ect , it specifies eit her a file
folder or a Web sit e for t he t em plat e’s files; y ou can overr ide t he default nam es
for t he file folder and Web sit e.
                                    N ot e
Not all t he pr oj ect t em plat e t ypes in Table 1- 1 are available
wit h t he non- Ent er prise ( or St andard) edit ions of Visual
St udio .NET. I n addit ion t o t he em pt y proj ect s, t he St andar d
edit ions m ak e available t he Windows Applicat ion, ASP.NET
Web Applicat ion, ASP.NET Web Serv ice, and Console
Applicat ion t em plat es.
                    7DEOH  9LVXDO %DVLF 1(7 3URMHFW 7HPSODWH 7\SHV

   7HPSODWH 1DPH                                     &UHDWHV $
Windows                Windows applicat ion w it h a form
Applicat ion
Class Library          Windows applicat ion suit able for a library of classes wit hout a
                       for m
Windows Cont r ol      Proj ect for dev eloping cust om reusable form cont r ols for
Librar y               Windows applicat ions
ASP.NET Web            Web applicat ion on a Web server
Applicat ion
ASP.NET Web            XML Web serv ice on a Web serv er
Ser vice
Web Cont r ol Librar y Proj ect for dev eloping cust om reusable cont r ols for Web
                       applicat ions
Console Applicat ion Com m and line applicat ion t hat operat es in an MS- DOS–st y le
                     window ( t he Console)
Windows Serv ice       Windows serv ice, form erly NT serv ice, applicat ion t hat runs
                       in t he background w it hout it s ow n cust om user int erface
Em pt y Pr oj ect      Local pr oj ect wit h no cust om st yle
Em pt y Web Pr oj ect Web proj ect wit h no cust om st yle
New Pr oj ect I n        Blank proj ect in an ex ist ing folder
Ex ist ing Folder
Ther e ar e t wo m ain cat egor ies of t em plat es: Web pr oj ect s and local proj ect s. Web
proj ect s perm it a browser t o serv e as t he client for a proj ect . Web pr oj ect s are
opt im ized for form processing on t he Web ser v er . Local pr oj ect s offer cust om
for m user int erfaces wit h t he capabilit y of processing on a local w orkst at ion. Local
proj ect s can pr ov ide richer env ir onm ent s m or e conduciv e t o client - side
program m ing, but local proj ect s don’t offer t he wide accessibilit y of solut ions
running fr om a Web ser ver.

Cr e a t in g a n d Run n in g a Con sole Applica t ion

When y ou select a Console Applicat ion t em plat e and click OK t o launch a new
proj ect , Visual St udio .NET r esponds by opening a pr oj ect w it h a blank m odule. I n
addit ion t o t he Module window, Visual St udio displays Solut ion Explorer and t he
Propert ies w indow. You can ent er code dir ect ly int o t he Module w indow, which
appears as a t ab t hat y ou can select alt er nat ely w it h t he St art Page. Figur e 1- 2
shows a code sam ple in t he Main subrout ine t hat prom pt s for a first and second
nam e before com bining t hem and display ing t hem in t he Console ( t he com put er’s
m onit or ) . The code is also available as MyNam eI sFrom Console in t he Chapt er 1
folder on t he com panion CD for t his book . Alt hough Visual Basic dev elopers didn’t
prev iously have Console applicat ions rout inely available, t his sam ple should be
very easy t o follow. The final t w o lines present an inst ruct ion and cause t he
window t o r em ain open unt il t he user responds t o t he inst ruct ion. This allows t he
user t o v iew t he full nam e in t he Console w indow.

Figu r e 1 - 2 . A Con sole a p plicat ion for displayin g a fu ll n a m e b a se d on u se r
                          inpu t for fir st a n d se con d n am e s.




To t he r ight of t he Module w indow are t w o ot her windows. The t op one of t hese is
Solut ion Explorer. I t shows t he file st r uct ure for t he solut ion. Solut ion Explor er
indicat es in it s first line t hat t he solut ion consist s of j ust one proj ect . Below t hat
line appears t he nam e of t he proj ect , MyNam eI sFrom Console. Wit hin t he proj ect
are t hree ent ries: one each for t he Refer ences, Assem blyI nfo.v b, and Module1.vb
elem ent s wit hin t he solut ion’s proj ect . By default , t he Propert ies window is below
Solut ion Explorer. I n t he Full Pat h pr opert y t ext box is an excerpt show ing t he
pat h t o Module1.vb on m y com put er . When y ou click t he proj ect nam e in Solut ion
Explor er, t he Pr oj ect Folder t ext box in t he Propert ies window displays t he pat h of
t he dir ect ory holding t he solut ion’s files. I t is t his direct ory t hat you copy t o
deploy your solut ion on anot her com put er w it h t he .NET Fram ew or k inst alled. The
solut ion w on’t run wit hout t he com m on language runt im e on t he com put er t o
which you copy t he direct ory cont aining t he .NET Fram ew or k solut ion. See
Chapt er 8 for m or e det ailed cov erage of t he .NET Fram ew or k, including t he
runt im e and dist ribut ing .NET Fram ework solut ions as assem blies of files in
folders.
You can t est r un t he applicat ion by choosing St art from t he Debug m enu, or by
pressing F5. This opens t he Console w indow w it h a prom pt t o ent er a first nam e.
Aft er y ou close y our applicat ion and sav e any changes t o it , y our solut ion appears
on t he St art Page for r ecent solut ions. I f you st art Visual St udio .NET and t he
solut ion y ou want t o open doesn’t appear on t he Proj ect s t ab of t he St art Page,
you can also open t he solut ion by click ing Open Pr oj ect . I n t he Open Pr oj ect
dialog box , choose t he file w it h t he .sln ext ension and t he solut ion’s nam e
( My Nam eI sFrom Console) . A solut ion can cont ain j ust one .sln file, but it can
cont ain m ult iple pr oj ect s.
You also can r un t he solut ion and open t he Console w indow dir ect ly from
Windows Explor er w it hout using Visual St udio .NET. Open t he bin subdirect ory
wit hin t he dir ect ory cont aining t he assem bly folder for t he solut ion. Then double-
click t he My Nam eI sFr om Console.ex e file. This opens t he Console w indow w it h t he
prom pt for a first nam e.




An Ove r view of AD O.N ET Ca pa bilit ie s
ADO.NET encapsulat es t he dat a access and dat a m anipulat ion for t he .NET
Fram ew ork . This sect ion giv es y ou an overv iew of t he t opic t hat equips you for a
st art er sam ple in t he next sect ion. Microsoft chose t he nam e ADO.NET for t he
.NET Fr am ew ork dat a access com ponent t o indicat e it s associat ion w it h t he ear lier
ADO t echnology for dat a access. While t her e ar e som e sim ilarit ies in sy nt ax
bet ween ADO.NET and ADO ( part icular ly for connect ion st r ings) , m any will find
t he differ ences ar e m or e obv ious t han t he sim ilarit ies. These differences
subst ant ially upgrade ADO.NET over ADO in t w o k ey ar eas— scalabilit y and XML
( Ext ensible Mark up Language) int er operabilit y. As a result , y ou w ill be able t o
creat e dat abase applicat ions w it h ADO.NET t hat serv e m or e users and shar e m ore
dat a t han y ou did w it h ADO. See Chapt er 10 for a m or e int ensive exam inat ion of
ADO.NET. Chapt er 12 explicit ly explores int eroperabilit y bet ween ADO. NET and
XML.

.N ET D a t a Pr ovide r Type s

Your .NET Fram ework solut ions requir e .NET dat a providers t o connect t o dat a
sources. These pr ov iders are differ ent fr om t hose used wit h ADO, but t her e are
dist inct sim ilar it ies in som e of t he ways y ou use t hem . Wit h .NET dat a prov iders,
your solut ions can connect , r ead, and ex ecut e com m ands against dat a sources.
The .NET prov iders also offer select ed ot her funct ions, such as t he m anagem ent
of input and out put par am et ers, securit y, t ransact ions, and dat abase ser ver
errors.
Visual St udio .NET ships wit h t wo .NET dat a providers— t he SQL Serv er .NET dat a
prov ider and t he OLE DB .NET dat a pr ov ider. I n addit ion, y ou can dow nload an
ODBC .NET dat a prov ider fr om t he Micr osoft MSDN dow nload sit e
( ht t p: / / m sdn.m icr osoft .com / downloads/ default .asp) .

                                          N ot e
As I writ e t his chapt er , t he ODBC .NET dat a pr ov ider j ust becam e
av ailable wit h t he r ollout of t he shipping version of Visual St udio
.NET. You can download it fr om
ht t p: / / m sdn.m icrosoft .com / downloads/ default .asp?url= / downloads/ s
am ple.asp?url= / m sdn- files/ 027/ 001/ 668/ m sdncom posit edoc.x m l.
The URLs for resour ces som et im es change. You can alway s sear ch
for t he ODBC .NET dat a pr ovider at t he MSDN download sit e t o
obt ain it s curr ent download locat ion.
The t hr ee pr ov iders t ak en t oget her offer fast , highly focused access t o select ed
dat a sources as well as general access t o a w ide range of possible dat a sources.
The SQL Ser ver .NET dat a provider is opt im ized for SQL Ser ver 7.0 and SQL
Ser ver 2000. This dat a prov ider connect s dir ect ly t o a SQL Serv er inst ance.
The OLE DB .NET dat a prov ider connect s t o OLE DB dat a sources t hr ough t w o
int erm ediat e lay ers— t he OLE DB Serv ice Com ponent and t he classic OLE DB
prov ider int roduced along w it h ADO. The OLE DB Serv ice Com ponent m anages
connect ion pooling and t ransact ion serv ices. The classic OLE DB prov ider , in t urn,
dir ect ly connect s t o a dat abase serv er . Micr osoft explicit ly t est ed t he OLE DB .NET
dat a provider w it h SQL Ser ver, Or acle, and Jet 4.0 dat abases. Use t he OLE DB
.NET dat a provider t o connect t o t he SQL Serv er 6.5 v ersion and earlier ones.
This pr ov ider is also good for connect ing t o y our Micr osoft Access solut ions based
on t he Jet 4.0 engine.
The OLE DB .NET dat a prov ider definit ely doesn’t wor k w it h t he OLE DB prov ider
for ODBC dat a sources ( MSDASQL) . Because t he .NET OLE DB dat a pr ovider
doesn’t connect t o ODBC dat a sources, y ou requir e t he ODBC .NET dat a prov ider
for connect ing t o ODBC dat a sources fr om y our .NET Fr am ew ork solut ions.
Ther e ar e four m ain .NET dat a pr ov ider classes for int eract ing w it h a rem ot e dat a
source. The nam es of t hese classes change slight ly for each t ype of pr ov ider, but
each .NET dat a prov ider has t he sam e four kinds of classes. The nam es for t he
SQL Ser ver .NET dat a prov ider classes for int eract ing wit h SQL Server inst ances
are SqlConnect ion, SqlCom m and, SqlDat aReader, and SqlDat aAdapt er. You can
use t he SqlDat aReader class for read- only applicat ions fr om a SQL Serv er dat a
source. Two especially convenient ways t o display r esult s w it h a SqlDat aReader
class are in a m essage box or t he Visual St udio .NET Out put w indow. The
SqlDat aAdapt er class act s as a bridge bet w een a r em ot e SQL Ser ver dat a source
and a Dat aSet class inst ance inside a Visual Basic .NET solut ion.
A dat a set in a Visual St udio solut ion is a fift h t y pe of ADO.NET class. A dat a set
can cont ain m ult iple t ables. A sixt h ADO.NET class is t he Dat aView class, w hich
act s lik e a v iew based on a t able w it hin a Dat aSet obj ect . Windows For m s in
Visual Basic .NET applicat ions can bind only t o t ables w it hin a Dat aSet obj ect and
Dat aView obj ect s. I exam ine t he Dat aSet obj ect lat er in t his sect ion. Chapt er 10
includes a syst em at ic sum m ary of all six ADO.NET classes t hat r ev iews select ed
propert ies and m et hods of each class. The ov er view of ADO.NET classes in
Chapt er 10 is support ed by num erous code sam ples t hat illust rat e how t o
m anipulat e inst ances of t he classes program m at ically .

                                     N ot e
I n or der t o use abbreviat ed nam es, such as t hose list ed in
t his sect ion for t he SQL Serv er .NET dat a pr ovider class
inst ances, y our applicat ion needs a refer ence t o t he SqlClient
nam espace. You can cr eat e such a reference wit h an I m port s
Sy st em .Dat a.SqlClient st at em ent j ust befor e a Module
declarat ion.

SqlCon n e ct ion Cla ss

An inst ance of t he SqlConnect ion class can int erface direct ly w it h a SQL Serv er
dat a source. Use a const ruct or st at em ent t o inst ant iat e a SqlConnect ion obj ect
from t he SqlConnect ion class. The const ruct or st at em ent is a new t ype of sy - nt ax
for .NET Fram ew or k solut ions. This t ype of st at em ent perm it s y ou t o declare,
inst ant iat e, and pass st art up param et ers t o an obj ect based on a class. Wit h t he
SqlConnect ion const ruct or st at em ent , y ou can specify a connect ion st r ing as an
argum ent for t he const r uct or st at em ent . Alt er nat iv ely, you can assign t he
connect ion st r ing t o t he SqlConnect ion obj ect aft er it s inst ant iat ion w it h a
propert y assignm ent st at em ent for t he Connect ionSt ring propert y. The follow ing
line shows t he synt ax t o inst ant iat e a new SqlConnect ion obj ect , My SQLCnn1,
wit h a connect ion st r ing designat ing int egrat ed secur it y t o t he m ydb dat abase on
t he m yserv er inst ance of SQL Serv er. You don’t hav e t o explicit ly indicat e a
prov ider because t he const ruct or st at em ent r ev eals t he t ype of prov ider t hr ough
it s r efer ence t o t he SqlConnect ion class.
Dim MySQLCnn1 As New _
SqlConnection(“Integrated Security=SSPI;" & _
"Data Source=myserver;Initial Catalog=mydb")

Aft er inst ant iat ing a SqlConnect ion obj ect , you need t o invoke it s Open m et hod
befor e t he obj ect can link anot her obj ect based on one of t he ot her SQL Ser ver
.NET dat a provider classes, such as SqlCom m and, SqlDat aAdapt er, or
SqlDat aReader , t o a SQL Serv er inst ance. I nv oke t he Close m et hod t o recover t he
resources for a SqlConnect ion obj ect w hen your solut ion no longer needs it . The
Close m et hod rolls back any pending t ransact ions and releases t he connect ion t o
t he connect ion pool. The Dispose m et hod is also available for r em ov ing
connect ions, but it inv okes t he Close m et hod and perform s ot her .NET
adm inist rat iv e funct ions. Microsoft r ecom m ends t he Close m et hod for r em oving a
connect ion. Unclosed connect ions ar en’t r et urned t o t he connect ion pool.

SqlCom m a n d a n d SqlD a t a Re a de r Cla sse s

One w ay t o put a connect ion t o use is t o em ploy it along w it h t he SqlCom m and
and SqlDat aReader obj ect s. A SqlDat aReader obj ect can m aint ain an open
for ward- only, read- only connect ion w it h a SQL Ser ver dat abase. While t he
SqlDat aReader using a SqlConnect ion obj ect is open, you cannot use t he
SqlConnect ion obj ect for any ot her purpose except t o close t he connect ion.
Closing a SqlDat aReader obj ect releases it s associat ed SqlConnect ion obj ect for
ot her uses. The SqlDat aReader class doesn’t have a const ruct or st at em ent . You
declare t he SqlDat aReader obj ect w it h a Dim st at em ent and assign a result set
from a SqlCom m and obj ect t o a SqlDat aReader wit h t he Ex ecut eReader m et hod
of t he SqlCom m and obj ect . Finally, invoke t he SqlDat aReader obj ect Read
m et hod t o open a r ow fr om t he result set in t he SqlDat aReader .
The SqlCom m and obj ect can ser ve m ult iple funct ions, including processing a T-
SQL st at em ent against a connect ion. When used in t his fashion, t he SqlCom m and
can t ake t wo argum ent s. The first can be a T- SQL dat a access st at em ent , such as
SELECT * FROM MyTable . The second SqlCom m and argum ent designat es t he
source connect ion for t he T- SQL st at em ent . For exam ple, y ou can use t he nam e
of a SqlConnect ion obj ect , such as My SQLCnn1.
Figur e 1- 3 shows t he rout e fr om a SQL Serv er dat a source t o a SqlDat aReader
obj ect . Alt hough t he SqlConnect ion and SqlCom m and obj ect s support t wo- way
int eract ion w it h a dat a source, t he SqlDat aReader obj ect allows read- only access
t o t he result set from t he T- SQL st at em ent ser v ing as an argum ent for a
SqlCom m and const r uct or. Because a SqlDat aReader obj ect cannot specify it s ow n
dat a source, a SqlDat aReader obj ect m ust link t o a SqlConnect ion obj ect t hr ough
an int erm ediat e SqlCom m and obj ect .

 Figu re 1 - 3 . A sch e m a t ic illu st ra t ing t h e r ou t e b y w h ich a SqlDa t a Rea de r
                      ob j e ct re t u r n s va lu e s t o a n a pplicat ion .
The SqlCom m and obj ect can do m ore t han prov ide a result set t o t he
SqlDat aReader obj ect . The discussion of t he SqlDat aReader obj ect described t he
use of t he SqlCom m and obj ect Execut eReader m et hod. Thr ee r elat ed m et hods
highlight som e cont rast ing SqlCom m and obj ect funct ionalit y.

    •   I nvok e t he Execut eNonQuery m et hod t o perfor m t wo t ypes of act ions.
        First , use t his m et hod t o perfor m dat a definit ion t asks, such as cr eat ing
        st ored procedures and v iews. Second, t he Ex ecut eNonQuery m et hod can
        enable dat a m anipulat ion t asks, such as insert s, updat es, and delet es.
    •   Next , y ou can apply t he Ex ecut eScalar m et hod t o a SqlCom m and obj ect
        when y ou want t o r et ur n a single v alue fr om a SELECT st at em ent . The
        m et hod ret ur ns t he first colum n from t he first r ow of a r esult set . I f you
        program t his cell t o be an aggregat e value such as a count or sum , y ou
        can r eadily ext ract t hat single value w it h t he Ex ecut eScalar m et hod.
    •   Finally, t he Execut eXMLReader m et hod opens a T- SQL source st at em ent
        wit h a FOR XML clause int o an XMLReader obj ect . Chapt er 6 cont ains
        ext ensive cov erage of t he FOR XML clause. Obj ect s for dealing w it h XML
        will be cov ered in Chapt er 12.

Th e SqlD a t a Ada pt e r Cla ss a n d t h e D a t a Se t Cla ss

You use obj ect s based on t he SqlDat aAdapt er class in com binat ion w it h obj ect s
based on t he Dat aSet class. A Dat aSet obj ect , which is an inst ance of t he Dat aSet
class, represent s an in- m em ory cache of dat a ret r iev ed from a dat abase. The
Dat aSet obj ect offers a disconnect ed dat a source as opposed t o t he alw ays-
connect ed dat a source for SqlDat aReader obj ect s. As a consequence, using t he
SqlDat aAdapt er and Dat aSet obj ect s inst ead of a SqlDat aReader obj ect im prov es
applicat ion scalabilit y. This scalabilit y im prov em ent result s because t he Dat aSet
doesn’t persist a connect ion t o it s underly ing dat a source ov er t he w hole of it s
lifet im e as does t he SqlDat aReader obj ect . While t he SqlDat aReader isn’t as
scalable as t he SqlDat aAdapt er / Dat aSet com binat ion, t he SqlDat aReader can
prov ide fast er per form ance from a rem ot e dat a source because it deliv ers dat a in
t he st yle of a forward- only, r ead- only cursor— t he classic fir ehose deliv er y m odel.

                                     N ot e
The t er m firehose refers t o t he fact t hat dat a gushes out of a
forward- only, read- only cursor.
The SqlDat aAdapt er and Dat aSet obj ect s com bine t o enable bot h dat a access and
dat a m anipulat ion capabilit ies. This is im port ant because SqlDat aReader obj ect s
prov ide st rict ly dat a access capabilit ies ( t hat is, you cannot perform updat e,
insert , or delet e t asks w it h a SqlDat aReader obj ect ) . Use t he SqlDat aAdapt er Fill
m et hod t o populat e a Dat aSet obj ect wit h values from a SQL Ser ver dat a source.
Because a single Dat aSet obj ect can work w it h m ult iple SqlDat aAdapt er and OLE
DB Dat aAdapt er obj ect s, y ou can populat e a single Dat aSet obj ect w it h
het er ogeneous dat a sources fr om m ult iple dat abase serv ers. For exam ple, y ou
can populat e a single dat a set wit h t ables, v iews, or st or ed procedures from t wo
different SQL Serv er inst ances or from Access and Oracle dat a sources in addit ion
t o a SQL Server dat a source. Furt herm or e, you can j oin all t he dat a sources
wit hin a Dat aSet obj ect on fields w it h com m on dat a t ypes.
Use t he SqlDat aAdapt er Updat e m et hod t o t ransfer changes from a Dat aSet
obj ect t o it s under ly ing dat a sources. When users per form insert , updat e, and
delet e operat ions against t he cont ent s of a Dat aSet obj ect , t hose m odificat ions
don’t t ransfer t o t he dat a sources for t he Dat aSet obj ect unt il your applicat ion
inv okes t he Updat e m et hod for a SqlDat aAdapt er obj ect underly ing t he dat a
source. Despit e it s nam e, t he Updat e m et hod can process all t hree t ypes of dat a
m anipulat ion operat ions. How ev er , y ou need a cust om SqlCom m and obj ect t o
accom m odat e each t ype of dat a m anipulat ion t ask. Therefore, a SqlDat aAdapt er
can r elat e t o a r em ot e dat a source t hr ough m or e t han a single SqlCom m and
obj ect . Bet ween t he t im e y ou populat e t he Dat aSet obj ect and t he t im e your
applicat ion inv ok es t he SqlDat aAdapt er Updat e m et hod, it ’s possible for t he
underly ing dat a source on a SQL Ser ver inst ance t o change. Any changes can
cause ex cept ions because t he or iginal values in a dat a set can be differ ent fr om
t he cur rent values in t he SQL Server dat a source. The SqlDat aAdapt er has ev ent s
and propert ies t o help m anage except ions t hat can occur dur ing an updat e
process. Figure 1- 4 pr esent s a schem at ic diagram sum m ar izing how
SqlDat aAdapt er and Dat aSet obj ect s exchange dat a wit h an under ly ing dat a
source. By cont rast ing t his diagram w it h t he one in Figure 1- 3, you can easily
spot an im port ant differ ence bet w een t he SqlDat aReader and a Dat aSet obj ect
supplied by a SqlDat aAdapt er obj ect . The capabilit y of per form ing dat a
m anipulat ion w it h t he Dat aSet obj ect is a cr it ical feat ur e t hat m eans m any
applicat ions w ill rely on a Dat aSet obj ect inst ead of a SqlDat aReader obj ect .

 Figu r e 1 - 4 . A sch em a t ic illu st r at in g t h e rou t e by w h ich SqlD a t aAd a pt er
  a n d D a t a Set obj e ct s e xch a n g e va lu es w it h a SQL Se rv e r da t a sou r ce .
The Dat aSet obj ect offers an obj ect m odel for m anaging t he indiv idual elem ent s
wit hin it . The Dat aSet obj ect consist s of a Dat aTable collect ion ( along wit h ot her
elem ent s) . This collect ion can cont ain one or m ore t ables. You can creat e t hese
t ables w it h t he SqlDat aAdapt er Fill m et hod w hen y ou init ially populat e a Dat aSet
obj ect from a SQL Serv er dat a source. The Select Com m and pr opert y , which is a
T- SQL st at em ent or a st or ed procedure, for a SqlDat aAdapt er obj ect can serv e as
t he basis of a t able in t he Dat aTable collect ion for a Dat aSet obj ect . You can use
m ult iple SqlDat aAdapt er obj ect s t o add m or e t han one t able t o a Dat aSet obj ect .
Each t able has a r ich obj ect m odel t hat perm it s t he designat ion of pr im ary keys
and for eign k eys as well as const raint s t o m anage dat a int egrit y w it hin a t able.
One very pract ical use for t he Dat aTable collect ion and t he obj ect m odel for
indiv idual t ables is t hat you w ill use it t o nav igat e am ong t he values wit hin a
Dat aSet obj ect .

                                     N ot e
I n addit ion t o referencing t he colum n values of r ows wit hin
an indiv idual Dat aTable in a Dat aSet obj ect , y ou can
reference t he schem a of Dat aTable obj ect s wit hin a Dat aSet
obj ect . This is par t icular ly convenient when y ou want t o
cr eat e a t able t hat you w ant t o populat e wit h dat a fr om an
XML docum ent .
The Dat aSet obj ect support s four k ey m et hods for exchanging it s dat a wit h XML
docum ent s. Two of t he m et hods are used for w rit ing XML docum ent s based on a
Dat aSet obj ect , and t wo ar e for r eading XML docum ent s int o a Dat aSet obj ect .
Wit hin each pair , one m et hod focuses j ust on t ransferr ing schem a infor m at ion
and t he ot her focuses on t ransferr ing dat a as well as schem a inform at ion.




A St a r t e r AD O.N ET Sa m ple
This sect ion pr esent s a st art er sam ple t o illust rat e som e of t he concept s
described in t he preceding sect ion. Don’t w or ry about follow ing t he det ails of t he
exam ple. I nst ead, pay at t ent ion t o how easy it is t o get st art ed w it h ADO.NET.
This sect ion r einforces t he present at ion of basic ADO.NET concept s described in
t he preceding sect ion w it h sim ple dr ag- and- dr op t echniques and a lit t le code
included t o t ie obj ect s t oget her or enable select ed funct ionalit y. See Chapt er 10
for a collect ion of code sam ples t hat illust rat e how t o pr ogram ADO.NET obj ect s
when y ou r equir e cust om ized solut ions not r eadily available fr om t he graphical
dev elopm ent env ironm ent . Most pr ofessional developers get called on t o do t he
hard work t hat goes beyond dragging and dropping obj ect s. Aft er all, if it were
easy, t hey wouldn’t need you. How ev er, it is nice t o st art out by seeing how easy
it is t o cr eat e a sim ple solut ion m ost ly by dragging and dr opping.

                                     N ot e
For t hose who want t he sam ple fr om t his sect ion as a point
of depart ur e, it is av ailable on t he book’s CD as t he
GraphicalDat aBind solut ion.

Addin g a SqlD a t a Ada pt e r , SqlConn e ct ion, a n d D a t a Se t
You can drag a SqlDat aAdapt er obj ect t o a for m j ust lik e a t ext box or a com bo
box in Visual Basic 6. Ther e is ev en a w izard t o help y ou configur e t he
SqlDat aAdapt er obj ect . Figur e 1- 5 shows t he opening screen im m ediat ely aft er
dragging a SqlDat aAdapt er obj ect t o t he st art up blank form , Form 1, for a
Windows applicat ion. You can use t his w izard t o specify t wo ADO.NET obj ect s.

    Figu re 1 - 5 . Th e D a t a Ad a pt er Con figu ra t ion W iz a rd e n a ble s you t o
       gr ap hically con fig u r e a Sq lD at a Ada pt e r ob j ect a n d it s re la t ed
             Sq lConn ect ion ob j e ct for u se w it h a W ind ow s for m .




First , you can designat e a SQL Serv er dat abase t o w hich t o connect ; t his creat es
a SqlConnect ion obj ect . This w izard offers sev eral rout es for specify ing a
dat abase connect ion. For exam ple, y ou can pick a prev iously creat ed connect ion,
or you can creat e a new collect ion fr om t he Dat a Link Propert ies dialog box. This
dialog box let s y ou specify t he com m on connect ion st ring argum ent s, such as a
dat abase serv er , a t ype of aut hent icat ion, and a dat abase nam e. I n t his st art er
sam ple, I used t he default connect ion t o t he Nort hw ind dat abase.
Second, y ou can specify a dat a source w it hin a dat abase connect ion using a SQL
st ring or a st or ed pr ocedur e. For t his st art er applicat ion, I used SELECT
CategoryID, CategoryName FROM Categories as t he SQL st ring sour ce for t he
SqlDat aAdapt er obj ect . Alt hough a graphical designer is available for building
query st at em ent s, y ou will be sev erely ham per ed as a SQL Ser ver dev eloper if
you don’t lear n T- SQL, t he dialect of SQL t hat SQL Ser ver support s. I n addit ion,
you w ill find a grasp of T- SQL im port ant for craft ing t he st at em ent s for t he
SqlCom m and obj ect s t hat enable you t o build solut ions t hat updat e a SQL Ser ver
dat a source from a Windows applicat ion.
Aft er y ou finish configur ing t he Dat a Adapt er Configurat ion Wizard, t he
com ponent t ray w ill open below your blank for m . The t ray w ill hold t he t w o
obj ect s t hat t he w izard creat ed— a SqlDat aAdapt er obj ect and a SqlConnect ion
obj ect . Because a SqlDat aAdapt er obj ect is m er ely a br idge bet w een a r em ot e
dat a source and a dat a set in a Windows applicat ion, y ou w ill need t o creat e a
dat a set . Then your SqlDat aAdapt er obj ect can fill t he dat a set w it h dat a fr om t he
rem ot e dat a source specified by y our r eplies t o t he Dat a Adapt er Configurat ion
Wizard.
I m m ediat ely aft er a SqlDat aAdapt er obj ect is cr eat ed, t hr ee link s are displayed
near t he bot t om of t he Propert ies w indow for t he obj ect . One of t hese link s r eads
Generat e Dat aset . Clicking t he link opens t he Generat e Dat aset dialog box, in
which you designat e an ex ist ing dat a set or specify t he nam e for a new one.
Figur e 1- 6 shows t he specificat ion of a new dat a set nam ed DsCat egories for t he
SqlDat aAdapt er creat ed wit h t he Dat a Adapt er Configurat ion Wizard. When you
click OK w it hin t he Generat e Dat aset dialog box port ray ed in Figur e 1- 6, Visual
Basic .NET adds a new obj ect nam ed DsCat egories1 t o t he t ray below t he form .
I n addit ion, Visual Basic .NET adds an XML schem a nam ed DsCat egories.xsd t o
t he solut ion t hat describes t he dat a set . You can view t he schem a for t he dat a set
graphically or as XML code by double- click ing t he file’s nam e in Solut ion Explor er .
The schem a’s graphical view is int eract iv e so t hat you can change t he dat a t ype
specificat ion for colum ns and m ak e ot her design changes t o t he Cat egor ies t able.
The Propert ies w indow for t he DsCat egor ies.xsd shows t he nam e of t he t able
specificat ion as Cat egor ies. At t his point , you have com plet ed t he cr eat ion of t he
DsCat egories dat a set , which cont ains a Dat aTable nam ed Cat egories.

        Figu r e 1 - 6 . You n e ed t o ad d a da t a set b efore you ca n u se a
SqlDa t a Ada pt e r. You ca n ad d t h e da t a set a s sim p ly a s g ivin g it a n a m e in
                          t h e Ge n e ra t e D at a set dia log b ox .
                                     N ot e
Alt hough t he Generat e Dat aset dialog box shows t he dat a set
nam e as DsCat egories, Visual Basic .NET assigns
DsCat egories1 as t he dat a set nam e in t he t ray below For m 1.
Aft er adding a SqlDat aAdapt er obj ect and a Dat aSet obj ect t o an applicat ion, y ou
can pr ev iew t he dat a t hat t he SqlDat aAdapt er will bring t o t he applicat ion.
Click ing t he Prev iew Dat a link in t he Propert ies window for a SqlDat aAdapt er
obj ect opens t he Dat a Adapt er Pr ev iew dialog box. Click t he Fill Dat aSet but t on t o
display t he dat a in t he dialog box . Because of t he SQL st at em ent used when
configur ing our SqlDat aAdapt er obj ect , t he but t on populat es t he form wit h a t able
t hat shows t he Cat egor yI D and Cat egory Nam e colum n values from t he Nort hw ind
dat abase. Don’t confuse click ing t he but t on on t he form w it h populat ing t he dat a
set for use w it h a Windows form . Filling t he Cat egories dat a t able in t he
DsCat egories dat a set wit h dat a values fr om a SQL Ser ver inst ance and display ing
t he values on a Window s form r equires t w o m or e st eps. First y ou need t o invoke
t he Fill m et hod for t he SqlDat aAdapt er obj ect . Second you need t o bind form
cont r ols, such as t ex t box es, t o colum ns in t he local Cat egor ies dat a t able.

Fillin g a D a t a Se t a n d Bin din g Con t r ols t o I t

A logical place t o fill a dat a set for use w it h a form is t he for m Load ev ent
procedur e. A single line of code in t he t em plat e will fill t he dat a set . Run t he line
of code from t he form Load event t o m ake t he cont ent s for t he dat a set available
as soon as t he form opens. The follow ing code segm ent illust rat es t he synt ax for
inv ok ing t he SqlDat aAdapt er Fill m et hod t o populat e a dat a set . The ev ent
procedur e is for Form 1, which is t he default st ar t up obj ect for a Windows
applicat ion. The Fill m et hod t akes t w o argum ent s in t his sit uat ion. First you
specify t he dat a set nam e. Second y ou designat e t he Dat aTable nam e wit hin t he
dat a set . You m ust nam e a Dat aTable obj ect because one dat a set can hold
m ult iple Dat aTable obj ect s. Leav ing out t he Dat aTable nam e w ill cause an er ror.
       Private Sub Form1_Load(ByVal sender As System.Object, _

           ByVal e As System.EventArgs) Handles MyBase.Load

           SqlDataAdapter1.Fill(DsCategories1, “Categories”)

     End Sub

Aft er y ou fill t he dat a set , you can bind it t o cont rols on a form . For exam ple, I
added t wo t ext box es t o Form 1 for t he st art er ADO.NET applicat ion. You can do
t his w it h t he Toolbox j ust as in pr ior Visual Basic versions. What ’s new is t hat
t here is now a Dat aBindings propert y . You can graphically bind t he Tex t propert y
for a t ext box cont r ol t o a colum n in t he Cat egories dat a t able. Figur e 1- 7 shows
how t o bind t he Text pr opert y for Text Box1 t o t he Cat egor yI D colum n in t he
Cat egor ies dat a t able. The Form 1.vb Design t ab shows Text Box1 select ed on
Form 1. The Propert ies window r ev eals t he assignm ent of t he Cat egory I D colum n
t o Text Box1. Select ing a colum n fr om t he Cat egor ies dat a t able com plet es t he
t ask. I follow ed t he sam e pr ocess for Text Box2, but I select ed Cat egory Nam e
inst ead.
I f you r un Form 1 by pr essing t he F5 key, you see t he form w it h t w o t ext box es
show ing t he Cat egoryI D and Cat egory Nam e colum n values for t he first row from
t he Cat egor ies dat a t able. While it is nice t o see dat a in t he t ext boxes,
applicat ions t ypically seek t o allow users t o at least browse t hrough dat a. To
enable browsing, y ou need cont rols t hat let a user nav igat e t hrough t he rows of
t he Cat egor ies dat a t able.

Figu r e 1 - 7 . Use t h e D at a Bin din gs pr op e rt y t o bin d t h e Te x t p roper t y of a
                t ex t box con t rol t o a colu m n in a D at a Ta ble ob j ect .




N a v iga t in g Th r ou gh Row s

A row of but t on cont r ols can pr ov ide t he basis for a nav igat ion bar. All we need
are Text propert y set t ings indicat ing t he nav igat ion each but t on prov ides and
ev ent procedures for t he Click ev ent of each but t on t hat nav igat es t hr ough t he
rows in t he Cat egor ies dat a t able. I added four but t on cont r ols t o Form 1 wit h
ev ent procedures t o cont rol nav igat ion in r esponse t o click ev ent s. For exam ple,
Figur e 1- 8 shows t he t ext box es aft er t he but t on cont r ol on t he far r ight has been
click ed. Not ice t hat t he last row ( for Cat egoryI D 8 in t he Cat egor ies dat a t able)
shows in t he t op t ext box .

    Figu r e 1 - 8 . For m 1 in t h e st a rt e r AD O.N ET sam ple aft e r t h e last - row
       bu t t on ( > | ) h a s b e en clicke d displa ys colu m n valu e s fr om t h e
                      cor re spon d in g r ow in it s t e xt b ox con t r ols.
The follow ing set of Click ev ent pr ocedur es for But t on1 t hr ough But t on4 shows
how easy it is t o cont r ol nav igat ion. The but t ons from left t o r ight navigat e t o t he
first row, t he pr ev ious r ow, t he next row, and t he last row. The procedur es
updat e t he Posit ion propert y of t he BindingCont ext pr opert y on t he for m for t he
Cat egor ies Dat aTable in t he DsCat egor ies1 dat a set . This m anipulat ion, in t ur n,
affect s all t ext box cont r ols bound t o t he Cat egories dat a t able. Chapt er 10 dr ills
down m or e deeply int o t he obj ect m odel suppor t ing t hese m anipulat ions. The
im port ant point t o not ice her e is t hat t he code doesn’t hav e t o handle m ov ing
past t he beginning or ending r ow because ADO.NET is sm art about recognizing
eit her end of a r owset , such as t he Cat egories dat a t able.
      Private Sub Button1_Click(ByVal sender As System.Object, _
          ByVal e As System.EventArgs) Handles Button1.Click


           ’Move to the first row.
           Me.BindingContext(DsCategories1, “Categories”).Position _
               = Me.BindingContext(DsCategories1, “Categories”). _
                   Position.MinValue

     End Sub

     Private Sub Button2_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button2.Click

           ’Move to the previous row.
           Me.BindingContext(DsCategories1, “Categories”).Position _
               -= 1

     End Sub

     Private Sub Button3_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button3.Click

           ’Move to the next row.
           Me.BindingContext(DsCategories1, “Categories”).Position _
                       += 1

     End Sub

     Private Sub Button4_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button4.Click
           ’Move to the last row.
           Me.BindingContext(DsCategories1, “Categories”).Position _
               = Me.BindingContext(DsCategories1, “Categories”). _
               Position.MaxValue

       End Sub




Usin g Qu e r y Ana lyzer
Query Analyzer is y our friend for debugging T- SQL st at em ent s. Because T- SQL is
so im port ant t o SQL Ser ver developm ent , m ast ering t his t ool can be par t of what
m akes y ou int o a gr eat SQL Ser ver dev eloper .

W ha t ’s Qu e r y An a lyze r For ?

Query Analyzer is one of t he client t ools t hat ships wit h SQL Serv er 2000. This is
anot her way of saying t hat Quer y Analyzer isn’t part of t he dat abase serv er. You
are aut hor ized t o use Query Analyzer, and t he ot her client t ools, by t he allocat ion
of a Client Access License t o y our workst at ion. Alt hough t he client t ools don’t ship
wit h MSDE 2000 ( Microsoft SQL Serv er 2000 Deskt op Engine) , t hey ar e available
wit h any r egular v ersion of SQL Serv er 2000, such as t he Ent erprise, St andard,
Dev eloper , and Personal edit ions.
I t hink of Query Analyzer as sort of an I DE for running T- SQL st at em ent s. This
client t ool is a r eal help for anyone program m ing solut ions for SQL Serv er. Quer y
Analyzer w ill help y ou t o easily and quick ly debug y our T- SQL code. Alt hough y ou
can pr ogram and debug T- SQL dir ect ly w it h Visual Basic .NET and ADO.NET,
Query Analyzer prov ides a m uch r icher env ironm ent t hat m akes y our T- SQL
coding go m uch fast er. Ev en if an applicat ion calls for r unning T- SQL inside of a
Visual Basic .NET applicat ion, I oft en find it convenient t o debug t he st at em ent in
Query Analyzer befor e insert ing t he T- SQL code int o m y Visual Basic .NET
applicat ion.
Ther e ar e at least five r easons t o becom e com fort able w it h T- SQL, and using
Query Analyzer m ay be one of t he best ways t o do t hat .

   •     You can build richer query st at em ent s t hat r et ur n precisely t he dat a y ou
         want wit hout hav ing t o resort t o a graphical quer y builder . I ndeed, som e
         query operat ions, such as t hose per form ed by t he UNI ON funct ion, cannot
         be r epresent ed by graphical query designers.
   •     You can cr eat e dat a m anipulat ion st at em ent s for updat ing, insert ing, and
         delet ing r ows. Graphical query builders aren’t always effect ive at creat ing
         t hese st at em ent s.
   •     You can program secur it y t opics, such as creat ing SQL Ser ver logins and
         cont r olling access t o dat abase obj ect s and serv er adm inist rat ion funct ions.
   •     You can program t he cr eat ion of dat abases and t he obj ect s wit hin t hem ,
         such as t ables, st or ed procedures, and user- defined funct ions. Several
         chapt ers w it hin t his book include script s t o creat e dat abases and populat e
         t hose dat abases wit h obj ect s aut om at ically.
   •     You can t ake advant age of program m ing feat ur es, such as I F…ELSE
         st at em ent s, local var iables, param et ers, and ret ur n values t o build
         flex ibilit y and user int er act ivit y int o y our applicat ions.

Many T- SQL sam ples ar e especially designed for use wit h Quer y Analyzer . For
exam ple, t hese sam ples set t he dat abase cont ex t for T- SQL code w it h a USE
st at em ent . This st at em ent explicit ly t arget s Quer y Analyzer and doesn’t run fr om
m ost ot her SQL Ser ver client s, such as Visual Basic .NET. Books Online, t he SQL
Ser ver Help syst em , follows t his convent ion wit h it s sam ples. Therefor e, a basic
fam iliar it y w it h Quer y Analyzer w ill help y ou t o t ake adv ant age of t he r ich
collect ion of sam ples in Books Online. I n addit ion, t he T- SQL sam ples in t his book
follow t he sam e convent ion. Ther efor e, t his sect ion gives y ou a br ief int r oduct ion
t o Quer y Analyzer. You will hav e am ple opport unit y t o r einforce and ext end t he
underst anding t his sect ion conveys wit h t he T- SQL sam ples t hr oughout t he
balance of t his book. I n fact , t he com m ent ary for t hese sam ples som et im es
describes how t o r un code in Quer y Analyzer.

M a k ing a Conn e ct ion w it h Qu e r y An a lyz e r

To st art Query Analyzer , click t he St art but t on on t he Windows t askbar; choose
Program s, t hen Micr osoft SQL Serv er, and t hen Query Analyzer. When y ou st art
Query Analyzer t his way , y ou w ill be gr eet ed w it h t he Connect To SQL Ser ver
dialog box . Recall t hat Query Analyzer is a client t ool. Therefore, y ou can use it
wit h any SQL Serv er inst ance t hat y ou can connect t o and for w hich y ou hav e
access perm ission. I f y ou are connect ing t o t he local inst ance of SQL Serv er on
your com put er for which y ou are t he adm inist rat or, y ou can designat e t he SQL
Ser ver as “( local) ” and choose Windows Aut hent icat ion. ( See Figur e 1- 9.) The
set t ings in Figur e 1- 9 ar e suit able for connect ing t o SQL Ser ver w it h any Windows
login. Click OK t o com plet e t he connect ion t o t he serv er.

Figu r e 1 - 9 . Th e con n e ct ion se t t in gs for logg in g in t o t h e loca l in st an ce of
                      SQL Se rve r w it h W indow s a u t h e n t ica t ion .




Query Analyzer offers t he norm al flex ibilit y in how y ou connect t o a SQL Serv er
inst ance. As I alr eady not ed, y ou can connect wit h any Windows login t hat a SQL
Ser ver inst ance recognizes. I n addit ion, y ou can use SQL Serv er aut hent icat ion. I f
you select SQL Server Aut hent icat ion rat her t han Windows Aut hent icat ion in t he
Connect To SQL Serv er dialog box , Query Analy zer enables t he Login Nam e and
Password t ext box es so t hat y ou can specify a SQL Ser ver login and password. I n
addit ion, you can connect t o any ot her SQL Ser ver inst ance besides t he local
default one. I f y ou k now t he nam e of t he inst ance t o w hich y ou want t o connect ,
t ype t he nam e in t he SQL Ser ver com bo box in t he Connect To SQL Serv er dialog
box. Ot herw ise, click t he br owse but t on ( …) next t o t he com bo box . This opens a
dialog box t hat list s SQL Ser ver inst ances cur r ent ly act ive on t he net w ork t o
which your w orkst at ion connect s. Select an inst ance nam e t o specify a connect ion
t o t hat serv er.
See Chapt er 7 for m or e about SQL Serv er secur it y and logging in t o SQL Ser ver
inst ances w it h differ ent t ypes of logins. Unt il Chapt er 7, one safe appr oach t o
running t he sam ples is t o connect as a m em ber of t he sysadm in ser ver role, such
as t he SQL Serv er adm inist rat or. Mem bers of t he sysadm in serv er r ole hav e
unr est rict ed perm ission on a SQL Server inst ance. Chapt er 7 giv es guidelines and
procedur es for r est rict ing t he perm issions for an applicat ion’s users.

Ru nn in g, Sa vin g, a n d Ope nin g T- SQL Scr ipt s

When Quer y Analyzer opens as descr ibed in t he preceding sect ion, it will connect
a user t o t he default dat abase for t he login t hat t he user specified in t he Connect
To SQL Serv er dialog box . The default is t he m ast er dat abase unless a dat abase
adm inist rat or changed t he st andard default dat abase specificat ion w hen adding a
new login.
Because m ost user - defined quer ies don’t int er r ogat e t he m ast er dat abase, w hich
is a sy st em dat abase, y ou w ill usually want t o change t he dat abase cont ext
befor e w r it ing any SQL query st at em ent s. You can em ploy t he USE st at em ent for
t his. Just follow USE wit h t he nam e of t he dat abase for w hich you want t o wr it e a
query . The follow ing st at em ent dir ect s Query Analyzer t o run quer y st at em ent s
against t he pubs dat abase ( unt il anot her USE st at em ent or som e ot her specific
inst ruct ion t o use anot her dat abase) . The pubs dat abase is one of t he sam ple
dat abases t hat is inst alled aut om at ically wit h SQL Ser ver 2000.
USE pubs

Figur e 1- 10 shows t his sim ple SELECT st at em ent for t he aut hors t able in t he pubs
dat abase:
SELECT au_fname, au_lname, state
FROM authors
WHERE contract = 1

The SELECT st at em ent appears aft er t he USE st at em ent in t he Edit or pane, which
is w here y ou t ype T- SQL st at em ent s in Query Analyzer. The st at em ent select s
t hr ee colum n values from t he aut hors t able if a row has a cont ract colum n value
equal t o 1. You can see t he r esult set fr om t he query st at em ent in t he Result s
pane t hat appears below t he Edit or pane, as show n in Figure 1- 10. Query
Analyzer aut om at ically displays t he Result s pane w hen you r un a query , but you
can also show and hide it by pr essing Ct r l+ R.
By default , Quer y Analy zer displays t he r esult set in t he Result s pane w it hin a
spreadsheet lik e gr id. At t he bot t om of t he Result s pane are a Grids t ab and a
Messages t ab. You can click t he Messages t ab t o see general feedback from SQL
Ser ver about how a query st at em ent operat ed. For exam ple, t he Messages t ab for
t he quer y in Figur e 1- 10 says, “( 19 r ow ( s) affect ed) ”, which corr esponds t o t he
num ber of rows t he query st at em ent r et ur ns. Warnings and err or feedback fr om a
SQL Ser ver inst ance appear in t he Messages pane.
You also can choose t o display t he result set in t he Result s pane as t ext in
colum ns. I n t hat case, t her e is only a Result s t ab at t he bot t om of t he Result s
pane, and bot h t he r esult set and m essages are display ed in t he pane. To specify
whet her y ou want t o set t he r esult set in a gr id or in t ex t , choose Opt ions fr om
t he Tools m enu, t hen choose t he Result s t ab, and t hen use t he com bo box at t he
right of t he Opt ions dialog box t o specify Result s To Text , Result s To Gr ids, or
Result s To File.

 Figu re 1 - 1 0 . A q u e ry st a t e m e n t for t h e pub s d at a ba se a n d it s r esu lt se t
                                 r u n from Qu e ry An a lyz er .
Aft er creat ing a T- SQL script , you can save it so t hat y ou or ot hers can reopen it
and use it again lat er. Most of t he sam ple files for Chapt er 2 t hrough Chapt er 7
are saved scr ipt s wit h t he .sql ext ension. To save a script file for t he fir st t im e or
resav e an ex ist ing script file w it h a new nam e, choose Sav e As from t he File
m enu, nav igat e t o a desir ed folder w it h t he Sav e Quer y dialog box , ent er a
filenam e, and click Sav e. These st eps will sav e t he cur r ent scr ipt in t he
designat ed folder w it h t he filenam e t hat y ou specify w it h t he .sql ext ension. For
exam ple, I follow ed t hese st eps t o sav e t he script shown in Figur e 1- 10 t o m y
com put er. I saved t he file as Aut horsQuery .sql in t he Chapt er01 folder of t he SQL
Ser ver Dev elopm ent Wit h VBDot Net dir ect ory on m y C dr iv e.
Ther e ar e sev eral ways t o open a script file. For exam ple, im m ediat ely aft er
connect ing t o a SQL Ser ver inst ance for a new Query Analyzer session, y ou can
choose Open from t he File m enu, navigat e in t he Open Query File dialog box t o
t he folder wit h t he script file ( .sql) , highlight t he filenam e, and click Open. These
st eps open an Edit or pane in Query Analyzer w it h t he sav ed script file. Figure 1-
11 shows t he opened script file sav ed in t he pr eceding paragraph in an Edit or
pane. Not ice t hat t he t it le bar for t he pane includes t he pat h along w it h t he
filenam e and ext ension.
The Obj ect Br owser w ill also script obj ect s for y ou. To aut om at ically cr eat e a
script for an obj ect , r ight - click an obj ect such as t he Cat egories t able, and choose
Script Obj ect To New Window As and t hen t he Creat e com m and. This feat ur e
allows you t o see t he T- SQL scr ipt behind y our favorit e obj ect s t o lear n how t o
m ake m ore obj ect s lik e t hem or t o help you change t heir design t o m eet
expanded obj ect ives.
As y ou build up your collect ion of dat abases and t he obj ect s wit hin t hem , y ou
m ight st art t o find special value in t he Obj ect Search com ponent w it hin Query
Analyzer. You can open t he Obj ect Search dialog box by pr essing t he F4 key or by
choosing Obj ect Search from t he Tools m enu and t hen Open. You can open
m ult iple Obj ect Search dialog box es at t he sam e t im e. The dialog box let s you
search for any obj ect or subset of obj ect s, such as views or st ored pr ocedur es, by
nam e or ev en a part of a nam e. Figur e 1- 13 shows an excerpt fr om t he result s in
a search for any t ype of dat abase obj ect t hat begins w it h Cat eg in any dat abase
on t he curr ent ly connect ed SQL Serv er inst ance. As you can see, obj ect s
beginning w it h Cat eg for t heir nam e ar e very popular in t he Nort hw ind dat abase.
( Ot her dat abases out side t he excerpt show n also hav e obj ect s beginning wit h
Cat eg.)

 Figu r e 1 - 1 1 . An op en e d T- SQL scr ipt fr om a sa v ed .sq l file . Th e p at h an d
           file n a m e in t h e t it le ba r in dica t e t h e sou rce of a .sq l file.




Se le ct e d Ot h e r Topics

Ther e’s lot s m or e t o Quer y Analyzer, but t he pr eceding int r oduct ion equips you
for t he w ays in which t his book exploit s t he t ool. I n t his sect ion, I br iefly highlight
a couple of m y fav orit e ot her uses for Quer y Analyzer .
The Obj ect Br owser is a conv enient t ool for explor ing t he dat abases and t he
obj ect s wit hin t hem on a connect ed SQL Serv er inst ance wit h a t r ee- t y pe
int erface. You can use t his Query Analyzer com ponent t o ex am ine t he dat abase
obj ect s wit hin a dat abase. You can show or hide t he Obj ect Br owser by pressing
t he F8 k ey or by choosing Obj ect Br owser from t he Tools m enu and t hen t he
Show / Hide com m and. Figur e 1- 12 shows t he Obj ect Browser w indow expanded t o
display t he colum n nam es and dat a t ype specificat ions for t he Cat egor ies t able
( dbo.Cat egories) in t he Nort hw ind dat abase. I oft en find it conv enient t o drill
down int o a dat abase design and check t he spelling of colum n nam es. Being able
t o quick ly look up t he dat a t ype for a colum n in a t able is part icularly convenient
when y ou ar e declaring a search param et er for a co- lum n in a t able; use t he
wrong dat a t ype, and y ou m ay not get a m at ch, even w it h t he right value.

  Figu r e 1 - 1 2 . Th e Obj e ct Br ow ser ope n e d t o sh ow t h e n a m es an d da t a
                t ype s for t h e colu m n s in t h e N or t h w in d d at a ba se .
Figu re 1 - 1 3 . You ca n u se t h e Obj e ct Sea rch d ia log in Qu e r y An a lyz e r t o
            se a rch for obj e ct s by n a m e ( or e ve n pa rt of a n am e ) .
Cha pt e r 2 . Ta ble s a nd D a t a Ty pe s
This chapt er t arget s t he design and program m ing of SQL Serv er t ables wit h T-
SQL ( Transact St r uct ured Query Language) . SQL Serv er dat abase adm inist rat ors
and dev elopers use T- SQL for program m ing dat abase adm inist rat ion and dat a
access. By dat a access, I m ean select ing r ecords from a dat abase. T- SQL is
generally com pat ible wit h t he SQL- 92 st andard endorsed by ANSI ( Am erican
Nat ional St andards I nst it ut e) and I SO ( I nt er nat ional St andards Organizat ion) .
Howev er, Micr osoft opt im ized and st ream lined T- SQL for use wit h SQL Ser ver.
Any dev eloper w ho want s t o use Visual Basic .NET t o build cust om SQL Ser ver
solut ions will be sever ely handicapped w it hout a good grasp of SQL Serv er dat a
t ypes and t ables, as well as T- SQL. Several subsequent chapt ers in t his part of
t he book w ill explor e select ed ot her dat abase obj ect s, such as views, st ored
procedur es, and user - defined funct ions, from design and im plem ent at ion
perspect ives w it h T- SQL. The next part of t he book builds on t his foundat ion as it
dem onst rat es how t o cr eat e cust om SQL Ser ver solut ions w it h Visual Basic .NET.
This chapt er begins w it h an ex plorat ion of SQL Ser ver dat a t ypes. Next it
prov ides an overv iew of differ ent t ypes of t ables. A ser ies of T- SQL sam ples
illust rat es core t able design issues and solut ions. These sam ples int roduce y ou t o
program m ing t echniques for SQL Serv er t ables. By underst anding how t o script
dat abase obj ect s, such as t ables, y ou can r eadily duplicat e t hose dat abase
obj ect s across m ult iple serv ers. For exam ple, a Visual Basic dev eloper can build a
solut ion on one serv er and t hen readily t ranspor t t he obj ect s for use on anot her
serv er — j ust by running t he script s for t he obj ect s. You can also adapt t he script
from one obj ect as a st art ing point for ot her, sim ilar , obj ect s. A clear
underst anding of t able script ing t echniques w ill help you t o aut om at e t able
design. This frees r esources for focusing on t he needs of client s for y our
dat abases.




Cha pt er Re sou r ces
Ther e ar e t wo k ey r esources for t his chapt er . Fir st , a SQL Serv er dat abase nam ed
Chapt er 02 illust rat es m any of t he design concept s used t hroughout t his chapt er.
Second, a collect ion of T- SQL sam ple script s illust rat es coding t echniques for
creat ing t ables and wor king w it h t he r esources wit hin a t able.

Th e Ch a pt e r ’s T- SQL Sa m ple Scr ipt s

The T- SQL sam ple collect ion for t his chapt er illust rat es k ey design and
im plem ent at ion issues for script ing SQL Serv er dat abase obj ect s. All t he sam ple
script s t hat y ou see in t his chapt er ar e av ailable on t he book ’s com panion CD.
The sam ples ar e all sav ed wit h t he .sql ext ension, so you can open and r un each
of t hem from Query Analyzer . As you learned in Chapt er 1, Query Analy zer is a
graphical t ool t hat ships wit h Micr osoft SQL Ser ver 2000. As y ou read and run t he
sam ple script s, you m ight find it helpful t o lear n m ore about t he st r uct ure of t he
Chapt er02 dat abase by browsing it w it h SQL Serv er Ent erprise Manager , which
also was discussed in Chapt er 1.

Th e Ch a pt e r ’s Sa m ple D a t a ba se
The script in t his sect ion cr eat es a new v ersion of t he Chapt er02 dat abase.
Subsequent T- SQL code sam ples w ill cr eat e addit ional t ables in t he dat abase and
dem onst rat e t echniques for w or k ing w it h t ables.
Prepar e t o creat e t he Chapt er02 dat abase by st art ing Query Analyzer and
connect ing t o t he SQL Ser ver inst ance y ou are using. Log in as sa or wit h a user
I D t hat belongs t o t he sysadm in fix ed serv er r ole. This book dr ills dow n on
secur it y explicit ly in Chapt er 7, wher e y ou will learn how t o fine- t une dat abase
and user securit y set t ings. When users connect t o a SQL Serv er dat abase t hrough
your Visual Basic .NET applicat ions, t hey m ust ident ify t hem selv es t hr ough t he
secur it y account s discussed in Chapt er 7. Unt il t hat chapt er, using a login t hat
belongs t o sysadm in w ill w ork for all sam ples.
Copy or t ype t he follow ing T- SQL scr ipt int o t he Edit or pane in Query Analyzer,
and press F5 t o run t he script t o cr eat e t he dat abase. Alt ernat iv ely , y ou can open
t he script direct ly fr om Query Analy zer : choose Open fr om t he File m enu, and
t hen nav igat e t o t he locat ion of t he script . Not ice t hat t he first com m ent in t he
sam ple is “ Cr eat eSam pleDB” — t he nam e of t he sam ple file. I use t his convent ion
for all t he sam ples in t he book t o m ak e it easier for y ou t o locat e and open t hem
from Quer y Analyzer.

       At t a ching a D a t a ba se t o a N e w SQL
                   Se r ve r I nst a nce
I r egular ly r ead on t he SQL Ser ver newsgroups of folks asking how
t o at t ach a dat abase t o a server . These dev eloper s want t o t ake a
dat abase and it s obj ect s developed on one server and r un t hem on
anot her server. Their need can be as sim ple as copying a dat abase
applicat ion t hey are dev eloping on t heir deskt op t o t heir lapt op so
t hey can wor k on it while away from t he office. Alt er nat ively, t hey
m ay want t o copy a dat abase fr om headquar t ers or one branch
office t o one or m ore ot her br anch offices.
Alt hough t here ar e wizards for t his kind of t hing, it is nice t o know
how t o pr ogr am t he adm inist rat ion of t his k ind of t ask for y our own
cust om solut ions. This capabilit y liberat es you fr om t he canned
wizar d solut ion and gives y ou m ore flexibilit y in how y ou work wit h
SQL Serv er. At it s m ost elem ent ar y level, t his can be as sim ple as
at t aching a pair of dat abase files t o a new server inst ance. I n t he
cont ex t of t his chapt er , a com plet ed v ersion of t he Chapt er 02
dat abase is on t he book’s CD. Therefore, you m ight care t o copy a
version t o anot her inst ance of SQL Ser ver besides t he one y ou use
t o t est t he sam ples for t his chapt er. The inst ance can be on anot her
com put er or t he sam e com put er .
St art t o m igr at e t he Chapt er02 dat abase by copy ing t he
Chapt er 02_dat .m df and Chapt er 02_log.ldf files fr om t he CD t o t he
Dat a folder for t he SQL Serv er inst ance t o which you want t o at t ach
t he com plet ed dat abase. Aft er clear ing t he r ead- only at t r ibut e
set t ings for t he files, y ou can r un t he following scr ipt from Query
Analyzer . The script at t aches t he chapt er’s t wo dat abase files t o t he
default inst ance of t he SQL Serv er t o which Quer y Analyzer
connect s. By changing MSSQL t o MSSQL$MYOTHERI NSTANCE, you
can at t ach t he dat abase files t o a SQL Server inst ance nam ed
MYOTHERI NSTANCE. You m ust copy your dat abase files t o t he Dat a
pat h for t he SQL Server inst ance in t he sp_at t ach_db st at em ent
before r unning t he scr ipt .
--AttachSampleDB
--Run the script from the master database.
USE master

--Update the paths for the data and log files so they
--are appropriate for your computer.
EXEC sp_attach_db @dbname = N’Chapter02’,
   @filename1 =
    N’c:\Program Files\Microsoft SQL Server\MSSQL\Data\Cha
pter02_dat.mdf’,
   @filename2 =
    N’c:\Program Files\Microsoft SQL Server\MSSQL\Data\Cha
pter02_log.ldf’

The init ial USE st at em ent in t he script specifies t he source dat abase so t hat t he
sam ple r uns from t he SQL Ser ver m ast er dat abase. Next t he script rem ov es any
prior v ersion of t he Chapt er02 dat abase on t he serv er. This ensures t hat you can
always cr eat e a new copy of t he dat abase. Aft er r em ov ing any pr ior v ersion, t he
code invokes t he CREATE DATABASE st at em ent . This st at em ent assigns t he
logical filenam es Chapt er02_dat and Chapt er02_log t o t he dat a and log files for
t he dat abase. Alt hough your SQL Serv er dat abases can hav e m ore files, t hese
t wo are necessary for populat ing a dat abase and per form ing backup operat ions.
Updat e t he operat ing syst em file pat hs so t hat t hey are appr opr iat e for your
com put ing set up.
--CreateSampleDB
--Execute statements from the master database.
USE master
GO

--Drop any prior version of Chapter02 database.
IF EXISTS (SELECT *
    FROM   INFORMATION_SCHEMA.SCHEMATA
    WHERE CATALOG_NAME = N’Chapter02’)
DROP DATABASE Chapter02
GO

--Create new version of Chapter02 database.
CREATE DATABASE Chapter02
ON
(NAME = Chapter02_dat,
     FILENAME =
     ’c:\program files\microsoft sql server\mssql\data\Chapter02_dat.m
df’,
     SIZE = 1)
LOG ON
(NAME = Chapter02_log,
     FILENAME =
     ’c:\program files\microsoft sql server\mssql\data\Chapter02_log.l
df’,
     SIZE = 1,
     MAXSIZE = 5)
GO
D a t a Types for Ta bles
Tables are t he building blocks for SQL Serv er applicat ions because t hey st or e t he
dat a for t he ent it ies t hat an applicat ion m odels. Lik ew ise, colum ns are t he
building blocks of t ables because t ables st ore t heir dat a as colum n values. SQL
Ser ver applicat ions can oft en have t ables w it h num er ous rows, so it is im port ant
t o specify t he dat a t ype for colum ns t o ensur e t hat t hey use t he m inim um
am ount of st orage. When y ou specify t he dat a t ype, you ar e indicat ing t he k ind of
dat a t hat t he colum n is going t o cont ain. Making t hese assignm ent s cor rect ly
speeds t he perform ance of y our SQL Ser ver applicat ions w hile also conser ving
st orage space. I n addit ion, t he v alidit y of y our dat abase m odel for a r eal- w or ld
syst em can depend on t he use of pr oper dat a t y pes.
I n m any circum st ances, y our applicat ions can denot e dat a wit h one of t he dat a
t ypes built int o SQL Ser ver— t he syst em dat a t y pes. When your applicat ion needs
m or e definit ion t han t hese syst em dat a t ypes allow nat iv ely, you can creat e user-
defined dat a t y pes t hat refine t he syst em dat a t ypes. Howev er, y our abilit y t o
fashion valuable user - defined dat a t ypes depends on your grasp of t he syst em
dat a t ypes.
I f you ar e fam iliar wit h dat a t ypes, y ou m ay want t o skip t his sect ion and refer t o
it as needed. But if you are new t o SQL Serv er program m ing or need a refr esher
on dat a t ypes, read on.

Syst e m D a t a Type s

I t is useful t o t hink about t he syst em dat a t ypes in six gr oups. I n addit ion t o t he
six hom ogeneous cat egor ies, t her e is a collect ion of special, or m iscellaneous,
syst em dat a t ypes. The six hom ogeneous gr oups of dat a t ypes pert ain t o:

    •     Charact er dat a
    •     Unicode dat a
    •     Num er ic dat a
    •     Monet ary dat a
    •     Dat e and Tim e dat a
    •     Binary dat a

Ch a r act e r D a t a

Charact er dat a consist s of alphanum eric charact er sequences. Ther efor e, y ou can
represent any com binat ion of num bers and w or ds wit h charact er dat a, such as
“123 Mulber ry Lane”, “$1,000,000”, “Your nam e goes her e: ” or “Rick Dobson”.
SQL Ser ver has t hree charact er dat a t ypes: char, v archar, and t ext . The follow ing
t able br iefly sum m ar izes t hem .
   'DWD                                   'DWD 7\SH 'HVFULSWLRQ
   7\SH
  1DPH
char        For fixed- lengt h charact er dat a up t o 8000 charact ers. Use char ( n) t o
            specify, wit h n as t he num ber of charact ers. The st orage size is n byt es.
            Appr opriat e w hen all t he colum n values are t he sam e lengt h ( or w hen
            t his is v er y near ly t r ue) .
varchar     For var iable- lengt h char act er dat a up t o 8000 charact ers. Use
            v archar( n) t o specify, w it h n as t he m axim um num ber of charact ers.
          The st orage size for any varchar colum n value is t he act ual size, w her e
          1 byt e equals 1 charact er . Appr opr iat e when t her e is subst ant ial
          v ariabilit y in lengt h bet ween colum n values.
t ext       For var iable- lengt h char act er dat a t hat can grow t o 2 31 - 1
            ( 2,147,483,647) charact ers in t he SQL Serv er inst ance’s code page
            for m at . Alt hough som e of t hese code pages perm it double- byt e form at
            for r epresent ing charact ers, t he lengt h of a t ext dat a t ype colum n value
            is st ill t he num ber of charact ers, w her e 1 charact er equals 1 byt e.
SQL Ser ver support s im plicit and explicit conv er sion bet ween dat a t ypes. SQL
Ser ver handles im plicit conv ersions aut om at ically ; you use t he CAST and
CONVERT funct ions t o convert bet ween t ypes explicit ly . The CONVERT funct ion is
a propr iet ary ext ension of t he CAST funct ion t hat offers ext ra conv ersion
capabilit y not available from CAST, which is SQL- 92 com pliant . See t he “CAST
and CONVERT” t opic in SQL Ser ver Books Online for m ore det ail on conversion
bet ween SQL Ser ver dat a t ypes.
I m plicit conv ersions don’t depend on t he t ransform at ion of a value by t he
CONVERT or CAST funct ion. I m plicit conv ersion also applies t o t he conv ersion of a
result fr om com bining or com par ing t w o or m or e values wit h different dat a t ypes.
A var iet y of Books Online t opics clar ify im plicit conversion, including t he “ CAST
and CONVERT” t opic. For exam ple, see t he “Dat a Type Conversion,” “Dat a Types
and Table St ruct ures,” and “Dat a Type Pr ecedence” Books Online t opics. You can
use t he Search t ab in Books Online t o search for t hese t opics. The Book s Online
search engine w ill oft en r et urn m ult iple t opics for any search st r ing, ev en w hen
you specify a precise search t opic t it le. Scan t he list of t it les ret urned by t he
search engine for t he ex act one y ou seek.

Un icode D a t a

Unicode is a 16- bit char act er encoding st andard. SQL Serv er dat a t ypes for
Unicode cor respond t o SQL charact er dat a t ypes— nchar , nvarchar , and nt ext for
fix ed- lengt h, var iable- lengt h, and v er y long Unicode dat a. One k ey dist inct ion is
t hat t he Unicode form at for t r anslat ing bit s t o charact ers r elies on a single
st andard t ranslat ion t able t hat uses 2 byt es per charact er . The charact er dat a
for m at s use a collect ion of differ ent code pages m ost of which assign 1 byt e per
charact er . This dist inct ion gives Unicode form at t he capacit y t o r epr esent m or e
t han 65,000 charact ers, while non- Unicode char act er dat a t ypically repr esent s
only 256 charact ers at a t im e ( or per code page) . The Unicode codes t hat hav e
been assigned r epresent charact ers in m ost of t he wr it t en languages of t he wor ld.
Charact er dat a uses syst em - lev el t ables called code pages t o det erm ine how t o
t ranslat e bit s t o charact ers. Different count ries can r ely on differ ent code pages t o
represent t heir charact er set . For applicat ions t hat r un in m any different
count ries, it can be challenging t o find a single code page w it h valid and
consist ent bit - t o- charact er t ranslat ions for all languages. Using Unicode dat a
resolv es t his pr oblem because it s code page accom m odat es 2 16 charact ers. The
price for t his easier cross- count ry applicabilit y is t hat each charact er has a size of
2 by t es inst ead of t he 1 byt e per charact er. As a r esult , t he m ax im um num ber of
charact ers for Unicode dat a t ypes is half t hat of cor responding charact er dat a
t ypes.
The follow ing t able sum m ar izes t he t hr ee Unicode dat a t ypes. These dat a t ypes
align w it h t he charact er dat a t ypes, but t hey have differ ent lengt h and
applicabilit y.
'DWD 7\SH                                'DWD 7\SH 'HVFULSWLRQ
   1DPH
nchar       For fixed- lengt h charact er dat a up t o 4000 char act ers in lengt h w it h a
            Unicode dat a form at . Use nchar ( n) t o specify, w it h n as t he num ber of
              charact ers. The st orage size in byt es equals t wice t he num ber of
              charact ers. Corresponds t o t he char dat a t ype in t erm s of applicabilit y
              except for it s broader usefulness for repr esent ing charact ers from
              m ult iple languages.
nvarchar For var iable- lengt h char act er dat a up t o 4000 charact ers in lengt h. Use
         nvarchar ( n) t o specify, wit h n as t he m ax im um num ber of charact ers.
         The st orage size for any nvarchar colum n value is t he act ual size,
         wher e 2 byt es equal 1 charact er. Corr esponds t o t he varchar dat a t ype
         in t erm s of applicabilit y except for it s broader usefulness for
         represent ing charact ers fr om m ult iple languages.
nt ext        For var iable- lengt h char act er dat a t hat can grow t o 2 30 - 1
              ( 1,073,741,823) charact ers in t he Unicode code page form at .
              Cor r esponds t o t he t ext dat a t ype in t erm s of applicabilit y except for it s
              broader usefulness for r epresent ing charact ers from m ult iple
              languages.

                                       N ot e
I n t he case of colum n dat a t y pe specificat ions, precede t he
charact er dat a t y pe nam e w it h an n t o denot e t he m at ching
Unicode dat a t ype nam e. Repr esent charact er const ant s in
SQL Server wit h single- quot at ion m ark delim it ers. Use a
leading N t o represent a Unicode const ant . For exam ple, a
charact er const ant appears as ‘my character constant’ .
However, t he m at ching Unicode equiv alent appear s as N’my
Unicode constant’ .

N u m e r ic D a t a

Num er ic dat a consist s of num bers only. You can per form arit hm et ic operat ions on
num er ic dat a, and y ou can com pare num er ic values along a num eric scale, w hich
can differ fr om com par isons based on collat ions for charact er dat a and Unicode
dat a. SQL Serv er has t hree general cat egor ies for num er ic dat a: int eger dat a,
decim al dat a, and approxim at e dat a. Wit hin each of t hese cat egor ies, t her e are
one or m or e specific dat a t ypes. Bey ond t hat , t he num eric dat a cat egor ies denot e
different classes of num bers or ways of r epresent ing num bers.

I n t ege r Da t a

I nt eger dat a t ypes denot e values t hat SQL Ser v er r epr esent s exclusively as whole
num bers. The int eger dat a t ypes include t iny int , sm allint , int , and bigint . The dat a
t ypes differ pr im ar ily in t he m agnit ude of t he num ber t hat t hey can r epr esent ,
but t he t iny int dat a t ype differs in t hat it cannot represent negat iv e values as can
t he ot hers. I nt eger dat a t ypes, part icular ly int , are com m only used along w it h t he
I DENTI TY propert y t o specify aut om at ically incr em ent ing colum n v alues t hat
serv e as t he pr im ar y k ey for a t able.
The next t able list s t he int eger dat a t ypes along wit h br ief sum m ar ies of t heir
capabilit ies. Your applicat ions should generally use t he sm allest dat a t ype
possible. However, use a dat a t ype w it h sufficient range for y our needs because
SQL Ser ver rej ect s colum n values out side t he lim it s for a dat a t ype. Calculat ions,
such as aggregat ions in views, w ork different ly for t iny int and sm allint v alues. I n
t hese cases, SQL Serv er aut om at ically prom ot es t he r et ur n value t o t he int value
range. Therefor e, t he sum of a set of t iny int colum n values can exceed 255, but
no indiv idual t iny int colum n value can ex ceed 255.
The t iny int / sm allint prom ot ion policy doesn’t apply t o calculat ions based on int
colum n values; SQL Ser ver doesn’t aut om at ically pr om ot e a r et ur n value out side
t he int lim it s— even if t he result is wit hin t he bigint lim it s. I nst ead, SQL Ser ver
ret ur ns an er ror. I n addit ion, t he bigint dat a t ype doesn’t work w it h all funct ions
t hat t he ot her int eger dat a t y pes can use, and t her e are special funct ions for
select ed t asks, such as count ing inst ances and ret ur ning r ows affect ed by
quer ies, in which t he quant it ies exceed t he int r ange t o fall in t he bigint range.
See t he “Using bigint Dat a” t opic in Books Online for m ore det ail on t he special
rest r ict ions t hat apply t o t he bigint dat a t ype.
'DWD 7\SH                                 'DWD 7\SH 'HVFULSWLRQ
      1DPH
t iny int    For values in t he range 0 t hr ough 255. Each t iny int colum n value is 1
             byt e long.
sm allint    For values from - 2 15 ( - 32,768) t hrough 2 15 - 1 ( 32,767) . Each sm allint
             colum n value consum es 2 byt es of st orage.
int          For values from - 2 31 ( - 2,147,483,648) t hr ough 2 31 - 1 ( 2,147,483,647) .
             Each int colum n value r equires 4 byt es of st orage.
bigint       For values from - 2 63 ( - 9,223,372,036,854,775,808) t hr ough 2 63 - 1
             ( 9,223,372,036,854,775,807) . Each bigint colum n value requir es 8
             byt es of st orage.

De cim a l D a t a

The decim al dat a cat egory is a single num er ic cat egory w it h t w o equivalent SQL
Ser ver dat a t ypes: num er ic and decim al. You can use t hem int erchangeably, but
decim al is pr obably t he m or e com m on dat a t ype nam e. Like t he int eger dat a
t ypes, t he decim al dat a t ypes pr ecisely r epr esent values. How ev er , decim al dat a
t ypes differ from int eger dat a t y pes in t hree ways. First , decim al dat a t ype values
allow for places aft er t he decim al. ( Recall t hat int eger dat a t ypes rest r ict you t o
whole num bers.) Second, decim al dat a t ype specificat ions per m it a v ar iable
precision ( or t ot al num ber of digit s) . The t ot al num ber of digit s, w hich can range
from 1 t hr ough 38, includes digit s t o t he right and left of t he decim al point . Third,
you can designat e a decim al dat a t y pe for a colum n w it h var iable scale ( or digit s
t o t he r ight of t he decim al point ) .

                                     N ot e
The decim al dat a t y pe in SQL Serv er 2000 and t he Decim al
dat a t ype in Visual Basic .NET aren’t t he sam e. The Decim al
dat a t ype in Visual Basic can represent num ber s wit h values
fr om 1 t hr ough 28 digit s t o t he right and left of t he decim al
point . This dist inct ion ( 1 t hrough 28 v s. 1 t hr ough 38) is
im port ant . Unless pr oper pr ecaut ions ar e t ak en, you can
encount er over flow err or s as y ou ext ract colum n v alues wit h
a decim al dat a t ype from a SQL Serv er t able int o your Visual
Basic .NET applicat ion. I f you know t he num ber s in t he SQL
Server t able exceed t he v alues t hat Visual Basic .NET can
represent wit h it s Decim al dat a t ype, consider represent ing
t he SQL Serv er decim al dat a t y pe v alues wit h anot her dat a
t y pe in Visual Basic .NET, such as Double, which has a range
fr om - 1.79E + 308 t hr ough 1.79E + 308.
Designat e a decim al cat egory value w it h decim al( p,s) or num eric( p,s) . The p
value r epresent s t he pr ecision; t he s value denot es t he scale. The pr ecision m ust
be less t han or equal t o 38 but great er t han or equal t o t he scale. The scale m ust
be less t han or equal t o t he pr ecision, but t he scale has t o be gr eat er t han or
equal t o 0. The m ax im um dat a range for decim al t ype values is fr om - 10 38 + 1
t hr ough 10 38 - 1. This r ange subst ant ially ex ceeds t he lim it s of any int eger dat a
t ype. The sam e holds t r ue for t he t w o m onet ar y dat a t ypes t hat SQL Ser ver
offers. ( We’ll rev iew t hese short ly.)

                                    N ot e
Colum ns w it h t he decim al dat a t ype specificat ion can also
serve as an aut o- increm ent ing pr im ary k ey w hen you assign
an I DENTI TY pr opert y t o t he colum n. Set t he scale t o 0 for
t his applicat ion of t he dat a t y pe.
The lengt h in byt es for t he decim al dat a t ype specificat ion depends on t he
precision. The follow ing t able sum m arizes t he relat ionship bet ween st or age
requir em ent s and pr ecision for decim al dat a t ypes.
               3UHFLVLRQ                                   6WRUDJH %\WHV
1–9                                   5
10–19                                 9
20–28                                 13
29–38                                 17

App roxim a t e D at a

All t he prior num er ic dat a t ypes pr ecisely r epr esent ed dat a values. This avoids
rounding err or . The t wo approx im at e dat a t ypes allow you t o represent dat a
values wit hout perfect precision ( but ext rem ely close t o t he exact value) . I n
exchange for r educed precision r equirem ent , t he approx im at e dat a t ypes offer a
m uch w ider range t han t he pr ev ious dat a t ypes. When y ou need t o repr esent
num bers bey ond t he range of t he preceding num er ic cat egory dat a t ypes, t he
approx im at e dat a t y pes offer a v iable alt er nat iv e ( for exam ple, in engineer ing
applicat ions w or king wit h v ery large or sm all values) . Approxim at e dat a t ypes
also enable your applicat ions t o use less st orage space when r educed precision is
accept able for y our needs.
The t wo SQL Ser ver approx im at e dat a t ypes ar e r eal and float . The real dat a t ype
offers t he sm aller range and precision, but it r equires j ust 4 byt es per dat a value.
I t s range ext ends from - 3.40E + 38 t hr ough 3.40E + 38. The float dat a t ype
ext ends from - 1.79E + 308 t hr ough 1.79E + 308, but each float dat a t y pe value
requir es 8 byt es of st or age. Therefore, t he float dat a t ype offers increased range
and precision r elat ive t o t he r eal dat a t ype, but float dat a t ype v alues consum e 4
m or e byt es per colum n value. Bot h dat a t ypes follow t he I EEE ( I nst it ut e of
Elect r ical and Elect ronic Engineers) 754 specificat ion for approx im at e dat a t y pes.
SQL Ser ver uses t he round up m ode, which is one of four r ounding m odes in t he
754 specificat ion.

M on et a ry D a t a

SQL Ser ver has t wo dat a t ypes for r epr esent ing m onet ary dat a. Bot h are accurat e
t o t he near est t en- t housandt h of a m onet ary unit . The sm allm oney dat a t ype has
a range fr om - 214,748.3648 t hr ough 214,748.3647. SQL Serv er r equires 4 byt es
of st orage for each value w it h t his dat a t ype. The m oney dat a t ype has a range
t hat st art s at - 922,337,203,685,477.5808 and runs t hrough
922,337,203,685,477.5807. This dat a t ype consum es 8 byt es of st orage for each
colum n value. Wit h eit her dat a t ype, y ou can use a cur r ency sym bol, such as $,
and a decim al point w hen input t ing values, but you shouldn’t input values w it h
com m as. I n ot her w ords, use $1234.5678 inst ead of $1,234.5678.
As y ou can see, t he t w o m onet ary dat a t ypes ar e t w o possible variat ions of t he
decim al dat a t ype in t erm s of it s pr ecision and r ange. For exam ple, you can
represent sm allm oney dat a t ypes wit h decim al( 10,4) . The m oney dat a t ype has
decim al( 19,4) . When you need t o represent m onet ary dat a wit h ot her form at s,
use alt er nat iv e decim al specificat ions, such as decim al( 19,2) or decim al( 38,2) .

Da t e an d Tim e D a t a

SQL Ser ver has t wo dat a t ypes for int er nally r epresent ing dat e and t im e v alues.
These dat a t ypes differ in precision as w ell as range. Befor e div ing int o t he det ails
of each dat a t ype, not e t hat SQL Ser ver dat a t y pes for dat e and t im e v alues
always cont ain bot h a dat e and a t im e value. I n addit ion, while SQL Ser ver uses
one of t w o int er nal form at s for st or ing dat e and t im e values, it displays dat e and
t im e values as st r ings. I n addit ion, you will frequent ly input a new dat e or t im e
colum n value as a st ring. When designat ing a dat e or a t im e value w it h a st ring,
you can designat e j ust t he dat e, j ust t he t im e, or bot h t he dat e and t he t im e.
The sm alldat et im e dat a t y pe has t he short er range of t he t wo dat a t ypes for
dat es and t im es. This dat a t ype includes dat es from January 1, 1900, t hr ough
June 6, 2079. Wit hin any given day, sm alldat et im e dat a t y pe values r epresent
t im e from 12: 00 A.M. ( m idnight ) t hr ough 11: 59 P.M., t o t he near est m inut e. The
sm alldat et im e dat a t y pe rounds down t o t he nearest m inut e for all values of
29.998 seconds or less. Conv ersely , it r ounds up t o t he near est m inut e for all
values of 29.999 seconds or m or e. You can designat e a dat et im e value wit h a
charact er st ring t o t he near est one- t housandt h of a second, such as '        January 1,
                         ,
1900 12: 00: 29.998' for im plicit conv ersion as input t o colum ns wit h a sm all-
dat et im e dat a t ype specificat ion. Each sm alldat et im e colum n v alue r equires 4
byt es of st orage— t w o for t he dat e and t wo for t he t im e.
The ot her dat a t ype for dat e and t im e values is dat et im e. Values in dat et im e
for m at can range from January 1, 1753, t hr ough Decem ber 31, 9999. As wit h t he
sm alldat et im e dat a t y pe, t he dat et im e dat a r epr esent s t im e from m idnight .
Howev er, t he pr ecision is t o t he nearest 3.33 m illiseconds. Therefore, y ou can
                                                             00:               .
represent t he first t im e value aft er m idnight as ' 00: 00: 003' SQL Serv er
rounds dat et im e values int ernally t o t he near est m illisecond wit hin it s pr ecision.
                                                                                  00:
For exam ple, t im e values t o t he near est m illisecond pr ogr ess from ' 00: 00: 000'
     00:                   00:                .
t o ' 00: 00: 003't o ' 00: 00: 007' The dat et im e dat a t ype specificat ion
consum es 8 byt es of st orage— 4 byt es for t he dat e and 4 byt es for t he t im e.

Bin a r y D at a

Binary dat a represent s dat a in it s nat iv e binar y form at . For exam ple, a GUI D, or
globally unique ident ifier, appears as a 16- byt e binary dat a st ream . SQL Serv er
represent s each byt e w it h t wo hex adecim al num bers. The decim al num ber 17, for
exam ple, appears as 11 in hexadecim al form at , which cor responds t o 00010001
as a byt e. Hexadecim al for m at t ing uses t he let t ers A t hr ough F t o denot e t he
decim al v alues 10 t hrough 15. Therefor e, t he hexadecim al num ber 9F t ranslat es
t o 159 in decim al for m at , or 10011111 as t he bit s for a byt e. SQL Ser ver
fr equent ly denot es hex adecim al v alues for input and display w it h a leading 0x ;
t hat is, a zer o follow ed by a lowercase x. Of course, t he int er nal represent at ion
cont ains j ust t he binary represent at ion for dat a.
Ther e ar e t hr ee dat a t y pes for binar y dat a in SQL Ser ver. When you ar e w or king
wit h dat a st r ings of 8 KB or less, use eit her binary or varbinary. For longer binar y
dat a st ream s, such as Word docum ent s or Excel w orksheet s in Office 97 or Office
2000, use t he im age dat a t ype. The follow ing t able sum m arizes t he t hr ee binary
dat a t ypes.
'DWD 7\SH                                'DWD 7\SH 'HVFULSWLRQ
  1DPH
binary      For fixed- lengt h binar y dat a up t o 8000 byt es in lengt h. Use binary ( n)
            t o specify, w it h n as t he num ber of byt es. The st orage size is n byt es.
            Appr opriat e w hen all t he colum n values are t he sam e lengt h.
varbinary For var iable- lengt h binary dat a up t o 8000 byt es in lengt h. Use
          varbinary ( n) t o specify, wit h n as t he m ax im um num ber of byt es. The
          st orage size for any var binary colum n value is t he act ual size of a bit
          st ream in byt es. Appr opriat e when not all colum n values ar e t he sam e
          lengt h.
im age      For var iable- lengt h char act er dat a t hat can grow t o 2 31 - 1
            ( 2,147,483,647) byt es. Use t his dat a t ype w hen your binary dat a
            ex ceeds 8 KB for any colum n values. Alt hough t he dat a t ype’s nam e is
            im age, it accom m odat es any binar y dat a, including bit m ap or GI F
            im age files as well as Word .doc files.


Spe cia l Syst e m D a t a Type s

Four rem aining syst em dat a t ypes com plet e t he set available for specify ing
colum ns in a t able: t im est am p, bit , uniqueident ifier , and sql_var iant . These dat a
t ypes don’t fit int o any one cat egor y. This sect ion addr esses each of t he dat a
t ypes indiv idually.
The t im est am p dat a t ype is a binary v ariable t hat t racks t he lat est addit ion or
revision of a r ow t hroughout a dat abase. I t is a sequent ial num ber— som ew hat
lik e an aut onum ber in Access or an int eger wit h an I DENTI TY pr opert y set t ing in
SQL Ser ver. How ev er, it pert ains t o an ent ire dat abase inst ead of a single t able
wit hin a dat abase. Whenever a user adds a new r ow or r ev ises a v alue in a row of
a t able wit h a t im est am p colum n, t he t im est am p colum n value incr eases by 1.
SQL Ser ver repr esent s t his t im est am p v alue as an 8- byt e binary value. I f t he
largest t im est am p value t hr oughout any row in any t able of a dat abase is
0x13579BDF, t he next t im est am p value w ill be 0x13579BE0.

                                    N ot e
Colum ns declared wit h a t im est am p dat a t y pe don’t cont ain
dat et im e or sm alldat et im e values. Micr osoft announced it s
int ent ion t o reference t he t im est am p dat a t y pe as t he
rowv er sion dat a t ype in fut ur e SQL Ser v er ver sions.
The bit dat a t ype is for r epr esent ing Tr ue/ False or Yes/ No dat a. I n SQL Ser ver, a
bit dat a t ype w it h t he v alue 1 is equivalent t o True or Yes. The bit value 0
corr esponds t o False or No. You can, opt ionally, m ak e a bit dat a t ype nullable so
t hat it can hav e t he value 0, 1, or NULL. Values in bit form at consum e 1 bit , and
SQL Ser ver packs bit dat a values 8 bit s t o t he byt e t o conser ve space. Ther efor e,
1 t hrough 8 bit dat a t ype colum ns in a row requir e 1 byt e of st orage. The nint h
t hr ough t he sixt eent h bit dat a t ype colum ns add a second byt e of st orage for
each row.
The uniqueident ifier dat a t ype specifies a 16- by t e GUI D. Since a GUI D is unique
in space and t im e, t he uniqueident ifier is a candidat e for ident ify ing r ow s across
m ult iple inst allat ions of SQL Ser ver, such as by st at e in t he Unit ed St at es or by
count ry. How ev er , because of it s size, using a uniqueident ifier can slow an
applicat ion and consum e st orage dispr oport ionat ely. The sever it y of t his
uniqueident ifier w eak ness escalat es wit h t he num ber of rows in a t able. Consider
using an int ( or ev en a bigint ) colum n w it h an I DENTI TY propert y along wit h a
second colum n t o denot e place. This alt ernat iv e approach t o uniquely ident ify ing
records at m ult iple locat ions can m ake an applicat ion r un fast er and consum e less
st orage. Also, t he uniqueident ifier doesn’t w or k well for t he full range of SQL
Ser ver funct ions; see t he “ uniqueident ifier” and “Using uniqueident ifier Dat a”
t opics in Books Online for m ore det ail.
A sql_var iant dat a t ype specificat ion enables a colum n in a t able t o accept a
m ix ed collect ion of dat a values based on any ot her syst em dat a t ype ex cept t ext ,
nt ext , t im est am p, im age, and sql_var iant . All ot her syst em dat a t ypes requir e t he
values in a colum n t o be of one dat a t ype. You can’t ent er charact er dat a int o a
colum n wit h an int dat a t ype. Wit h a sql_var iant dat a t ype specificat ion, a single
colum n can cont ain char, int , and dat et im e dat a values all in a single colum n. The
sql_var iant dat a t ype nam e der iv es it s nam e because of it s sim ilarit y t o t he Visual
Basic Var iant dat a t ype.
The m ix ed dat a t ype values in a sql_var iant colum n can cause it s values t o
behave different ly w hen you’re com par ing sql_v ariant values w it h values of
anot her dat a t ype or w hen y ou’r e sort ing a t able by t he values in a sql_var iant
colum n. See t he “Using sql_v ariant Dat a” t opic in Books Online for m or e det ails
on t his t opic.
'DWD 7\SH 1DPH                                'DWD 7\SH 'HVFULSWLRQ
t im est am p     The t im est am p dat a t ype has a binary ( 8) dat a form at unless you
                  m ake it nullable. A nullable t im est am p dat a t ype has a
                  varbinary ( 8) dat a form at . SQL Serv er aut om at ically generat es
                  t im est am p values; your applicat ion or your users hav e no need t o
                  populat e a t im est am p colum n.
bit               Pr im arily for m odeling at t ribut es t hat can hav e one of t w o st at es.
                  Howev er, t he dat a t ype also does perm it NULL v alues. SQL
                  Ser ver opt im izes st orage of bit dat a t ype values so t hat t he first 8
                  t ake up t o 1 byt e, t he next 8 a second byt e, and so on.
uniqueident ifier A 16- byt e binary num ber t hat r epresent s it s value as 32
                  hexadecim al charact ers. The form at for display ing t he -
                  hexadecim al charact ers is xx xxx xxx - x xxx - x xxx - xxxx -
                  xxxx xxx xxx xx. Use t he NewI D funct ion t o generat e a new
                  uniqueident ifier. You can specify a uniqueident ifier value eit her
                  wit h a charact er st r ing r epr esent ing t he 32 hex adecim al
                  charact ers or w it h a binary num ber. Howev er, always use t he
                  NewI D funct ion w hen y ou m ust ensur e t he uniqueness of t he
                  uniqueident ifier value.
sql_var iant      For st or ing m ult iple ot her k inds of dat a t ype values in a single
                  colum n. This SQL Serv er dat a t ype bears a r esem blance t o t he
                  Visual Basic Var iant dat a t ype.

                                     N ot e
Two addit ional SQL Server t ypes do not r epresent individual
num bers or st r ing values. These ar e t he t able and cursor
t y pes. The t able ty pe can represent a whole r esult set of
values, such as a t able r et urned by a user- defined funct ion.
Chapt er 5 dem onst rat es t he use of t his SQL Serv er t ype. The
SQL Server cur sor t ype refers t o server- side cur sors. Many
dev eloper s prefer t o avoid t his t ype because it can degr ade
dat abase perfor m ance.

Use r - D e f ine d D a t a Type s

User- defined dat a t ypes enable you t o define cust om dat a t ypes based on syst em
dat a t ype and nullabilit y . You and your dev eloper t eam can t hen apply t hese
user - defined dat a t ypes in m ult iple t ables t hroughout a dat abase. The scope of a
user - defined dat a t ype is t he cur rent dat abase, but y ou can copy t he script
defining a user - defined dat abase t o ot her dat abases.
Use t he sp_addt ype and sp_dropt y pe syst em st or ed procedur es t o add and drop
user - defined dat a t ypes t o and from a dat abase. When you add a user - defined
dat a t ype w it h sp_addt ype, specify it s nam e, base dat a t ype, and nullabilit y by
posit ion or w it h param et er nam e assignm ent s. Aft er creat ing a user - defined dat a
t ype, you can assign it t o t able colum ns t hroughout a dat abase. I f y ou add a
user - defined dat a t ype t o t he m odel dat abase, every new user - defined dat abase
will hav e t he user - defined dat a t ype. This is because SQL Serv er uses t he m odel
dat abase as a st art ing point for all user- defined dat abases. The sp_dropt y pe
syst em st ored procedur e can generally r em ove a user- defined dat a t ype from a
dat abase, but t his syst em st ored pr ocedur e w on’t succeed if any t ables ex ist wit h
colum ns defined by t he user - defined dat a t ype.

                                    N ot e
Sy st em st ored procedures, such as sp_addt ype and
sp_dropt ype, gain focus as a general t opic in Chapt er 4.
The sp_addt ype syst em st ored pr ocedur e allows you t o specify a user - defined
dat a t ype in t erm s of it s base dat a t ype. For ex am ple, y ou can designat e a post al
code dat a t ype w it h a char( 5) or a char ( 9) base dat a t ype. How ever, users can
st ill ent er values ot her t han num bers in t he post al code charact er fields. To
specify const raint s t hat apply t o user - defined dat a t ypes, designat e a SQL Ser ver
Rule obj ect and bind t he rule t o t he user - defined dat a t ype; use t he sp_bindr ule
syst em st ored procedur e t o bind a r ule. Then dev elopers can specify new t ables
wit h colum ns specified by user - defined dat a t y pes t hat conv ey t he r ule. This
approach for apply ing r ules bound t o user - defined dat a t ypes works for t he
creat ion of new t ables but not for t he m odificat ion of ex ist ing colum ns in ex ist ing
t ables. For im plem ent at ion det ails of user - defined dat a t ypes, see t he Books
Online t opics for sp_addt y pe, sp_dr opt ype, and sp_bindr ule.

                                    N ot e
Exam ine t he pubs sam ple dat abase in Ent er prise Manager for
several ex am ples of how t o apply user- defined dat a t y pes in
a dat abase.



Scr ipt in g Ta ble s
The “Dat a Types for Tables” sect ion earlier in t his chapt er described t he m ost
fundam ent al elem ent s of a t able. How ev er , it didn’t dem onst rat e how t o apply
t hose elem ent s t o t he const r uct ion of a t able. This sect ion int r oduces T- SQL
st at em ent s and synt ax rules for cr eat ing t ables. The sect ion also exam ines issues
relat ing t o t he processing of select ed dat a t ypes and t he m odify ing of a t able’s
design.

Cr e a t in g a Ta ble

You use t he CREATE TABLE st at em ent t o creat e a new t able. Before inv ok ing t he
st at em ent , y ou m ust designat e a dat abase t o hold y our new t able. Specify t his
dat abase wit h t he USE st at em ent . The follow ing sam ple script assigns it s new
t able, Em ailCont act s, t o t he Chapt er02 dat abase; r ecall t hat t he “ Chapt er
Resources” sect ion includes a script for creat ing a fresh copy of t his dat abase.
Wit hin t he CREATE TABLE st at em ent , y ou can specify colum n nam es for t he t able
along w it h dat a t ypes and ot her set t ings for each colum n. The script cr eat es a
t able nam ed Em ailCont act s wit h four colum ns nam ed Cont act I D, First Nam e,
Last Nam e, and Em ail1. The Cont act I D colum n ser ves as a prim ary k ey. The
colum n’s specificat ion includes a nam e ( Cont act I D) , a dat a t ype ( int ) , and a
specificat ion for it s nullabilit y ( NOT NULL) ; and t he last key word designat es t he
colum n as a pr im ary key. Because t he t able includes addit ional colum ns, t he
colum n declarat ion ends wit h a com m a.
The rem aining t hree declarat ions wit hin t he CREATE TABLE st at em ent specify
colum ns for holding cont act dat a. Each of t hese declarat ions begins wit h a colum n
nam e follow ed by a dat a t ype and a nullabilit y assignm ent . A com m a separat es
t he declarat ion for each colum n. I n cont rast wit h t he colum n serv ing as t he
prim ary k ey for t he t able, t he t hr ee colum ns for st or ing cont act dat a can be null.
This allows a user t o creat e a row for a cont act at one t im e and t hen populat e t he
row at a lat er t im e. SQL Ser ver has a default set t ing for t he nullabilit y of colum ns
t hat y ou can configur e. The default configurat ion is for ANSI com pat ibilit y, w hich
allows nulls for new colum ns. Nev ert heless, it is good pract ice t o designat e t he
nullabilit y of colum ns ex plicit ly.
--CreateEmailContactsTable_01
--Execute statements after USE from Chapter02 database
USE Chapter02
--Create EmailContacts with three columns.
CREATE TABLE EmailContacts
(
ContactID int Not Null PRIMARY KEY,
FirstName nvarchar(20) NULL,
LastName nvarchar(35) NULL,
Email1 nvarchar (255) NULL
)
GO

The script will work t he first t im e y ou run it . Howev er , if you t ry t o run t he script
a second t im e, it will fail wit h a m essage rem inding y ou t hat t he Em ailCont act s
t able is already in t he dat abase. I n order t o rer un t he CREATE TABLE st at em ent
successfully, you can condit ionally dr op t he Em ailCont act s t able. You need t o
drop t he t able condit ionally because t he DROP TABLE st at em ent w ill fail if t he
t able isn’t already in t he dat abase. While y ou’r e edit ing t he preceding script , it
m ight be nice t o add som e dat a and t hen r un a sim ple SELECT query t o see how
t o insert and ret rieve dat a fr om t he t able. The next script dem onst rat es
t echniques for achiev ing t hese r esult s.
This nex t script illust rat es broad design issues for r unning T- SQL script s in Query
Analyzer. For exam ple, t he USE st at em ent designat es a source dat abase t o use
for r unning t he st at em ent . USE isn’t a T- SQL st at em ent ; rat her , it is a keyw ord
for Quer y Analyzer t hat inst ruct s it t o connect t o a dat abase on t he ser ver for t he
curr ent Query Analyzer session. I f t he dat abase doesn’t ex ist on t he connect ion,
Query Analyzer r et ur ns an er ror m essage. Not ice also t hat bat ches of T- SQL
st at em ent s ar e delim it ed by t he GO k eyw ord. This is a keyword for Query
Analyzer as w ell. The GO k eyw ord inst r uct s Quer y Analyzer t o int erpret and run
t he preceding T- SQL st at em ent s. Posit ion t he GO k eyw ord in script s t o ensur e
t hat a set of st at em ent s will r un before y ou st ar t anot her set of st at em ent s. This
keyw ord is convenient for isolat ing er rors.
Aft er t he USE st at em ent , t he script t est s for t he prior ex ist ence of t he
Em ailCont act s t able. I f it does ex ist in t he curr ent dat abase, t he script inv ok es a
DROP TABLE st at em ent t o r em ov e t he pr ior v er sion of t he t able. An I F EXI STS
st at em ent based on an I NFORMATI ON_SCHEMA view is a com m on m eans of
t est ing for t he ex ist ence of a dat abase obj ect . I NFORMATI ON_SCHEMA views
ret ur n m et adat a about m any classes of SQL Serv er dat abase obj ect s besides
t ables. A subsequent sect ion dwells on t his t opic m or e specifically.
The CREATE TABLE st at em ent is ident ical t o t he preceding T- SQL list ing.
Howev er, in t he cont ext of t his sam ple, y ou can r er un t he script r epeat edly
wit hout encount er ing an err or m essage about t he obj ect already ex ist ing. Aft er
creat ing t he t able, t he follow ing list ing populat es t he t able w it h t wo row s. I t uses
t he I NSERT I NTO st at em ent t o add r ows. Because t hese st at em ent s designat e
colum n values for all t he t able’s colum ns in t he order in w hich t hey appear in t he
t able, t he st at em ent s can sim ply r eference t he VALUES k ey word follow ed by t he
colum n values for a row .
--CreateEmailContactsTable_02
--Execute statements after USE from Chapter02 database.
USE Chapter02
GO

--Remove prior version of EmailContacts if it exists.
IF EXISTS
    (
    SELECT *
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = ’EmailContacts’
    )
DROP TABLE EmailContacts

--Create EmailContacts with three columns.
CREATE TABLE EmailContacts
(
ContactID int Not Null PRIMARY KEY,
FirstName nvarchar(20) NULL,
LastName nvarchar(35) NULL,
Email1 nvarchar (255) NULL
)
GO

--Populate EmailContacts and run a SELECT query.
INSERT INTO EmailContacts
    VALUES(1,’Rick’, ’Dobson’, ’rickd@cabinc.net’)
INSERT INTO EmailContacts
    VALUES(2,’Virginia’, ’Dobson’, ’virginia@cabinc.net’)
SELECT * FROM EmailContacts
GO

A SELECT st at em ent closes t he scr ipt . When t he SELECT st at em ent r uns, Query
Analyzer displays t he r esult set in t he Result s pane, as show n in Figure 2- 1.

   Figu re 2 - 1 . Th e r e su lt se t from t h e script t o cre a t e, popu la t e , a n d list
                          va lu e s for t h e Em ailCon t a ct s t a b le.
Vie w in g M e t a da t a

Met adat a is t he inform at ion about dat a, such as a dat abase ser ver and it s
obj ect s, including dat abases, t ables, and k eys. So far, t his chapt er has review ed
t wo m ain T- SQL sam ples. One of t hese cr eat ed a dat abase— Chapt er02. The ot her
creat ed a t able— Em ailCont act s—wit hin t he dat abase. I n t ur n, t he t able has
several colum ns, and one of t hose colum ns is defined as a prim ary key . I t is oft en
useful t o be able t o generat e report s t hat cont ain inform at ion about t he cont ent s
of a dat abase ser ver and it s obj ect s. For exam ple, t he pr ev ious sam ple show ed
t hat det erm ining w het her a t able alr eady ex ist ed in a dat abase would allow y our
applicat ion t o avoid an er ror— t ry ing t o creat e a new t able w it h t he sam e nam e as
an ex ist ing one. SQL Serv er I NFORMATI ON_SCHEMA v iews can der iv e t his k ind of
inform at ion for your applicat ions. This sect ion exam ines t his capabilit y by
dem onst rat ing it .
The follow ing T- SQL script includes four bat ches of st at em ent s— each t erm inat ed
by t he GO k eyw ord— t hat illust rat e different uses and form at s for der iv ing
m et adat a w it h I NFORMATI ON_SCHEMA v iews. The init ial bat ch dem onst rat es t he
synt ax for r eport ing t he dat abases wit hin a connect ion. I n t his case, t he
connect ion is t he one based on y our login t o Query Analyzer and t he m ast er
dat abase for t he SQL Serv er inst ance. The m ast er dat abase is one of t he syst em
dat abases t hat SQL Ser ver creat es w hen you inst all it . This dat abase is vit al t o
t he proper operat ion of a SQL Serv er inst ance. One funct ion of t his dat abase is t o
t rack inform at ion about all t he dat abases on a SQL Ser ver inst ance. The
SCHEMATA v iew of t he I NFORMATI ON_SCHEMA ret ur ns a high- lev el sum m ary of
t hat inform at ion.
The next bat ch of T- SQL st at em ent s begins by changing t he cont ext for t he
st at em ent s from t he m ast er dat abase t o t he Chapt er02 dat abase. This bat ch
ret ur ns all t he colum ns from t he TABLES v iew of t he I NFORMATI ON_SCHEMA for
which t he t able’s nam e doesn’t begin w it h eit her sys or dt p. While user s can
creat e t ables w it h nam es t hat begin w it h eit her of t hese charact er st rings, SQL
Ser ver uses t ables beginning wit h t hese charact ers t o m anage a dat abase.
Ther efor e, excluding t ables t hat begin wit h t hose charact ers can ret ur n
inform at ion about user - defined t ables. Of course, if y our applicat ion creat es any
t ables beginning w it h t hese prefixes, t hey w on’t appear in t he result set for t he
TABLES v iew.

                                    N ot e
The TABLES v iew for I NFORMATI ON_SCHEMA r et urns
infor m at ion about views as well as t ables. Specify a
TABLE_TYPE colum n value of VI EW in t he WHERE clause for
a SELECT st at em ent t o ret urn only v iews.
Wit h t he COLUMNS v iew of t he I NFORMATI ON_SCHEMA, you can ret urn
inform at ion about colum ns in a dat abase. The t hird bat ch illust rat es t his app-
licat ion. I t also r eveals a new sy nt ax for specify ing t he dat abase ser ving as t he
source for t he v iew. Not ice t hat t he specificat ion of t he v iew nam e has t hr ee
part s. The first of t hese is t he dat abase nam e— Chapt er02. Designat ing a
dat abase nam e as t he first part r em ov es t he need t o designat e a dat abase
cont ext w it h a USE st at em ent . This is because no m at t er w hat dat abase cont ext
t he st at em ent ex ecut es, it always ext ract s infor m at ion fr om t he dat abase— t hat
is, t he first part of t he I NFORMATI ON_SCHEMA view nam e. The second and t hird
part s follow t he conv ent ion for t he pr eceding bat ches except for t he nam e of t he
specific I NFORMATI ON_SCHEMA v iew ( COLUMNS) . The sam ple also includes a
WHERE clause t o reference a part icular t able— in part icular, Em ailCont act s.
Wit hout t he WHERE clause, t he T- SQL st at em ent in t he bat ch will ret ur n
inform at ion for all t he colum ns w it hin t he Chapt er02 dat abase, including t hose
from syst em and user - defined t ables.
The final bat ch shows t he I NFORMATI ON_SCHEMA sy nt ax for r eport ing about t he
keys in a dat abase. These include t he pr im ar y k eys, for eign k eys, and unique
keys. The inform at ion is r eally about t he colum ns on w hich an applicat ion defines
it s keys. As w it h t he pr eceding bat ch, t his sam ple rest r ict s t he r esult only t o keys
for t he Em ailCont act s t able.
--INFORMATION_SCHEMA_Samples
--List databases on current server.
USE master
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
GO

--List user-defined tables in Chapter02 database.
USE Chapter02
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE NOT(SUBSTRING(TABLE_NAME,1,3) = ’sys’
    OR SUBSTRING(TABLE_NAME,1,3) = ’dtp’)
GO

--List all columns in EmailContacts table.
SELECT * FROM Chapter02.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ’EmailContacts’
GO

--List data on columns constrained as keys in
--the EmailContacts table.
SELECT * FROM Chapter02.INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = ’EmailContacts’
GO

Figur e 2- 2 displays an excerpt from t he r esult set for t he preceding script . The
ret ur n for each bat ch begins wit h a new set of colum n headers. The list of
dat abases includes our user - defined dat abase, Chapt er02, along w it h t he t wo SQL
Ser ver sam ple dat abases, pubs and Nort hwind, as well as t he four syst em
dat abases. The second header shows j ust one r ow for t he lone t able in
Chapt er02. The t hird header r ows rev eal t he nam es of t he four colum ns wit hin
t he Em ailCont act s t able. This view pr ov ides m uch addit ional inform at ion about
each colum n, such as it s nullabilit y, dat a t ype, and relat ed set t ings, including it s
precision and scale if appropriat e. The row for t he last set of colum n headers
prov ides inform at ion about t he lone k ey for t he Em ailCont act s t able. This is t he
t able’s pr im ar y k ey . Each k ey has a nam e, w hich appears in t he
CONSTRAI NT_NAME colum n. Because our synt ax for t he creat ion of t he t able
didn’t specify a nam e for t he pr im ar y k ey , t he last row of out put in Figure 2- 2
shows t he syst em - generat ed nam e for t he t able’s pr im ary key in t he
CONSTRAI NT_NAME colum n. A subsequent sam ple in t he “ Scr ipt ing Key s and
I ndexes” sect ion illust rat es t he synt ax for assigning a specific nam e t o a pr im ar y
key .

 Figu r e 2 - 2 . Sa m ple ou t pu t from a se t of fou r T- SQL ba t ch e s illust r a t in g
                  t h e b eh avior of I N FORM ATI ON _ SCH EM A vie w s.




I NFORMATI ON_SCHEMA offers m any m or e v iew s besides t hose illust rat ed in t he
preceding four bat ches. For exam ple, you can gat her inform at ion about check
const raint s for colum n v alues, t able const raint s, st ored pr ocedur es, and user-
defined funct ions. Refer t o t he “I nform at ion Schem a View” t opic in Book s Online
for an overv iew of t he I NFORMATI ON_SCHEMA views along w it h links defining t he
result set for each t ype of view available.

W or k ing w it h Colum n D a t a Type s

The “Cr eat ing a Table” sect ion int r oduced t he CREATE TABLE st at em ent synt ax
and dem onst rat ed how t o declar e t ypical syst em dat a t ypes such as int and
nvarchar. Apply ing t his fram ework w ill enable y ou t o assign t he ot her dat a t ypes
t o colum ns as well. I n spit e of t he sim plicit y of t he ov erall approach, t her e are
special issues for som e dat a t ypes, and one dat a t ype hasn’t been cov ered yet .
This sect ion r ev iews t hese issues.

Com p ar in g t im e st am p an d da t e t im e D at a Typ e s

Those w ho ar e m igrat ing t o SQL Ser ver m ay be confused at first by t he t im e-
st am p dat a t ype and whet her it has anyt hing t o do w it h dat et im e dat a ( it
doesn’t ) . The row version alias for t im est am p act ually sum m ar izes t he purpose of
t he t im est am p dat a t ype m ore precisely. This m ay be one r eason w hy Micr osoft
plans t o use t he r owv er sion nam e m or e prom inent ly in t he fut ur e.
The follow ing scr ipt cont rast s t he t im est am p and dat et im e dat a t ypes. The
cont rast r elies on t wo t ables, t 1 and t 2, each w it h t hr ee colum ns, col1, col2, and
col3. The col1 colum n has an int dat a t ype and offers a value for
program m at ically populat ing r ows in each t able. The col2 and col3 colum ns
populat e aut om at ically . The dat a t ype for col2 is dat et im e, but it has a DEFAULT
const raint t hat assigns t he cur r ent t im e aut om at ically . Users and your
applicat ion’s code can override t his default value. The t im est am p dat a t ype also
aut om at ically populat es col3 in bot h t ables. Howev er , for t his dat a t ype, only SQL
Ser ver updat es t he value. This occurs wit h t he insert ion of a new row or t he
revision of any value in an ex ist ing row .
Aft er creat ing t he t 1 and t 2 t ables, t he scr ipt does a couple of operat ions t o
cont rast t im est am p and dat et im e dat a t ypes. The script insert s a recor d int o each
t able w it h a delay of 1 second bet w een each insert ion. The WAI TFOR DELAY
st at em ent act ually suspends t he operat ion of SQL Ser ver for t he durat ion of it s
argum ent . Ther efore, t he insert ion for t able t 2 can occur m or e t han 1 second
aft er t he insert ion for t able t 1 because SQL Ser ver r equires t im e t o per for m t he
operat ion. Aft er running a SELECT query t o show t he colum n values in t ables t 1
and t 2, t he script next updat es t he value of col1 in t able t 2. Then it reruns t he
SELECT quer y t o dem onst rat e t he im pact of t he operat ion on t he colum n values
in t he sam ple. At t he sam ple’s conclusion, t he script r em ov es t he t 1 and t 2 t ables
from t he Chapt er02 dat abase.
--CompareTimestampToDatetime
--Execute statements after USE from Chapter02 database.
USE Chapter02

--Create two tables named t1 and t2.
CREATE TABLE t1
(
col1 int,
col2 datetime DEFAULT GETDATE(),
col3 timestamp
)
CREATE TABLE t2
(
col1 int,
col2 datetime DEFAULT GETDATE(),
col3 timestamp
)
GO

--Insert a row in tables t1 and t2 with
--a one-second delay between tables.
INSERT INTO t1 (col1) VALUES (1)
WAITFOR DELAY ’00:00:01’
INSERT INTO t2 (col1) VALUES (1)
GO

--Run queries on tables t1 and t2.
SELECT ’t1’ AS ’Table Name’, * FROM t1
SELECT ’t2’ AS ’Table Name’, * FROM t2
GO

--Update column col1 in table t2.
UPDATE t2 SET col1 = col1 + 2
GO

--Re-run queries on tables t1 and t2.
SELECT ’t1’ AS ’Table Name’, * FROM t1
SELECT ’t2’ AS ’Table Name’, * FROM t2
GO

--Drop tables t1 and t2.
DROP TABLE t1
DROP TABLE t2
GO

Figur e 2- 3 shows t he Result s pane fr om Query Analyzer for t he pr eceding script .
The col2 value for t he second row is 1 second plus a SQL Serv er clock t ick ( 3
m illiseconds) behind t he col2 value for t he first r ow. This clock t ick is t he t im e
t hat it t ak es t o com plet e t he r ow insert ion for t able t 2. The col3 values for t he
first and second rows ar e displaced by 1. Because t he insert ion for t able t 2
occurr ed im m ediat ely aft er t he one for t able t 1, t his is appropr iat e. I f ot her
insert ions t ook place bet ween t he init ial insert ion for t able t 1 and t able t 2, t he
difference in t he binary value for col3 w ould be great er . The updat e of col1 for
t able t 2 dem onst rat es t his point .
The second pair of rows in Figur e 2- 3 also displays t he colum n values for t ables
t 1 and t 2 aft er an updat e t o col1 in t able t 2. I n t he case of t able t 1, t he col3
value r em ains unalt er ed. How ev er , t he col3 value for t able t 2 gr ows by 1 fr om it s
init ial value aft er t he insert ion. This incr eased v alue r eflect s t he im pact of t he
updat e t o col1 in t able t 2. While t he second pair of r ows var ies from t he first pair
for col3 in Figure 2- 3, t he col2 values are ident ical bet w een t he first and second
pair of rows. This is because updat ing v alues of ot her colum ns has no im pact on
t he dat et im e values in col2, but updat ing any v alue in a r ow does im pact t he
value of t he t im est am p colum n value in t he row .

                                      N ot e
You can hav e j ust one colum n per t able w it h a t im est am p
dat a t ype.

   Figu r e 2 - 3 . Sa m p le ou t pu t con t r a st in g t h e beh avior of d a t e t im e an d
                                  t im e st a m p d a t a t ype s.




Usin g sql_ va ria n t Da t a Typ e V alu e s

The sql_v ar iant dat a t y pe is t he only dat a t ype t hat let s y ou st or e differ ent dat a
t ypes in t he sam e colum n. This capabilit y is useful for st oring a collect ion of
values in a colum n in w hich y ou don’t k now in advance what t ypes of values you’ll
hav e. This can ar ise in a sit uat ion in which y ou let a user define values on an ad
hoc basis.
Consider a t able t hat st or es m iscellaneous infor m at ion about cont act s. Som et im e
your applicat ion m ay need t o st or e a m oney dat a t ype, anot her t im e a user m ay
want t o specify a dat e, and in y et ot her cases, your applicat ion m ay need t o
designat e a var iable- lengt h charact er value. This kind of scenar io is t ypical of
sit uat ions in w hich y our applicat ion needs t o charact er ize elem ent s but t he
com plet e set of elem ent s and t heir at t r ibut es isn’t known at t he t im e t hat you
dev elop t he applicat ion.
The follow ing scr ipt assigns a set of ext ended propert ies t o a t able of cont act s
ident ified by a Cont act I D colum n. Not ice t hat t he CREATE TABLE st at em ent uses
t hr ee colum ns t o charact er ize t he cont act s. The m ost im port ant colum n is
PropValue, w hich has a sql_var iant dat a t ype. This colum n st ores t he act ual value
t hat charact er izes a cont act . I n som e cases, t he cont act charact er ist ic is a
m onet ary value, in ot her cases it is a dat e, and in st ill ot her cases it is a st ring
value, such as t he nam e of a fav or it e sport or st or e. Pr opI D and PropNam e
describe t he charact erist ic for t he cont act . Pr opNam e m ak es it easy t o follow
what t he Pr opValue colum n values describe w it hout r equir ing anot her t able t o
decode t he PropI D colum n values. A subsequent sam ple w ill ret urn t o t he
Cont act Ext Pr ops t able and link it t o ot her t ables cont aining cont act and propert y
nam es. I n addit ion, t hat sam ple w ill add a pr im ary key t o t he t able. These
refinem ent s ar en’t necessary t o dem onst rat e t he behavior of sql_var iant dat a
t ypes.
The I NSERT I NTO st at em ent s t hat add v alues t o t he Pr opValue colum n use CAST
funct ions t o est ablish sub dat a t ypes w it hin t he sql_var iant colum n. This isn’t
st rict ly necessary, but t he CAST funct ion confir m s t he abilit y of t he sql_var iant
dat a t ype t o accept m ult iple ot her dat a t ypes.
--SQL_variantSample
--Execute statements after USE from Chapter02 database.
USE Chapter02
GO

--Remove prior version of ContactExtProps if it exists.
IF EXISTS
    (
    SELECT *
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = ’ContactExtProps’
    )
DROP TABLE ContactExtProps
GO

--Create ContactExtProps with four columns.
CREATE TABLE ContactExtProps
(
ContactID int NOT NULL,
PropID int NOT NULL,
PropName nvarchar(20),
PropValue sql_variant
)
GO

--Populate ContactExtProps with values.
INSERT INTO ContactExtProps
    VALUES(1, 1,’Birthday’, CAST(‘9/9/1944’ AS datetime))
INSERT INTO ContactExtProps
    VALUES(1, 2, ’Salary’, CAST(50000 AS money))
INSERT INTO ContactExtProps
    VALUES(1, 3, ’Bonus’, CAST(30000 AS money))
INSERT INTO ContactExtProps
     VALUES(1, 4, ’Favorite Sport’, ’Boxing’)
INSERT INTO ContactExtProps
     VALUES(2, 1, ’Birthday’, CAST(‘1/1/1950’ AS datetime))
INSERT INTO ContactExtProps
     VALUES(2, 2, ’Salary’, CAST(60000 AS money))
INSERT INTO ContactExtProps
     VALUES(2, 3, ’Bonus’, CAST(40000 AS money))
INSERT INTO ContactExtProps
     VALUES(2, 5, ’Favorite Store’, CAST(‘Tailspin Toys’ AS nvarchar(2
0)))
GO

--Select all records with a Favorite Store property.
SELECT ContactID, PropName, PropValue
FROM ContactExtProps
WHERE PropName = ’Favorite Store’
GO

--Select Salary and Bonus properties and add one to
--money data type for Salary and Bonus properties.
SELECT ContactID, PropName, Cast(PropValue AS money)+1, PropValue
FROM ContactExtProps
WHERE PropID >=2 and PropID <=3
GO

--This SELECT fails because sql_variant doesn’t implicitly
--convert to other data types (for example, money)
SELECT ContactID, PropName, Cast(PropValue AS money), PropValue+1
FROM ContactExtProps
WHERE PropID >=2 and PropID <=3
GO

Three SELECT quer ies at t he end of t he pr eceding script illust rat e som e of your
opt ions for ext ract ing dat a fr om colum ns declar ed w it h a sql_var iant dat a t ype.
The first SELECT query includes PropValue, t he sql_var iant dat a t ype, in t he
SELECT list for a query , but it uses a colum n defined w it h t he nvarchar dat a t ype
in a WHERE clause. This SELECT query succeeds and ret urns t he nam e of t he
favor it e st or e for any record t hat has t he PropNam e value ’Favor it e St ore’.
The second SELECT query uses PropI D, a colum n w it h an int dat a t ype, in t he
WHERE clause t o ext ract records w it h inform at ion about salary and bonus for
cont act s in t he PropValue colum n. This sam ple t ransform s t he sql_var iant dat a
t ype for PropValue t o a m oney dat a t ype in t he SELECT list . Then it adds 1 t o t he
t ransform ed value. This addit ion operat ion succeeds because it w or ks wit h t he
explicit ly conv ert ed sql_var iant dat a t ype.
The last SELECT query t ries t he sam e addit ion t ask as t he second SELECT query,
but it s SELECT list relies on an im plicit t ransfor m at ion of t he sql_var iant dat a t ype
t o a dat a t ype t hat support s addit ion. Because SQL Server doesn’t support t his
t ransform at ion for a sql_var iant source dat a t y pe, t he last SELECT query fails.
Figur e 2- 4 displays t he out put from t he first t w o successful quer y st at em ent s.

  Figu r e 2 - 4 . N ot ice t h a t t h e Pr opV a lu e colum n , w h ich h as a sql_ var ia n t
    d at a t ype , r et u rn s valu e s w it h diffe r en t da t a t yp e form a t s, su ch a s
                    va ria b le - le n gt h ch a ra ct er st rin g s a nd m one y.
Usin g Com pu t e d Colum n s in Tab le s

A com put ed colum n adds a v irt ual colum n t o a t able based on an expression t hat
draws on one or m or e ot her colum ns w it hin t he t able. You can specify a
com put ed colum n w it h a CREATE TABLE ( or an ALTER TABLE) st at em ent . You can
use a com put ed colum n in a SELECT list , a WHERE clause, or an ORDER BY
clause. I n addit ion, com put ed colum ns can part icipat e in t he definit ion of an index
or prim ar y k ey . You can also use a com put ed colum n in t he definit ion of a
UNI QUE const raint . When y ou’r e using a com put ed colum n t o help define a
prim ary k ey or an index , t he expression m ust be det erm inist ic. I n ot her words,
t he expression m ust generat e t he sam e r esult all t he t im e based on t he sam e
input . An expr ession based on GETDATE isn’t appropriat e for a com put ed colum n
t hat w ill serve as a colum n for an index . This is because t he result w ill change
each t im e y ou open t he t able.
Despit e t he wide range of uses for com put ed colum ns, t her e are sev eral
circum st ances in w hich you cannot use t hem . For exam ple, you cannot specify
nullabilit y for com put ed colum ns. This is because SQL Ser ver aut om at ically
det erm ines w het her a com put ed colum n is null based on it s input and t he
expression for com bining t he com put ed colum ns in quest ion. Ev en non- nullable
input s can generat e null r esult s if an expression generat es an underflow or
ov erflow. I n addit ion, y ou cannot specify input s or m odify t he cont ent s of
colum ns w it h I NSERT I NTO or UPDATE st at em ent s. Yet anot her applicat ion t hat
doesn’t perm it t he use of com put ed colum ns is t hat w hich defines FOREI GN KEY
and DEFAULT const raint s.
The follow ing scr ipt sam ple illust rat es t he sy nt ax for specify ing a com put ed
colum n and shows an exam ple of how t o use it . The CREATE TABLE st at em ent
designat es t hr ee colum ns for t he Proj ect edDeliver yDat es t able. The fir st colum n is
aut oincrem ent ing, w it h default set t ings for t he I DENTI TY colum n pr oper t y. The
second colum n has a dat et im e dat a t ype for accept ing order dat es. The t hird
colum n is a com put ed colum n. The expression for t he colum n uses t he Dat eAdd
funct ion t o com put e a proj ect ed deliv er y dat e based on t he t able’s OrderDat e
colum n.

                                    N ot e
The I DENTI TY pr opert y perm it s y ou t o set t he seed value
and t he st ep value for an aut oincr em ent ing series. I t s default
seed and st ep v alues ar e bot h 1. You can specify alt er nat e
seed and st ep v alues by adding parent heses aft er t he
key word. For ex am ple, use I DENTI TY( 100, 10) t o specify a
series t hat st ar t s at 100 and progresses in st eps of 10.
--ComputedColumnSample
--Execute statements after USE from Chapter02 database.
USE Chapter02
GO

--Remove prior version of ProjectedDeliveryDates if it exists.
IF EXISTS
    (
    SELECT *
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = ’ProjectedDeliveryDates’
    )
DROP TABLE ProjectedDeliveryDates

--Create ProjectedDeliveryDates with three columns.
CREATE TABLE ProjectedDeliveryDates
(
OrderID int IDENTITY Not Null PRIMARY KEY,
OrderDate datetime Not Null,
ProjectedDeliveryDate AS DateAdd(day, 10, OrderDate)
)
GO

--Populate ProjectedDeliveryDates.
INSERT INTO ProjectedDeliveryDates
Values(GetDate())
INSERT INTO ProjectedDeliveryDates
Values(‘9/1/01’)

--Display date and time for projected delivery.
SELECT OrderID, OrderDate, ProjectedDeliveryDate
FROM ProjectedDeliveryDates

--Display just date for projected delivery.
SELECT OrderID, OrderDate,
    LEFT(ProjectedDeliveryDate,12)
    AS ’ProjectedDeliveryDate’
FROM ProjectedDeliveryDates
GO

Aft er insert ing order dat es based on eit her t he GETDATE funct ion or a st ring
represent ing a dat e, t he script queries t he Pr oj ect edDeliv er yDat es t able wit h t wo
separat e SELECT quer ies. The first SELECT query st at em ent dem onst rat es t he
com put ed colum n as part of t he list for t he st at em ent . For t his st at em ent , t he
Proj ect edDeliv eryDat e colum n displays bot h t he dat e and t he t im e. How ev er,
your applicat ion m ay r equir e j ust t he dat e. The second query st at em ent shows
how t o crop t he t im e value out of t he display. Figur e 2- 5 present s t he out put
from bot h SELECT st at em ent s.

Figu r e 2 - 5 . Th is e x am ple sh ow s t h e u se of a com pu t e d colu m n t o disp la y
         a pr oj ect e d d a t e for t h e de live ry of a n or de r in eit h er of t w o
r ep re se n t at ion s—on e t h at in clu de s a t im e a n d an ot h er t h a t sh ow s on ly a
                                               da t e.
Addin g Che ck Con st r a int s

Check const raint s ar e am ong t he m ost sim ple of t he const raint t ypes available t o
dat abase dev elopers and adm inist rat ors. Basically, a check const raint allows you
t o r est r ict t he values ent er ing a colum n— som ewhat in t he way t hat dat a t ype
specificat ions do. ( Users cannot ent er a charact er st ring int o a colum n wit h an int
dat a t ype.) However, check const raint s base t heir r est r ict ion on a Boolean
expression t hat evaluat es t o Tr ue or False. The const raint expr ession can draw on
one or m or e colum n values fr om t he t able t o w hich it applies. A colum n const raint
applies t o an individual colum n, and a t able const raint r efer ences t wo or m or e
colum ns. The value False for t he expression v iolat es t he const raint . SQL Ser ver
rej ect s t he insert ion of a r ecord wit h a value t hat violat es a const raint . You can
use t his behav ior t o m aint ain t he int egr it y of t he colum n values in t he t ables of
your dat abase applicat ions.
The follow ing scr ipt has t hr ee bat ches of st at em ent s. First t he script adds a
colum n check const raint t o t he Em ailCont act s t able init ially generat ed in t he
“Cr eat ing a Table” sect ion. The first bat ch also t est s t he const raint by at t em pt ing
t o insert a r ow w it h a colum n value t hat v iolat es t he const raint . I n t he second
bat ch, t he script shows how t o disable a const raint . This bat ch at t em pt s t o insert
t he sam e record t hat failed in t he first bat ch, but t his t im e t he insert ion succeeds.
The t hird bat ch dr ops t he const raint fr om t he Em ailCont act s t able and delet es t he
record added in t he second bat ch.
You can use t he ALTER TABLE st at em ent t o add a colum n check const raint t o a
t able, such as Em ailCont act s. The ALTER TABLE st at em ent perm it s t he
m odificat ion of a t able aft er it s creat ion. Besides adding check const raint s, you
can add ot her const raint s, such as pr im ary or for eign k eys, and new colum ns. To
add a const raint , use t he ADD k eyw ord follow ed by CONSTRAI NT. You can
opt ionally assign a const raint nam e. Specify ing a const raint nam e is par t icular ly
conv enient if your applicat ion has a need t o disable or rem ov e a const r aint . I f y ou
don’t explicit ly nam e y our const raint s, SQL Ser ver aut om at ically assigns a nam e.
The CHECK k eyword specifies t he t y pe of const raint . Finally , t he expr ession
t railing t he CHECK keyw ord r epr esent s t he condit ion for w hich t he check
const raint t est s. I n t he sam ple scr ipt , t he const raint evaluat es t he Em ail1 value
t o ensure t hat it cont ains t he @ sym bol. E- m ail addresses t hat don’t include t his
sym bol ar e inv alid.
--ColumnCheckConstraintSample
USE Chapter02

--Add CHECK constraint to require at
--least one @ in Email1.
ALTER TABLE EmailContacts
ADD CONSTRAINT ch_EmailContacts_Email1_for@
CHECK (CHARINDEX(‘@’,Email1)<>0)

--Test constraint with an Email1 value
--that contains no @; the INSERT statement fails.
INSERT INTO EmailContacts
    VALUES (3,’Karl’, ’Doe1’, ’Doe1.hlcofvirginia.com’)
GO

--Disable the constraint.
ALTER TABLE EmailContacts
NOCHECK CONSTRAINT ch_EmailContacts_Email1_for@

--Test the disabled constraint with an Email1 value
--that contains no @; the INSERT statement succeeds.
INSERT INTO EmailContacts
    VALUES (3,’Karl’, ’Doe1’, ’Doe1.hlcofvirginia.com’)
GO

--Drop the constraint and delete bad Email1 row.
ALTER TABLE EmailContacts
DROP CONSTRAINT ch_EmailContacts_Email1_for@
DELETE FROM EmailContacts
WHERE LastName = ’Doe1’
GO



Scr ipt ing Ke ys a n d I n de x e s

This sect ion dr ills dow n on t echniques for script ing pr im ary k eys, for eign k eys,
and indexes in y our t ables. Each t opic begins w it h a br ief descr ipt ion of
background issues befor e t he discussion of a sam ple or t w o t hat illust rat e t ypical
uses for t he t opic.

Prim a r y Keys

Prim ar y k eys hav e t w o especially dist inct iv e feat ur es. First , each row m ust hav e a
unique pr im ary k ey value. Second, no pr im ary k ey value can be null— ev en if it is
t he only null record in a t able. I t is com m on, but not m andat or y, t o base pr im ary
keys on a single colum n wit h an I DENTI TY pr opert y set t ing. A pr im ary key can
span m ult iple colum ns.
Each pr im ar y k ey cr eat es an index . An index is a dat abase obj ect t hat support s
fast access t o t he r ows wit hin a t able or v iew. Any one SQL Serv er t able can have
up t o 250 index es, but only one of t hese can be clust er ed. A clust er ed index
physically orders t he records for a t able in st or age according t o t he index values.
Because a clust ered index can speed perform ance so m uch, you should reserv e
t he clust er ed index so t hat it serv es your applicat ion’s m ost heav ily used look up
requir em ent . You can m ake eit her t he index for t he pr im ary key or anot her index
t he clust er ed index for a t able. Wit h a st andard SQL Serv er inst allat ion, a pr im ary
key declarat ion m ak es t he pr im ary key clust er ed by default . How ev er , you can
explicit ly declare a prim ary key as nonclust ered.
As m ent ioned prev iously, t he pr im ar y k ey can hav e it s nam e assigned eit her by
t he syst em or by a user . The follow ing script sam ple r e- creat es t he Em ailCont act s
t able. I f y ou check t he sam ple in t hat sect ion, y ou w ill observ e t hat t he prim ary
key declarat ion doesn’t include a nam e for t he prim ary k ey. The follow ing script
re- creat es t he generat ion of t he Em ailCont act s t able, but t his sam ple does
explicit ly nam e t he pr im ary key. The sam ple also dem onst rat es t he use of t he
sp_pk eys syst em st ored procedure— once befor e dr opping t he first version of t he
Em ailCont act s t able and a second t im e aft er cr eat ing a new v ersion of t he t able
wit h a user- defined nam e for t he prim ar y k ey . The sp_pkeys syst em st or ed
procedur e has a result set w it h a separat e r ow for each colum n in t he prim ary
key . The colum ns of t he r esult set r eport such it em s as t he dat abase nam e, t he
t able nam e, and t he pr im ary k ey nam e.
The prim ary k ey declarat ion in t his sect ion per form s ident ically t o t he one in t he
“Cr eat ing a Table” sect ion ex cept for t he assignm ent of a nam e t o t he prim ary
key . I n t his inst ance, t he sam ple uses t he CONSTRAI NT keyword. This is opt ional
for a prim ary k ey, but it s use can rem ind you t hat t he pr im ary key is a m em ber
of t he fam ily of const raint s, including check const raint s and foreign k ey
const raint s. The nam e for t he pr im ary k ey appears im m ediat ely aft er t he
CONSTRAI NT keyword. The follow ing scr ipt also explicit ly declar es t he prim ary
key as clust er ed. You can replace t he k eyw ord CLUSTERED w it h NONCLUSTERED
t o av oid physically ordering t he records in t he t able according t o Cont act I D
values.
--CreateEmailContactsTableWithPKName
--Execute statements after USE from Chapter02 database.
USE Chapter02
GO

--Print primary key columns and remove prior version
--of EmailContacts, if the table exists.
IF EXISTS
    (
    SELECT *
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = ’EmailContacts’
    )
    BEGIN
        EXEC sp_pkeys ’EmailContacts’
        DROP TABLE EmailContacts
    END

--Create EmailContacts with three columns while
--explicitly assigning a name to the primary key.
CREATE TABLE EmailContacts
(
ContactID int Not Null
    CONSTRAINT pk_EmailContacts_ContactID PRIMARY KEY CLUSTERED,
FirstName nvarchar(20),
LastName nvarchar(35),
Email1 nvarchar (255)
)
GO

--Populate EmailContacts and run a SELECT query
INSERT INTO EmailContacts
    VALUES(1,’Rick’, ’Dobson’, ’rickd@cabinc.net’)
INSERT INTO EmailContacts
    VALUES(2,’Virginia’, ’Dobson’, ’virginia@cabinc.net’)
SELECT * FROM EmailContacts
GO

--List primary key columns in EmailContacts.
EXEC sp_pkeys ’EmailContacts’

Figur e 2- 6 shows t he out put from t he pr eceding script . The result s below t he first
and t hird colum n headers reveal t he out put fr om t he sp_pkeys syst em st ored
procedur e befor e and aft er t he nam ing of t he pr im ary k ey . The first set of colum n
headers shows t he syst em defined nam e for t he pr im ary k ey. The t hird set of
colum n headers shows t he out put from t he sp_keys st or ed pr ocedur e aft er t he
assignm ent of a nam e t o t he pr im ar y k ey . Not ice how t he PK_NAME colum n value
in t he last r ow of Figure 2- 6 m at ches t he nam e assigned t o t he pr im ary key in t he
preceding script .

Figu r e 2 - 6 . Sa m ple ou t pu t de m on st ra t ing pr im a ry k e y n a m e s a ssig n e d by
      t h e syst e m ( t op r ow ) a n d by t h e pr ece d ing scr ip t ( bot t om row ) .




Recall t hat t he “Using sql_var iant Dat a Type Values” sect ion init ially creat ed t he
Cont act Ext Pr ops t able. When it was creat ed in t hat sect ion, t he script didn’t
creat e a pr im ary key for it . I n addit ion, t he Cont act Ext Pr ops t able includes a
colum n, PropI D, designed t o link t o anot her t able t hat defines nam es t o m at ch
t he PropI D values. The next script cr eat es a t able, Ext Props, t hat m at ches t he
PropI D int values w it h nam es in a colum n of var iable- lengt h charact er st rings.
The script t hen pr oceeds t o use t he sp_pk eys syst em st or ed pr ocedur e t o
det erm ine w het her a pr im ary key colum n is already in t he Cont act Ext Pr ops t able.
A value of 0 for @@ROWCOUNT specifies no pr im ary k ey . I f t he value is great er
t han 0, t he pr ocedur e drops t he ex ist ing pr im ar y k ey. Next t he pr ocedure uses an
ALTER TABLE st at em ent t o creat e a new pr im ary k ey based on t wo colum ns—
Cont act I D and PropI D. This prim ary key desi- gnat ion perm it s each cont act t o
hav e m ult iple propert ies but no m or e t han one set t ing for any one pr opert y. The
for eign k ey sam ple in t he next sect ion w ill dem onst rat e how t o link t he
Cont act Ext Pr ops t able t o t he Em ailCont act s and Ext Pr ops t ables.
--CreateExtProps
--Execute statements after USE from Chapter02 database.
USE Chapter02
GO

--Remove prior version of ExtProps, if it exists.
IF EXISTS
    (
    SELECT *
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = ’ExtProps’
    )
DROP TABLE ExtProps
GO

--Create ExtProps.
CREATE TABLE ExtProps
(
PropID int,
PropName nvarchar(20),
)

--Populate ExtProps with values.
INSERT INTO ExtProps
    VALUES(1, ’Birthday’)
INSERT INTO ExtProps
    VALUES(2, ’Salary’)
INSERT INTO ExtProps
    VALUES(3, ’Bonus’)
INSERT INTO ExtProps
    VALUES(4, ’Favorite Sport’)
INSERT INTO ExtProps
    VALUES(5, ’Favorite Store’)
GO

--Drop primary key for ContactExtProps.
EXEC sp_pkeys ContactExtProps, dbo, Chapter02
IF @@ROWCOUNT > 0
ALTER TABLE ContactExtProps
DROP CONSTRAINT pk_ContactExtProps_ContactID_PropID
GO

--Add Primary Key based on ContactID and PropID.
ALTER TABLE ContactExtProps
ADD CONSTRAINT pk_ContactExtProps_ContactID_PropID
    PRIMARY KEY NONCLUSTERED
    (
    ContactID,
    PropID
    )

--List primary key columns in ContactExtProps.
EXEC sp_pkeys ’ContactExtProps’

The preceding script closes by inv ok ing t he sp_pkeys syst em st ored pr ocedur e.
The out put from t he procedur e appears in Figur e 2- 7. Not ice t hat it cont ains t wo
rows— one for each colum n t hat cont r ibut es t o t he pr im ary key for t he
Cont act Ext Pr ops t able.

   Figu r e 2 - 7 . Ou t p ut fr om t h e sp_ pk eys syst e m st or ed pr oced u r e t h a t
                   sh ow s a pr im ar y k ey d efin ed on t w o colu m n s.




Fore ig n Keys

Foreign keys ar e colum n values in one t able t hat point t o t he pr im ary k ey or
unique k ey in anot her t able. Specifying a for eign k ey enforces refer ent ial int egr it y
bet ween t he t wo t ables. Refer ent ial int egr it y r equir es all new r ecords added t o
t he t able wit h t he for eign k ey t o m at ch eit her a prim ary or a unique key value in
t he ot her t able if it isn’t null. You can opt ionally specify act ions t o occur when y ou
updat e or rem ov e a pr im ary or unique k ey in t he t able on t he ot her end of t he
for eign k ey relat ionship. Specifically, you can cascade t he change fr om t he t able
wit h t he pr im ary or unique k ey t o t he one w it h t he for eign k ey. Alt er nat ively, y ou
can choose no act ion t o occur in t he t able wit h t he foreign k ey as a consequence
of updat es t o t he t able wit h t he pr im ary or unique k ey.
The follow ing scr ipt adds a couple of for eign k eys t o t he Cont act Ext Props t able.
The first foreign key uses t he Cont act I D in t he Cont act Ext Props t able t o refer t o
t he prim ary key for t he Em ailCont act s t able. The second for eign k ey uses t he
Cont act Ext Pr ops t able v ia it s PropI D colum n values t o r efer t o t he Ex t Pr ops t able.
Because t he Ext Props t able doesn’t init ially hav e a pr im ary or a unique k ey, t he
t able cannot part icipat e in a foreign key r elat ionship. Ther efor e, t he script first
adds const raint s t o t he PropI D colum n in Ext Props so t hat it serv es as t he t able’s
prim ary k ey. Then it declar es t he for eign k ey r elat ionship bet w een t he
Cont act Ext Pr ops t able and t he Ext Pr ops t able. Alt hough t he first for eign key
doesn’t declare any cascading act ion, t he declarat ion for t he second foreign key
specifies cascading updat es. The script sam ple illust rat es t he sy nt ax for
designat ing cascading updat es in it s declarat ion. Aft er t he second foreign k ey
declarat ion, t he script t est s t he cascading updat e behav ior by m ak ing a change t o
a Pr opI D value in t he Ex t Props t able and t hen v er ify ing t hat t he updat e cascades
t o t he corr esponding PropI D value in t he Cont act Ext Pr ops t able. The script
sam ple concludes by rest oring t he values and t he dat abase design t o t heir form er
st at e befor e t he addit ion of eit her for eign k ey. This m ak es it possible t o r erun t he
script wit hout any m anual set up act ivit y bet ween runs.
You add a for eign k ey t o a t able as a const raint . The synt ax for perfor m ing t his
t ask has at least t hr ee st eps, and it can hav e m or e if you specify a cascading
act ion. Begin t he foreign k ey declarat ion inside an ALTER TABLE st at em ent . Aft er
you open t he ALTER TABLE st at em ent , t he first st ep is t o indicat e t hat you want
t o add a const raint w it h t he ADD and CONSTRAI NT k ey words. You can,
opt ionally, assign a nam e t o t he foreign k ey const raint . Next add t he FOREI GN
KEY k ey word and follow it wit h parent heses cont aining t he nam es of t he colum ns
from t he cur rent t able part icipat ing in t he r elat ionship. Third add REFERENCES as
a keyword. Follow t his k eyw ord w it h t he nam e of t he t able t o which t he
relat ionship refers. Then, in parent heses aft er t he t able nam e, add t he colum n
nam es fr om t hat t able t hat part icipat e in t he r elat ionship. By default , updat e and
delet e act ions don’t cascade fr om t he t able wit h t he unique key or prim ary key t o
t he t able wit h t he for eign k ey . How ev er, y ou can opt ionally add an ON UPDATE or
ON DELETE clause t o t he for eign k ey declarat ion. I nclude in eit her clause
CASCADE t o t ransfer t he act ion from t he t able wit h t he prim ary or unique k ey t o
t he one w it h t he foreign key.
--ForeignKeysSamples
--Beginning of first FOREIGN KEY sample.
USE Chapter02

--Remove FOREIGN KEY constraint if it exists already.
EXEC sp_fkeys @fktable_name = N’ContactExtProps’
IF @@ROWCOUNT > 0
BEGIN
    ALTER TABLE ContactExtProps
    DROP CONSTRAINT ContactExtProps_fkey_ContactID
END

--Then, add a new FOREIGN KEY constraint.
ALTER TABLE ContactExtProps
ADD CONSTRAINT ContactExtProps_fkey_ContactID
FOREIGN KEY (ContactID)
REFERENCES EmailContacts(ContactID)

--Verify addition of new constraint.
EXEC sp_fkeys @fktable_name = N’ContactExtProps’
--End of first FOREIGN KEY sample


--Beginning of second FOREIGN KEY sample.
--Convert PropID in ExtProps to NOT NULL.
ALTER TABLE ExtProps
ALTER COLUMN PropID int NOT NULL
GO

--Then, define a primary key on PropID.
ALTER TABLE ExtProps
ADD CONSTRAINT pk_PropID PRIMARY KEY CLUSTERED (PropID)
GO
ALTER TABLE ContactExtProps
ADD CONSTRAINT ContactExtProps_fkey_PropID
FOREIGN KEY (PropID)
REFERENCES ExtProps(PropID)
ON UPDATE CASCADE

--Verify addition of new constraint.
EXEC sp_fkeys @fktable_name = N’ContactExtProps’
GO

--List ExtProps and ContactExtProps rows before
--update to ExtProps.
SELECT * FROM ExtProps
SELECT * FROM ContactExtProps

--Then, make a change in ExtProps that
--cascades to ContactExtProps.
UPDATE ExtProps
SET PropID = 50 WHERE PropID = 5

--List ExtProps and ContactExtProps rows after
--update to ExtProps.
SELECT * FROM ExtProps
SELECT * FROM ContactExtProps
GO
--End of second FOREIGN KEY sample.

--Do cleanup chores.
--Start to restore by resetting PropID values.
UPDATE ExtProps
SET PropID = 5 WHERE PropID = 50

--Next, drop FOREIGN KEY constraints.
ALTER TABLE ContactExtProps
DROP CONSTRAINT ContactExtProps_fkey_ContactID

ALTER TABLE ContactExtProps
DROP CONSTRAINT ContactExtProps_fkey_PropID

--Then, drop PRIMARY KEY constraint first .
ALTER TABLE ExtProps
DROP CONSTRAINT pk_PropID

--Finally, restore NULL setting for column.
ALTER TABLE ExtProps
ALTER COLUMN PropID int NULL
GO
--End of restore from second FOREIGN KEY sample.

Figur e 2- 8 shows t wo excerpt s fr om t he pr eceding script ’s out put . The t op panel
shows t he Ext Props t able rows ov er t he Cont act Ext Props t able r ows. This is
befor e an updat e of t he PropI D value 5 t o a new value of 50 in t he Ex t Pr ops
t able. The bot t om panel shows t he sam e t w o t ables aft er t he updat e of t he value
in t he Ext Pr ops t able. Not ice t hat t he change t o t he Ext Props t able cascades t o
t he Cont act Ext Props t able.

Figu r e 2 - 8 . Th e t op an d bot t om pa n e ls sh ow t h e Ext Pr ops t a ble ove r t h e
 Con t a ct Ext Pr op s t a ble b efore a n d a ft er a ch a n ge t o t h e Ex t Pr op s t ab le .
I n de x e s

Many dat abases can achieve perform ance gains t hrough t he addit ion of an index .
I ndexes are gr eat at speeding look ups and sort s. On t he ot her hand, t her e are
t im es w hen t he ov er head associat ed w it h m aint aining an index can slow an
applicat ion. This is part icular ly t rue w hen one or m or e indexes over lap wit h a
clust er ed pr im ar y k ey . Oft en dev elopers and adm inist rat ors hav e t o r esort t o
t im ing r uns for t y pical t asks t o det erm ine t he best configurat ion of indexes for a
dat abase applicat ion. Wit h t his in m ind, t he value of being able t o add and drop
index es program m at ically is considerable as y ou perform y our t im ing r uns t o
discer n t he opt im al index configurat ion.
The last script in t his chapt er illust rat es sev eral t echniques for w ork ing wit h
index es t hat y ou ar e lik ely t o find useful. The script begins by creat ing a user -
defined st ored procedure, List UserDefinedI ndex es, t hat list s t he index es for user -
defined t ables in a dat abase. ( You’ll r ead m uch m or e about st or ed procedures in
Chapt er 4.) See Figur e 2- 9 for sam ple out put . This procedure draws on bot h t he
sysobj ect s and sysindex es t ables— t wo syst em cat alog t ables. While y ou should
generally av oid m anipulat ing syst em t ables, som e advanced dev eloper s find it
useful t o do so. The Nam e colum n from t he sysobj ect s t able ( sysobj ect s.nam e)
ret ur ns t he t able for an index , and t he Nam e colum n from t he sysindex es t able
( sysindex es.nam e) is t he nam e for a specific index in a t able ( if t her e is one) . The
indid colum n present s t he index ident ifier colum n values. An indid value of 1
indicat es a clust er ed index, such as one cr eat ed wit h t he CREATE I NDEX
st at em ent or one associat ed w it h a prim ary k ey . Values of indid bet ween 2 and
250 ar e for nonclust ered indexes. An indid value of 0 indicat es t her e is no
clust er ed index for a t able. The indid colum n v alue also conv eys infor m at ion
about t ables cont aining large dat a t ypes, such as t ext , nt ext , and im age. See t he
“Table and I ndex Archit ect ur e” t opic in Books Online for addit ional det ail.

                                    N ot e
I nst ead of using t he List User DefinedI ndexes st or ed
procedure in t he scr ipt below, y ou can use t he syst em st or ed
procedure sp_helpindex t o collect infor m at ion about indexes.
This syst em st or ed procedure works sim ilarly t o sp_pkeys
and sp_fkey s, but it pr ov ides infor m at ion for indexes.
However, List User DefinedI ndexes gives you ex posur e t o
t echniques for w ork ing w it h syst em cat alog t ables, which ar e
a rich source of cont ent about a dat abase’s design.
You can add an index t o a t able w it h t he CREATE I NDEX st at em ent . The list ing
below init ially dem onst r at es t he synt ax for creat ing an index based on one
colum n. Follow CREATE I NDEX wit h t he nam e of your index . Then follow t he
index nam e w it h an ON clause. I n t he ON clause, include t he t able nam e wit h t he
colum n or colum ns for t he index. Place t he colum n nam e in par ent heses aft er t he
t able’s nam e.
The sam ple illust rat es t he applicat ion of t he CREATE I NDEX sy nt ax t w ice. The first
use of t he st at em ent is for adding an index based on t he Last Nam e colum n in t he
Em ailCont act s t able. This exam ple dem onst rat es how t o use t he CREATE I NDEX
st at em ent as described in t he pr eceding paragr aph. A second applicat ion of t he
st at em ent shows how t o creat e a unique index based on t w o colum ns from t he
Cont act Ext Pr ops t able— nam ely, Cont act I D and PropI D. The synt ax for t his
exam ple uses t he UNI QUE k eyw ord. This k eyw ord is appr opriat e for a t able wit h a
candidat e k ey because it specifies a second index t hat is unique for each record
besides t he pr im ary key . I n ot her words, t he colum n( s) cont r ibut ing t o a unique
index ar e candidat es for t he pr im ary key. By default , t he CREATE I NDEX
st at em ent generat es nonclust ered indexes. Howev er , y ou can insert CLUSTERED
aft er eit her CREATE or UNI QUE ( if it is pr esent ) t o m ak e a clust er ed index.
Use t he DROP I NDEX st at em ent t o rem ov e a user - defined index ( for ex am ple,
one you cr eat e w it h t he CREATE I NDEX st at em ent ) . The sy nt ax for t he DROP
I NDEX st at em ent uses a t wo- part nam e t o designat e t he index t o dr op. The first
part is t he t able nam e, and t he second part is t he index nam e. A per iod delim it s
t he t wo part s. Our st or ed procedure list s t he index es for prim ary k eys and
syst em - defined index es. You can delet e t he index for a pr im ar y k ey by dropping
t he key. I f t he SQL Serv er set t ings for a ser ver perm it it , you can rem ove t he
index for a for eign k ey dir ect ly from t he sysindex es t able. See t he “How t o set
t he allow updat es opt ion ( Ent erpr ise Manager ) ” and “Err or 259” t opics in Books
Online for m ore det ail on dir ect ly m anipulat ing syst em cat alog t ables, such as
sysindexes.
--IndexSamples
USE Chapter02
--Create a stored procedure to list for user-defined
--tables object name from sysobjects, and name and
--indid from sysindexes.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
       WHERE ROUTINE_NAME = ’ListUserDefinedIndexes’)
DROP PROCEDURE ListUserDefinedIndexes
GO
CREATE PROCEDURE ListUserDefinedIndexes
AS
SELECT sysobjects.id AS [sysobjects.id],
    sysindexes.id AS [sysindexes.id],
    sysobjects.name AS [sysobjects.name],
    sysindexes.name AS [sysindexes.name], sysindexes.indid
FROM sysobjects INNER JOIN sysindexes
ON sysobjects.id = dbo.sysindexes.id
WHERE (LEFT(sysobjects.name, 3) <> ’sys’)
    AND (sysobjects.name <> N’dtproperties’)
GO

--List indexes data.
EXEC ListUserDefinedIndexes

--Create an Index for LastName in EmailContacts.
CREATE INDEX ind_EmailContacts_LastName
ON EmailContacts(LastName)

--List indexes data.
EXEC ListUserDefinedIndexes

--Remove previously created index.
DROP INDEX EmailContacts.ind_EmailContacts_LastName

--Remove primary key for ContactExtProps based
--on ContactID and PropID.
EXEC sp_pkeys ContactExtProps, dbo, Chapter02
IF @@ROWCOUNT > 0
ALTER TABLE ContactExtProps
DROP CONSTRAINT pk_ContactExtProps_ContactID_PropID
GO

--List indexes data.
EXEC ListUserDefinedIndexes
GO

--Create an Index for LastName in EmailContacts.
CREATE UNIQUE INDEX ind_ContactExtProps_ContactID_PropID
ON ContactExtProps(ContactID, PropID)

--List indexes data.
EXEC ListUserDefinedIndexes
GO

--Attempt to enter a record with duplicate key values for
--ContactID and PropID.
INSERT INTO ContactExtProps Values (1, 1, ’Birthday’, ’9/9/1964’)
GO

--Remove previously created index.
DROP INDEX ContactExtProps.ind_ContactExtProps_ContactID_PropID

--List indexes data.
EXEC ListUserDefinedIndexes
GO

--Insert and then delete record with duplicate values for
--ContactID and PropID columns.
INSERT INTO ContactExtProps Values (1, 1, ’Birthday’, ’9/9/1964’)
DELETE FROM ContactExtProps WHERE PropValue = ’9/9/1964’
GO

Besides synt ax issues, t he pr eceding sam ple script illust rat es design issues for
wor k ing w it h index es, such as t est ing t he behavior of a unique index. To isolat e
t he effect of t he index, t he script drops a prim ar y k ey t hat requir es uniqueness on
t he sam e t wo colum ns as t he ind_Cont act Ext Props_Cont act I D_PropI D index. The
t est for t he validit y of t his unique index is an at t em pt t o ent er a record wit h a
duplicat e k ey v alue. Aft er failing, t he script dr ops t he unique index and confirm s
t hat y ou can add t he record if t he unique index isn’t present ; t he script closes by
rem ov ing t he t est r ecor d.
Figur e 2- 9 shows an ex cerpt from t he beginning of t he script w it h t he out put from
t he first t wo uses of t he List UserDefinedI ndex es st ored pr ocedur e. The m ain point
t o t ak e away from t he out put is t hat t he first list ing of index es doesn’t include a
reference t o ind_Em ailCont act s_Last Nam e, but t he second one does. I n bet w een
t he t wo r uns of t he List UserDefinedI ndex es st ored pr ocedure, t he script inv ok es
t he CREATE I NDEX st at em ent t o gener at e t he index . The t w o result set s also
show t he index es for clust ered and nonclust ered prim ar y k eys. For ex am ple,
pk_Em ailCont act s_Cont act I D is a clust er ed pr im ary key; not ice t hat it s indid
value is 1. The index for t he nonclust er ed pr im ary key ,
pk_Cont act Ext Pr ops_Cont act I D_PropI D, has an indid value of 2. Finally, t he
_WA_Sys_PropI D_77BFCB91 index is for a foreign k ey fr om a preceding sam ple.
SQL Ser ver didn’t rem ove t he index when t he script dr opped t he key.

     Figu re 2 - 9 . Th e se t w o re su lt set s iden t ify t h e a ddit ion of a n inde x,
ind _ Em a ilCon t act s_ Last N am e , t o t h e Em a ilCon t act s t a ble . By con t ra st in g
  t h e fir st w it h t h e se con d list in g, you can se e t h e e ffe ct of t h e CREATE
               I N DEX st a t em e n t for ind _ Em a ilCon t act s_ La st N am e .
Cha pt e r 3 . Pr ogr a m m ing D a t a Acce ss
w it h T- SQL
This chapt er present s T- SQL program m ing t echniques for dat a access. You can
use t hese t echniques in m any env ironm ent s— in Query Analyzer , encapsulat ed
wit hin v iews, in st or ed procedur es and user - defined funct ions— and in Visual Basic
.NET. When y ou finish wor k ing t hrough t his chapt er, y ou should possess a
foundat ion for ext ract ing precisely t he dat a y ou need fr om a SQL Serv er dat abase
for any applicat ion.
The obj ect iv e of t his chapt er is t o dem y st ify T- SQL dat a access t echniques so t hat
you can creat e T- SQL SELECT st at em ent s as easily as you used t o w rit e DAO and
ADO dat a access code. Alt hough t he chapt er assum es you’r e wor k ing in Query
Analyzer, t he t echniques y ou lear n w ill apply equally w hen y ou use T- SQL
st at em ent s in Visual Basic .NET.
The chapt er begins by int r oducing t he SELECT st at em ent and describing how t o
filt er colum ns and rows from a row source, such as a t able. Next t he chapt er
focuses on t echniques for aggr egat ing dat a acr oss a whole r ow source as well as
specific groups w it hin t he row source. The chapt er explor es part icular t echniques
for m oney and dat et im e var iables, and t he dat et im e t opic gains a sect ion of it s
own. The concluding sect ion exam ines ways of com bining r ow sources wit h j oins
and subquer ies. I f you hav e had difficult y underst anding j oins befor e, spend
som e t im e w it h t he script sam ples in t he chapt er and t he accom panying
com m ent ary t o build y our grasp of t his im port ant capabilit y.

                                     N ot e
By t he t erm r ow source, I refer t o a collect ion of rows from a
dat abase. Alt hough t his can be a t able, it can also be a view
based on one or m or e t ables. I n addit ion, a row sour ce can
be t he r esult set gener at ed by a st ored pr ocedure or a t able-
valued user- defined funct ion.
The T- SQL sam ples for t his chapt er ar e available in an .sql file on t he com panion
disk . You can use t he script s as st art ing point s for your own cust om
ext rapolat ions of t he t echniques. You can r un all t he sam ples fr om Query
Analyzer if y ou have t he Nort hwind and pubs dat abases inst alled on a SQL Ser ver
inst ance t o w hich y ou can connect .




I n t r odu ct ion t o D a t a Acce ss w it h T- SQL
Creat ing efficient , speedy, and flex ible dat a access solut ions for SQL Ser ver dat a
will inev it ably involve pr ogram m ing T- SQL. I n part icular, you w ill r equir e a firm
foundat ion in t he design of SELECT st at em ent s. This sect ion int roduces t he
SELECT st at em ent by review ing it s archit ect ur e. You’ll find code sam ples
designed t o illust rat e t he basic operat ion of t he st at em ent ’s m ain elem ent s,
including t he SELECT list as well as t he FROM and WHERE clauses, and you’ll be
int r oduced t o t he t opic of calculat ed colum ns.

Ov e r vie w of t h e SELECT St a t e m e n t
Learning t he synt ax and clauses for t he SELECT st at em ent is t he surest way t o
guarant ee your pr oduct ivit y w it h SQL Serv er. As m ent ioned in t he int roduct ion t o
t his chapt er , y ou can use t he SELECT st at em ent in SQL bat ches for Query
Analyzer, v iews, st or ed procedur es, and user - defined funct ions. I t is com m on t o
use t he SELECT st at em ent for dat a access wit h SQL Serv er.
A SELECT st at em ent can generat e a set of v alues. SQL Serv er lit erat ur e calls t he
values r et urned by a SELECT st at em ent it s r esult set . A t ypical SELECT st at em ent
can r et ur n a scalar value, a single colum n of values, or a t w o- dim - ensional ar ray
of values. I n norm al dat a access scenarios, t he t wo- d- im ensional array of values
will be t he m ost com m on design for a result set .
At a m inim um , a SELECT st at em ent includes a SELECT list and a FROM clause.
The list designat es t he colum ns t hat populat e a result set . You can use t he ent r ies
in t he SELECT list t o filt er colum ns and calculat e new colum ns based on t he r ow
source for t he SELECT st at em ent . The FROM clause designat es t he r ow source for
a SELECT st at em ent . The row source for a t ypical SELECT st at em ent can be a
t able, a view, a user - defined funct ion, or ev en a subquer y. This subquer y is
sim ply anot her SELECT st at em ent . At a m inim um , a SELECT st at em ent used for
dat a access m ust include a list and a FROM clause argum ent . The FROM clause
m ust appear aft er t he SELECT list . As w it h ot her SELECT clauses, y ou separat e
t he FROM clause from t he SELECT list by a space or a carr iage r et ur n.
You won’t always want t o see all t he dat a from t he source specified in t he FROM
clause. The SELECT list enables you t o specify a subset of t he row source’s
colum ns t hat should be included in t he r esult set . Sim ilar ly, t he WHERE clause
enables you t o designat e a subset of t he rows. The WHERE clause supplies t he
crit er ia used t o filt er rows in t he argum ent for a FROM clause. The WHERE clause
is opt ional. I f you don’t use a WHERE clause, t he SELECT st at em ent includes all
t he r ows designat ed by t he FROM clause in it s r esult set . When y ou do use a
WHERE clause, be sur e t o r efer ence colum ns in t he FROM clause argum ent . A
general way of denot ing t he synt ax for a basic SELECT st at em ent is:
SELECT
select_list

FROM
row_source

WHERE
criteria_expressions



Or de r in g D a t a in t h e Re su lt Se t

The rows in a r elat ional dat a source don’t have any special order . How ever, y ou’ll
oft en want t he result set fr om a SELECT st at em ent t o be arranged a cer t ain
way— for exam ple, in alphabet ical or num er ic order based on one or m or e
colum ns. You can achieve t his w it h t he ORDER BY clause. The colum ns you
designat e t o use for t he ordering can or iginat e wit h t he r ow source in t he FROM
clause, or t hey can be calculat ed colum ns. You can designat e ascending ( ASC) or
descending ( DESC) sort orders for any colum n in an ORDER BY clause. Ascending
order is t he default . That m eans y ou hav e t o specify an order only when y ou
requir e a descending or der. The ORDER BY clause should always com e aft er all
ot her SELECT st at em ent clauses except for t he COMPUTE and COMPUTE BY
clauses ( w hich I ’ll describe short ly ) .

Grou ping D a t a in t h e Re su lt Se t
Just as you’ll probably want t o ar range dat a in a r esult set in a cert ain way, you’ll
oft en want t o group dat a t o m ake it m ore useful. Wit h t he GROUP BY clause, you
can gr oup set s of rows in a result set . This clause is especially useful w hen you
want t o apply an aggregat e funct ion t o one or m or e colum ns in a r ow source.
Aggr egat e funct ions ar e useful for dev eloping sum m ary st at ist ics, such as t he
count , sum , or average of colum n v alues by gr oup. The result set s generat ed wit h
t he GROUP BY clause support business decision m aking. For exam ple, y ou can
use t he clause t o develop t ot al sales by region of t he count ry or by pr oduct
cat egory .
The GROUP BY clause w orks hand- in- hand w it h t he HAVI NG clause. The HAVI NG
clause enables y ou t o filt er groups in t he sam e way t hat t he WHERE clause
perm it s y ou t o filt er r ows. The GROUP BY and HAVI NG clauses belong aft er t he
FROM and WHERE clauses in a SELECT st at em ent . Just as wit h t he WHERE
clause, t he HAVI NG clause is opt ional. I f y ou do include it , posit ion it aft er t he
GROUP BY clause. ( Lat er in t he chapt er , I prov ide a sam ple script t hat uses
HAVI NG.)

Gen er at in g Su m m a ry V a lu es w it h COM PUTE an d COM PUTE BY

I n addit ion t o m ak ing a result set m ore useful by order ing and gr ouping, y ou’ll
som et im es find t hat a sum m ar y of t he dat a is j ust as im port ant as t he dat a it self.
That ’s w hen y ou m ight decide t o use t he COMPUTE and COMPUTE BY clauses t o
generat e not only det ail ( t he rows in t he result set ) but also sum m ary values
( aggr egat e t ot als and subt ot als) .
You’ll recall t hat t he GROUP BY clause r et urns a single result set . I n cont rast ,
COMPUTE and COMPUTE BY generat e m ult iple result set s. Wit h t he COMPUTE BY
clause, a SELECT st at em ent pr epar es a separat e r esult set for t he r ow s in each
group and anot her collect ion of r esult set s w it h t he sum m ary st at ist ics for each
group. The COMPUTE BY clause designat es aggregat e funct ions, colum ns for t heir
applicat ion, and gr ouping colum ns all in one clause.
The COMPUTE clause can generat e t w o r esult set s— one cont aining all t he r ows in
t he r ow source for a SELECT st at em ent and a second r esult set w it h sum m ary
st at ist ics for t he full set of rows. The COMPUTE clause cr eat es grand t ot al
st at ist ics, but t he COMPUTE BY clause creat es subt ot al st at ist ics for each group.

                                      N ot e
The COMPUTE BY and COMPUTE clauses cont rast wit h ot her
t echniques for prepar ing t ot als and subt ot als, such as t he
ROLLUP and CUBE operat ors. For m ore det ail on t hese
operat or s, see t he Books Online t opics “Sum m arizing Dat a
Using ROLLUP” and “Sum m ar izing Dat a Using CUBE.”
You can use t he GROUP BY and COMPUTE BY clauses in t he sam e SELECT
st at em ent . When y ou use t he t w o clauses t oget her, t he COMPUTE BY sum m ar y
st at ist ics apply t o t he gr oups of rows specified in t he GROUP BY clause. Apply ing
t he COMPUTE BY clause wit hout t he GROUP BY clause perm it s t he COMPUTE BY
clause t o generat e r esult s for indiv idual r ows designat ed by t he FROM clause.
Whenev er y ou designat e eit her t he COMPUTE BY or COMPUTE clause, it should
always appear as t he last clause in t he SELECT st at em ent . When you use bot h,
t he COMPUTE clause belongs aft er t he COMPUTE BY clause.
I prov ide m ore det ail on ordering, gr ouping, and aggregat ing result set s lat er in
t his chapt er .

Spe cifyin g Colu m n s a n d Row s
You use t he SELECT st at em ent t o r et ur n a r esult set or set s fr om a r ow source.
Howev er, you w on’t alw ays want t o ret ur n all colum ns and r ows in t he row
source. SELECT offers y ou various ways of filt er ing out w hat you don’t want .

Ret u r n ing All Colu m n s

The m ost elem ent ar y SELECT st at em ent is t hat which designat es t he r et ur n of all
colum ns fr om each row wit hin a r ow source. Ther e are t wo differ ent ways t o do
t his. The m ost fam iliar uses an ast er isk ( * ) t o denot e all t he colum ns in a r ow
source. For exam ple, if you want ed t o creat e a result set w it h all t he colum n
values for each row in t he Cust om ers t able, you could use t he follow ing code:
--SelectAllColumns
--Select all columns from all rows.
USE Northwind
SELECT *
FROM Customers

Not ice t hat t he USE key word specifies t he Nort hwind dat abase as t he dat abase
cont ext for t he st at em ent . Unless you ex plicit ly designat e ot herw ise, y our SELECT
st at em ent will apply t o t he curr ent dat abase. Subsequent sam ples w ill illust rat e
how t o ov erride t his default select ion.

                                     N ot e
The USE keyword is an inst ruct ion t o Query Analy zer. This
key word is not a part of T- SQL. You set t he dat abase cont ext
differ ent ly for ot her SQL Ser ver client s.
Ther e is anot her, less com m on, appr oach t o ret ur ning all colum ns t hat achiev es
t he sam e result as using an ast er isk: you can separat ely denot e each colum n
nam e in t he Cust om ers t able. The follow ing code shows t he first couple of colum n
nam es, an ellipsis, and t he last nam e from t he Cust om ers t able in t he Nort hw ind
dat abase. ( Not e t hat SQL Serv er synt ax doesn’t allow an ellipsis; it ’s used her e
wit h a few colum n nam es t o represent t he full list of Cust om ers colum ns.)
USE Northwind
SELECT CustomerID, CompanyName, ..., Fax
FROM Customers

The t wo different approaches w ill generat e equivalent r esult s for t he st andard
Cust om ers t able in t he Nort hwind sam ple dat abase. How ev er , in som e
circum st ances t hey can ret urn divergent result set s. I f y ou add a new colum n t o
t he Cust om ers t able, t he init ial sam ple w ill r et urn t he new colum n along wit h t he
old. On t he ot her hand, t he second sam ple t hat list s t he indiv idual colum ns w ill
om it t he new colum n because it s nam e isn’t in t he SELECT list . So w hich
approach is best ? The answer depends on y our needs. I n general, evaluat e v er y
carefully w het her y ou need all t he colum ns from a r ow source. You can speed an
applicat ion’s perform ance by choosing j ust t he colum ns t hat an applicat ion t ruly
requir es.

Ret u r n ing a Su bse t of Colu m n s

You can filt er out unwant ed colum ns in m any different ways. The following
sam ple ret urns values for all r ows in t he Cust om ers t able, but only fr om t he
Count ry, Cit y, and Com panyNam e colum ns. Because t here ar e 91 cust om ers in
t he Nort hw ind dat abase, t his r esult set has t hr ee colum ns and 91 r ows— one for
each row in t he t able.
--SelectSomeColumns
--Select some columns from all rows.
SELECT Country, City, CompanyName
FROM Customers

You m ay have not iced t hat unlik e t he pr ev ious code sam ple, t his one doesn’t
include a specific reference t o t he Nort hwind dat abase. That ’s because Query
Analyzer w ill cont inue t o use Nort hw ind unt il y ou specify a different dat abase wit h
a new USE st at em ent . All t he r em aining sam ples in t his chapt er assum e t hat t he
dat abase is Nort hw ind.

                                    N ot e
The elem ent s in a SELECT list and t he argum ent in a FROM
clause are ex am ples of ident ifiers for dat abase obj ect s. SQL
Server has precise rules for nam ing obj ect s and using obj ect
nam es as well as a r ich collect ion of Book s Online t opics for
describing t hem . For ex am ple, see t he t opic “Using
I dent ifiers” for a delineat ion of t he four rules for regular
ident ifier s. When dealing w it h obj ect s t hat cont ain ident ifier s
wit h em bedded spaces, such as t he Or der Det ails t able, you
can oft en appr opr iat ely r efer t o t hem by enclosing t heir
ident ifier s in br acket s or single quot at ion m ar ks— for
exam ple, FROM [Order Details] .

Ret u r n ing a Su bse t of Row s

Just as you can lim it w hich colum ns are ret ur ned, you also can lim it which r ows
are in t he result set . The follow ing script r et urns Count r y, Cit y , and
Com panyNam e colum n values for a subset of t he rows in t he Cust om ers t able.
The expression in t he WHERE clause denot es t he pr ecise subset — nam ely, t hose
cust om ers from a count ry beginning w it h eit her t he let t er B or C. That filt er ing is
done by using t he SUBSTRI NG funct ion t o exam ine j ust t he first charact er in each
Count ry colum n value. I will show y ou a sim pler way t o expr ess t his in a
subsequent sam ple, but you’ll lik ely find t his ex posur e t o t he SUBSTRI NG funct ion
useful.
Any legit im at e expression works in a WHERE clause. Your ex pr ession can apply t o
t he values for any colum n designat ed by t he r ow source in t he FROM clause.
The code also dem onst rat es t he use of t he ORDER BY clause. Because of t he t wo
argum ent s in t he clause, t he result set appears in alphabet ical order by count ry .
Wit hin each count ry, t he cit ies ar e, in t ur n, sort ed in alphabet ical order.
--SomeColumnsFromSomeRows
--Select some columns from some rows.
SELECT Country, City, CompanyName
FROM Customers
WHERE SUBSTRING(Country,1,1)<=‘C’ and LEFT(Country,1)>‘A’
ORDER BY Country, City

The result set from t he SELECT st at em ent cont ains 14 r ows, inst ead of t he 91
rows in t he preceding sam ple. This differ ence isn’t significant for a single user.
Howev er, if m any users repeat edly r un a query t hat r et urns less t han one- sixt h
as m any rows, y our ov erall net w or k perform ance w ill im pr ov e.
The follow ing sam ple r epeat s t he code fr om t he prev ious one but also print s t he
num ber of rows ret urned, using a cust om form at . By default , SQL Serv er w ill
report t he num ber of rows affect ed, w hich is t he num ber of rows in a r esult set
for a SELECT st at em ent . The sam ple t ur ns off t he default m essage w it h t he SET
NOCOUNT ON st at em ent . Then it declares a local st r ing var iable— @st r Rows—for
it s cust om r eport about t he num ber of r ows r et ur ned. The @@ROWCOUNT global
variable r et urns t he num ber of r ecords affect ed by t he last T- SQL st at em ent .
Because t his funct ion ret ur ns an int eger, a CAST funct ion is used t o conv ert t he
num er ic value ret urned by @@ROWCOUNT t o charact er dat a. The charact er dat a
is t hen concat enat ed w it h a st r ing t hat inform s t he user how m any r ow s are in
t he r esult set , which t he PRI NT st at em ent sends t o t he Messages Pane in Query
Analyzer.
--CustomCount
--Select some columns from some rows
--with custom count of rows affected.
SET NOCOUNT ON
Declare @strRows nvarchar(50)
SELECT Country, City, CompanyName
FROM Customers
WHERE SUBSTRING(Country,1,1)<=‘C’ and SUBSTRING(Country,1,1)>‘A’
ORDER BY Country, City
SET @strRows = ’Rows returned = ’ + Cast(@@ROWCOUNT AS nvarchar)
PRINT @strRows
SET NOCOUNT OFF


Using t he LI KE Ope r a t or w it h W ildca r ds
Many developer s and end users creat ing T- SQL st at em ent s for dat a
access will use t he LI KE oper at or t o specify a pat t er n m at ch. This
operat or appear s in SELECT st at em ent s wit hin t he WHERE clause.
The LI KE oper at or t ypically work s wit h one of t hree wildcard
par am et ers— % , _, and ^ . The % param et er r epresent s any set of
0 or m ore charact ers. You can use it at t he beginning or end of a
sear ch st r ing. The _ param et er designat es a single char act er in a
sear ch st r ing. You can posit ion t he _ par am et er at t he beginning or
end of a sear ch st r ing or wit hin a search st ring. The ^ par am et er
specifies t hat ret ur n values not m at ch a pat t er n. This param et er
always appears in a sear ch st r ing w it hin square bracket s. You can
apply it t o an individual charact er or a range of char act ers. Square
bracket s can denot e a pat t ern range wit h or wit hout t he ^
par am et er.
The following code dem onst r at es t he use of t he % param et er t o
ret ur n all rows in t he Cust om er s t able of t he Nort hwind dat abase
wit h U as t he first let t er of t heir Count ry colum n value. The ret urn
set includes rows wit h t he Count ry colum n values USA and UK.
--Return rows with Country values beginning with U.
SELECT CompanyName, Country
FROM Customers
WHERE Country LIKE ’U%’

By applying t he _ param et er in t he argum ent for a LI KE operat or, a
SELECT st at em ent can r et urn j ust rows t hat cont ain USA inst ead of
UK. The ’U_A’ ar gum ent fails t o m at ch r ows wit h t he Count r y
colum n value UK.
--
Return rows with Country values beginning with U followed
--
by any character, the letter A and any other characters.
SELECT CompanyName, Country
FROM Customers
WHERE Country LIKE ’U_A’

Using t he LI KE Operat or wit h Wildcards ( cont inued)
Wit h t he ^ operat or in squar e br acket s, we can ret ur n all rows
fr om t he Cust om ers t able ex cept t hose t hat st ar t t heir Count r y
colum n value wit h U.
--
Return rows with Country values that don’t begin with U.
SELECT CompanyName, Country
FROM Customers
WHERE Country LIKE ’[^U]%’

Using t he square brack et s t o denot e a range can sim plify som e
expressions. For exam ple, y ou can r et ur n row s fr om t he Cust om ers
t able t hat have Count ry colum n values beginning wit h eit her B or C
wit h t he square brack et s and t he LI KE operat or . The following
SELECT st at em ent shows t he sy nt ax.
--Return rows with Country values beginning with B or C.
SELECT CompanyName, Country
FROM Customers
WHERE Country LIKE ’[B-C]%’


Ca lcula t e d Colu m n s

A calculat ed colum n is one t hat doesn’t appear wit hin t he row source for a
SELECT st at em ent . I nst ead, you specify t he calculat ed colum n w it h an expr ession
inside t he SELECT st at em ent . Because norm alized t ables aren’t supposed t o
cont ain colum ns t hat depend on ot her colum ns in t he sam e t able, y ou w ill oft en
need t o dev elop calculat ed colum ns w hen work ing w it h pr oper ly designed
dat abases. For exam ple, y ou can com put e ext ended pr ice in t erm s of quant it y ,
price, and discount for t he line it em s in a t able of order det ails. I n addit ion, y ou
can com put e how lat e a shipm ent or a paym ent is by com put ing t he difference
bet ween dat es.
The follow ing sam ple illust rat es how t o specify a calculat ed colum n as well as how
t o use t he CAST funct ion t o t ransform t he dat a t ype for a calculat ed result . The
script list s four r egular colum ns from t he Order Det ails t able in t he Nort hw ind
dat abase and also a couple of calculat ed colum ns t hat com put e ext ended pr ice.
The calculat ed colum ns each m ult iply one regular colum n value by anot her t o
com put e ext ended pr ice, but t hey differ in form at t ing. Alt hough Quant it y is a
sm allint dat a t ype and Unit Pr ice is a m oney dat a t ype, Quantity*UnitPrice
ret ur ns a result w it h a m oney dat a t ype. However, m ult iply ing by (1-Discount)
conv ert s t he dat a t ype for t he expr ession t o a r eal dat a t ype. Wit hout any
conv ersion, t he ext ended pr ice w ill appear in scient ific not at ion ( wit h an E in t he
result ) . The sam ple shows how t o convert t he r esult t o eit her a m oney dat a t ype
or a decim al dat a t ype wit h t w o places aft er t he decim al point . Bot h of t hese
conv ersions pr eser ve t he ext ended price r esult as a num er ic value.
                                     N ot e
See t he “Dat a Type Precedence” t opic in Books Online for an
int roduct ion t o how SQL Serv er ret ur ns result s when t her e is
a calculat ion bet ween colum n v alues wit h different dat a
t y pes.
--AddCalculatedColumn
--Add a calculated column to the result set formatted
--to two different numeric formats.
SELECT OrderID, Quantity, UnitPrice, Discount,
    CAST(Quantity*UnitPrice*(1-
Discount) AS money) AS ’Price as money’,
    CAST(Quantity*UnitPrice*(1-
Discount) AS dec(9,2)) AS ’Price as dec(9,2)’
FROM [Order Details]

Figur e 3- 1 displays an excerpt from t he r esult set for t he preceding script . The
t wo colum ns on t he r ight show t he out com e fr om t he t w o CAST funct ions. The
label t o t he r ight of each CAST funct ion appear s as t he colum n heading in t he
result set excerpt . The CAST funct ion t hat conv ert s ext ended price t o m oney
shows four places t o t he right of t he decim al point . This is t he scale for t he
m oney dat a t ype. The CAST funct ion t hat t ransform s t he ext ended pr ice int o a
decim al dat a t ype show s j ust t wo places aft er t he decim al point . This is consist ent
wit h t he dec( 9,2) dat a t ype specified in t he CAST funct ion.

Figu r e 3 - 1 . An e x cer pt sh ow ing t h e r esu lt of t w o diffe re n t CAST fu n ct ion s
                                   for a re a l d at a t yp e .




The next sam ple illust rat es how t o com put e and r eport t he difference bet ween
t wo dat et im e v alues. The T- SQL bat ch uses t he DATEDI FF funct ion t o com put e
t he differ ence bet w een t wo local var iables. While t his sam ple isn’t explicit ly for
colum n values, t he sam e t echniques apply t o calculat ed colum n values. ( See t he
“Perform ing Dat e Ar it hm et ic” sect ion for det ails t hat sp- ecifically pert ain t o
colum n values.) The GETDATE funct ion r et ur ns a cur rent dat e and t im e. The
bat ch deposit s t he cur rent dat e and t im e int o t wo different local v ar iables—
@dt St art at t he t op of t he bat ch and @dt End in t he next - t o- last st at em ent . The
DATEDI FF funct ion com put es t he differ ence bet ween t hese t wo local v ariables.
The DATEDI FF funct ion enables you t o ext ract t he differ ence bet ween dat et im e
values in any of sev eral unit s. Using m s as t he first argum ent ex t ract s t he
difference in m illiseconds. You can use a pr ocedure lik e t his one for a quick
snapshot of t he t im e it t akes t o run som e T- SQL st at em ent s. Ot her, m ore
com prehensiv e, per for m ance m easures are av ailable fr om SQL Serv er ; see, for
exam ple, “Query Window St at ist ics Pane” in Books Online for m or e det ail.

                                     N ot e
A local var iable in T- SQL oper at es like a m em ory var iable in
Visual Basic. Ch a pt e r 3 provides explicit coverage of T- SQL
local variables.
--ComputeWithDatediff
--Demonstrates use of DATEDIFF function to compute
--a difference in milliseconds.
DECLARE @dtStart datetime
DECLARE @dtEnd datetime
DECLARE @intOrderID int
SET @intOrderID = 10700
SET @dtStart = GETDATE()
SELECT OrderID, Quantity, UnitPrice, Discount,
    CAST(Quantity*UnitPrice*(1-
Discount) AS money) AS ’Price as money’,
    CAST(Quantity*UnitPrice*(1-
Discount) AS dec(9,2))’Price as dec(9,2)’
FROM [Order Details]
WHERE OrderID < @intOrderID
SET @dtEnd = GETDATE()
SELECT DATEDIFF(ms, @dtStart, @dtEnd) ’Time to run (ms)’




Aggr e ga t in g a nd Gr oupin g Row s
T- SQL aggr egat e funct ions can apply t o all t he rows in a r esult set or j ust subset s
of t hem , such as t hose ident ified w it h a GROUP BY clause. For exam ple, you can
count t he num ber of ov erall rows in a r ow sour ce, or y ou can count t he rows by
count ry ( or by any ot her value on which y ou gr oup r ows) . You can choose t o
ret ur n aggr egat e values and t he r ows t hey sum m ar ize, or j ust t he aggr egat e
values.

Su m m a r y of Aggr e ga t e Fu nct ion s

Table 3- 1 it em izes t he aggregat e funct ions by list ing t heir nam es wit h a short
descript ion. The purpose of m any of t hese funct ions is im plied by t heir nam e. For
furt her det ails about funct ionalit y and synt ax , search Books Online for a t opic
wit h t he funct ion nam e.
                    7DEOH  6XPPDU\ RI 764/ $JJUHJDWH )XQFWLRQV

       1DPH                                       'HVFULSWLRQ
AVG                Ret urns an average
BI NARY            Can ret urn t he binary check sum for a row
CHECKSUM
CHECKSUM           Com put es a checksum for use in const ruct ing hash index es
CHECKSUM AGG Per form s a checksum com put at ion for a group
COUNT              Count s t he it em s in a gr oup or ov erall row source; r et ur ns an
                   int value
COUNT BI G         Like Count funct ion but ret ur ns a bigint value
GROUPI NG          For use wit h CUBE and ROLLUP operat ors
MAX                Ret urns m axim um value in a colum n
MI N               Ret urns m inim um value in a colum n
SUM                Ret urns sum of values in a colum n
STDEV                Com put es st andard dev iat ion for t he sam ple of values in a
                     colum n
STDEVP               Com put es st andard dev iat ion for t he populat ion of values fr om
                     which a colum n sam ples
VAR                  Com put es var iance for t he sam ple of v alues in a colum n
VARP                 Com put es var iance for t he populat ion of values from w hich a
                     colum n sam ples


Aggr e ga t in g W it hou t Gr ou pin g

Like som e of t he ot her aggregat e funct ions, t he COUNT funct ion has m ult iple
for m s. For exam ple, COUNT(*) ret ur ns t he num ber of values in a row source,
including null and duplicat e values. The WHERE clause can const rain t he range of
rows ov er which COUNT(*) com put es a r esult . I n t he next sam ple, t he r ow source
includes all cust om ers fr om a count ry st art ing w it h t he let t er B or C. Because t he
Cust om ers t able in t he Nort hwind dat abase has a pr im ary key, t he r ow s are all
unique. This SELECT st at em ent ret ur ns a scalar value of 14, w hich is t he num ber
of rows in t he Cust om er s t able m eet ing t he cr it er ion expr ession in t he WHERE
clause. Not ice t hat like an earlier sam ple in t his chapt er , t his code lim it s count ries
t o t hose st art ing w it h t he let t er B or C but does so using LEFT and I N rat her t han
SUBSTRI NG. You can use eit her m et hod, but t his one requir es a lit t le less t yping.
--CountRows
--Count all rows meeting a criterion.
SELECT Count(*)
FROM Customers
WHERE LEFT(Country,1) IN (‘B’,’C’)

You can use t he COUNT funct ion t o r et ur n j ust t he num ber of non- null v alues
wit hin a colum n by replacing t he ast er isk w it h t he nam e of a specific colum n. Any
rows w it h null values for a specific colum n in t he row source for t he quer y w on’t
be t allied as part of t he ret ur n value for t he COUNT funct ion. Changing t he
ast erisk t o a specific colum n nam e— Count ry —won’t change t he result in t he
prev ious sam ple because t here aren’t any null v alues in t he Count ry colum n. But
you can change t he r esult by using t he DI STI NCT k eyw ord as a pr edicat e t o t he
specific colum n. Posit ion t he k ey word inside t he par ent heses t railing t he funct ion.
The follow ing scr ipt illust rat es t his synt ax. The query st at em ent r et ur ns t he value
3 because t her e are only t hree dist inct count r ies in t he Cust om ers t able st art ing
wit h t he let t er B or C— Belgium , Brazil, and Canada.
--CountIncidences
--Count distinct incidences.
SELECT Count(DISTINCT Country)
FROM Customers
WHERE LEFT(Country,1) IN (‘B’,’C’)



Aggr e ga t in g w it h Gr ou pin g

I t is com m on t o use aggregat e funct ions w hen grouping on one or m or e colum ns.
For inst ance, inst ead of j ust com put ing t he t ot al count of cust om ers, you can
der iv e m or e det ailed inform at ion by com put ing t he count of cust om ers by cit y
and count ry . One approach t o per form ing t his t ype of calculat ion uses a GROUP
BY clause in a SELECT st at em ent . When y ou add a GROUP BY clause, t his, in
t ur n, places rest r ict ions on t he ent r ies in a SELECT list . I t is t ypical t o have j ust
t wo t ypes of ent r ies in t he list — aggr egat e funct ions, such as COUNT and SUM, for
specific colum ns; and colum ns t hat appear in t he GROUP BY clause.
The colum ns in t he GROUP BY clause det erm ine t he span ov er which an
aggregat e funct ion com put es. By adding Count r y t o t he GROUP BY clause and
including Count ry and COUNT( Cust om erI D) in t he list for a SELECT st at em ent ,
you can com put e t he count of cust om ers by count ry . The GROUP BY clause can
t ake m ult iple colum ns as argum ent s. Therefore, adding Cit y t o bot h t he GROUP
BY clause and t he SELECT list t ells t he COUNT funct ion t o count t he cust om ers by
cit ies wit hin count ry. The follow ing script illust rat es t his approach for cust om ers
who com e from count ries beginning wit h t he let t er B or C.
--CountCustomers
--Count column value instances meeting a criterion
--that is grouped and ordered by two columns.
SELECT Country, City, Count(CustomerID) ’# of Customers’
FROM Customers
WHERE LEFT(Country,1) IN (‘B’,’C’)
GROUP BY Country, City
ORDER BY Country, City

The result set from t he preceding script ( see Figur e 3- 2) shows how t he 14
cust om ers from count r ies beginning w it h B or C ar e dist r ibut ed by count ry and
cit y. I t shows cust om er s in nine cit ies wit hin t hree count r ies. The m ost cust om ers
in any cit y are in São Paulo, Brazil. The closing ORDER BY clause ar ranges t he
rows in t he r esult set alphabet ically by cit y w it hin count ry.

  Figu r e 3 - 2 . A re su lt se t sh ow in g g rou pin g b y cit y w it h in cou n t ry for a
                                    cou n t of cu st om e r s.




The result set for t he preceding scr ipt count s t he cust om ers by cit y, but it doesn’t
break out result s separat ely by gr oup or pr ov ide any subt ot als for t he num ber of
cit ies wit hin each count ry. You can use t he COMPUTE BY and COMPUTE clauses of
a SELECT st at em ent t o generat e r esult s lik e t hese. The follow ing script shows
how t o use t he COMPUTE BY clause t o split t he result s by count r y and add a
count of t he num ber of cit ies wit hin each count r y. A COMPUTE BY clause requir es
a m at ching ORDER BY clause; bot h clauses m ust specify t he sam e colum n nam e
as an argum ent . I n t his sam ple, not ice t hat Count ry appears in t he COMPUTE BY
and ORDER BY clauses. The final COMPUTE clause adds a count of t he t ot al
num ber of cit ies across all count r ies in t he collect ion of r esult set s for t he SELECT
st at em ent .
--CountCustomersInSpecifiedCountries
--Count column value instances meeting a criterion that is
--grouped and ordered by two columns and subtotaled by
--one column.
SELECT Country, City, Count(CustomerID) AS ’# of Customers’
FROM Customers
WHERE LEFT(Country,1) IN (‘B’,’C’)
GROUP BY Country, City
ORDER BY Country
COMPUTE Count(City) BY Country
COMPUTE Count(City)

The script generat es seven result set s t hat appear in a single Result s Pane w it hin
Query Analyzer, as shown in Figur e 3- 3. A separat e colum n header denot es t he
beginning of each result set . The t op r esult set shows t he count of cust om ers by
cit y w it hin Belgium . The second r esult set displays a count of t he num ber of cit ies
in Belgium . The next t wo pairs of result set s pr ov ide com parable infor m at ion for
cust om ers from Br azil and Canada. The final r esult set shows t he t ot al count of
cit ies across t he pr eceding result set s for each count r y.

Figu re 3 - 3 . A colle ct ion of re su lt se t s de m on st r at in g t h e op er a t ion of t h e
                        COM PUTE BY a n d COM PUTE cla u se s.




The next exam ple r et ur ns t o a m ore basic applicat ion of t he GROUP BY clause,
but t his script dem onst r at es t he aggr egat ion of a calculat ed colum n— nam ely ,
ext ended pr ice based on t he Quant it y , Unit Pr ice, and Discount colum ns in t he
Order Det ails t able. Because t he script groups by OrderI D colum n values, t he
result set displays t he t ot al ext ended pr ice for all t he it em s w it hin each order .
This script groups by Or derI D, and it also aggr egat es by OrderI D. The count of a
single OrderI D colum n v alue w it hin an order r et ur ns t he num ber of line it em s for
an order . The sum of t he expr ession for ext ended pr ice pr ov ides t he t ot al
ext ended pr ice for an or der. This is t he first sam ple script in t his book t hat
illust rat es t he synt ax for t he HAVI NG clause. I n t his inst ance, t he clause rest rict s
t he ent ries in t he result set t o orders w it h a t ot al ext ended pr ice of m or e t han
$11,000. The final ORDER BY clause in t he script is necessary t o arrange t he r ows
in descending order based on t ot al ext ended pr ice.
--CountAndSum
--Count one real column (OrderID) and SUM one calculated column
--to get total Extended Price for each order.
--Format money data type as characters for display.
SELECT OrderID, COUNT(OrderID) ’Line items’,
      ’$’ +
      CONVERT(varchar,CAST(SUM(Quantity*UnitPrice*(1-
Discount)) AS money),1)
      AS ’Extended Price’
FROM [Order Details]
GROUP BY OrderID
HAVING SUM(Quantity*UnitPrice*(1-Discount)) > 11000
ORDER BY SUM(Quantity*UnitPrice*(1-Discount)) DESC

Not ice t he use of a CAST funct ion nest ed w it hin a CONVERT funct ion. The CAST
funct ion t ransform s t he real t ot al ext ended pr ice for an order int o a m oney value.
The CONVERT funct ion repr esent s t he m oney v alue as a char act er st r ing
for m at t ed for curr ency wit h com m a delim it ers bet ween ev ery t hr ee digit s t o t he
left of t he decim al point and j ust t wo digit s t o t he r ight of t he decim al point . A
st ring ex pr ession adds a leading cur rency sign. The CONVERT funct ion offers
t hr ee different st yles for render ing cur rency as a charact er value. The t hird
argum ent for t he CONVERT funct ion designat es t he st yle. The follow ing t able
sum m ar izes t he effect of each possible value for t he t hird argum ent . The default
value is 0.
 &219(57 6W\OH $UJXPHQW                        6W\OH $UJXPHQW )RUPDW (IIHFWV
9DOXHV IRU 5HQGHULQJ 0RQH\
0                             No com m as, but j ust t wo digit s t o t he r ight of t he
                              decim al point
1                             Com m as separat ing ev ery t hr ee digit s t o t he left of t he
                              decim al point and j ust t wo digit s t o t he r ight of t he
                              decim al point
2                             No com m as, and four digit s t o t he right of t he decim al
                              point




Pr ocessing Da t es
Dat es ar e different fr om ot her dat a t ypes, and processing t hem can be t ricky . For
one t hing, SQL Ser ver t ypically saves dat e values in a num er ic form at wit h eit her
a dat et im e or a sm alldat et im e dat a t ype. For anot her , dat es repr esent a calendar
in w hich t he t ot al days per m ont h ar en’t consist ent fr om one m ont h t o t he next .
Also, you can gr oup dat es by day , w eek, m ont h, quart er, and y ear. Fort unat ely ,
SQL Ser ver offers som e highly useful funct ions t o sim plify t he use of dat es t hat
don’t apply t o ot her dat a t ypes. This sect ion ex plor es som e of t hese funct ions and
ot her t echniques t hat can help you pr ocess dat es wit h SQL Serv er.

Cou n t ing by Ye a r a nd M on t h

I t is com m on t o need t o aggregat e dat a by y ear and m ont h. This sect ion prov ides
four code sam ples t hat dem onst rat e how t o do it . I n part icular , t he scr ipt t ackles
t he problem of count ing t he orders per per iod of t im e, such as by y ear or by
m ont h w it hin a y ear.

Cou n t in g by Ye a r

The first sam ple generat es a r esult set t hat accum ulat es t he num ber of orders by
year. I t t akes j ust t hr ee lines t o do t his. The first is a SELECT st at em ent wit h a
list t hat includes t wo ent ries. The first ent ry is t he DATEPART funct ion for t he
OrderDat e from t he Orders t able. The DATEPART funct ion ret urns an int eger t hat
reflect s a part of a dat et im e value, such as t he m ont h num ber for a dat e. The
funct ion t akes t w o argum ent s. The first argum ent denot es t he dat e par t t o
ext ract . The sam ple uses yyyy t o ext ract t he year as a four - digit num ber. The
second argum ent is t he act ual dat et im e value. This can be an expr ession or a
colum n value. The sam ple r efer ences t he OrderDat e colum n value from t he
Orders t able. I n order t o accum ulat e a quant it y by y ear , t he T- SQL sam ple
includes t he sam e DATEPART funct ion as t he ar gum ent for a GROUP BY clause.
The second list ent ry is a COUNT funct ion. The funct ion uses OrderI D as it s
argum ent t o count t he num ber of orders wit hin a y ear .
--CountOrdersByYear
--Count one column by year date part.
SELECT DATEPART(yyyy, OrderDate), COUNT(OrderID)
FROM Orders
GROUP BY DATEPART(yyyy, OrderDate)

The DATEPART funct ion is ext r em ely flex ible. I t can ext ract any of 11 different
dat e part s from a dat et im e value. You can also use t he DATEPART funct ion w it h
sm alldat et im e values, but t he funct ion cannot ext ract m illiseconds for
sm alldat et im e values because t he dat a t ype doesn’t support t his lev el of
precision. The funct ion offers m ult iple argum ent s for specify ing w hich dat e part s
t o ext ract . At a m inim um , y ou can designat e dat e part s by t heir nam e or t heir
abbrev iat ion. Many dat e part s give you t he choice of t wo abbr ev iat ions for
referencing t hem . You can use t he DATEPART funct ion w it h one of it s part s t o
replace t he Year , Mont h, and Day funct ions. Table 3- 2 shows t he possible dat e
part argum ent s available for t he DATEPART funct ion.
                     7DEOH   $UJXPHQWV IRU WKH '$7(3$57 )XQFWLRQ

             'DWH 3DUW 1DPH                             'DWH 3DUW $EEUHYLDWLRQ
year                                    yy, y y yy
quart er                                qq, q
m ont h                                 mm, m
dayofy ear                              dy, y
day                                     dd, d
week                                    wk, ww
weekday                                 dw
hour                                    hh
m inut e                                m i, n
second                                  ss, s
m illisecond                            ms

Cou n t in g by M on t h

Dev eloping a r esult set t hat r et ur ns t he num ber of orders by m ont h w it hin y ear
builds on t he t echniques t hat y ou learned previously. I t is j ust a m at t er of put t ing
t he elem ent s t oget her cor rect ly. You include t hr ee it em s in t he list for t he SELECT
st at em ent t o ret ur n t he year, m ont h, and count of orders in a t im e per iod.
Specify t he Orders t able as t he argum ent for t he FROM clause. I n t he GROUP BY
clause, use a DATEPART funct ion st at em ent t o r et ur n t he year followed by a
com m a and a DATEPART funct ion t o ret ur n t he m ont h, like t his:
GROUP BY DATEPART(yyyy, OrderDate), DATEPART(mm,OrderDate)

Because we want t he result rows ordered by m ont h w it hin y ear , t he SELECT
st at em ent r equires an ORDER BY clause w it h t he sam e argum ent s as t he GROUP
BY clause.
The follow ing scr ipt shows t he SELECT list it em s. The first t wo it em s in t he list
m at ch t he argum ent s for t he GROUP BY clause. The last SELECT list argum ent is
t he aggr egat e funct ion, COUNT, t hat count s t he num ber of orders per dat e unit .
This sam ple design is v er y general. You can use any ot her aggr egat e funct ion or
m or e aggregat e funct ions t han t hose in t he sam ple. For exam ple, you can add a
DATEPART funct ion t o count orders by w eek wit hin y ear inst ead of or in addit ion
t o m ont h w it hin y ear.
--CountOrdersByYearAndMonth
--Count one column by year and month date parts of another.
SELECT DATEPART(yyyy, OrderDate) AS ’Year’,
       DATEPART(mm,OrderDate) AS ’Month’,
       COUNT(OrderID) AS ’Orders’
FROM Orders
GROUP BY DATEPART(yyyy, OrderDate), DATEPART(mm,OrderDate)
ORDER BY DATEPART(yyyy, OrderDate), DATEPART(mm,OrderDate)

Figur e 3- 4 shows an ex cerpt of t he result s fr om t he script . Not ice t hat m ont hs ar e
represent ed by t heir num ber . They are sort ed wit hin y ear, w hich also happens t o
be a num ber. At least som e of y our client s ar e bound t o r equest t he r eplacem ent
of t he m ont h num bers wit h nam es.

   Figu re 3 - 4 . An e x cer pt fr om a r e su lt se t t ha t displa ys t h e n u m be r of
                            or de rs by m on t h w it h in yea r .




The next script illust rat es an appr oach t o generat ing t he report in Figure 3- 4, but
wit h nam es inst ead of num bers t o designat e m ont hs. You can use t he DATENAME
funct ion t o ext ract a m ont h nam e as a charact er st r ing from a dat e. The
DATENAME funct ion t ak es t wo argum ent s— j ust lik e t he DATEPART funct ion. Bot h
funct ions use t he sam e codes t o represent dat e part s, and t he t wo also use a
dat et im e v alue as t he second argum ent . ( You can use a sm alldat et im e v alue as
well.) I n t he case of a m ont h dat e part , t he DATENAME funct ion pr ov ides t he
m ont h’s full nam e, such as January or February , inst ead of a num ber, such as 1
or 2.
--ShowMonthNames
--Count one column by year and month date parts of another
--column while showing month names instead of month numbers.
SELECT DATEPART(yyyy, OrderDate) AS Year,
      DATENAME(mm, OrderDate) AS Month,
      COUNT(OrderID) AS Orders
FROM Orders
GROUP BY DATEPART(yyyy, OrderDate),
      DATENAME(mm, OrderDate)
ORDER BY DATEPART(yyyy, OrderDate)

Howev er, t her e’s a problem . The scr ipt sort s t he result set by m ont h nam e, but
t he alphabet ical order of t he m ont hs doesn’t corr espond t o t heir t em poral order.
That ’s w hy t he m ont hs in t he r esult set are ar ranged alphabet ically w it hin each
year r at her t han chr onologically. One solut ion t o t his problem is t o set up a one-
t o- one cor respondence bet ween t he m ont h nam es ret ur ned by t he DATENAME
funct ion and t he m ont h num bers r et urned by t he DATEPART funct ion.
The follow ing scr ipt shows an approach t o m apping m ont h nam es t o m ont h
num bers t hat relies on only t he SELECT list it em s along w it h t he GROUP BY and
ORDER BY clauses. The SELECT list cont ains t hr ee t erm s: t he y ear r et urned by
t he DATEPART funct ion, t he m ont h nam e r et ur ned by t he DATENAME funct ion,
and t he COUNT funct ion t o com put e t he num ber of orders by y ear and m ont h.
( Any ot her aggr egat e funct ion would w or k as w ell.) Because t he DATENAME
funct ion appears in t he SELECT list , it m ust also be an argum ent for t he GROUP
BY clause. The t r ick is t o place t he DATENAME funct ion in t he GROUP BY clause in
bet ween t he first DATEPART funct ion for y ear and a second DATEPART funct ion
for m ont h. Because m ont h nam es m ap per fect ly t o m ont h num bers, t he t w o
GROUP BY argum ent s aft er t he DATEPART for y ear gr oup t he rows in an ident ical
way . The DATENAME ar gum ent for m ont h has t o appear in t he GROUP BY clause
because y ou need it in t he SELECT list . I n addit ion, t he DATEPART funct ion t hat
ret ur ns a m ont h’s num ber in t he GROUP BY clause is also necessary because t he
ORDER BY clause r equir es it as it s second argum ent . The out put from t he
follow ing scr ipt m at ches t he out put in Figure 3- 4 except t hat t he second colum n
shows m ont h nam es inst ead of m ont h num bers.
--ShowMonthNamesChronologically
--Count one column by year and month date parts of another
--column while showing month names instead of month numbers.
--Order months by names chronologically, not numerically.
SELECT DATEPART(yyyy, OrderDate) AS Year,
       DATENAME(mm, OrderDate) AS Month,
       COUNT(OrderID) AS Orders
FROM Orders
GROUP BY DATEPART(yyyy, OrderDate),
       DATENAME(mm, OrderDate),
       DATEPART(mm, OrderDate)
ORDER BY DATEPART(yyyy, OrderDate), DATEPART(mm, OrderDate)



Pe r f or m in g D a t e Ar it h m e t ic

The “Calculat ed Colum ns” sect ion dem onst rat ed how t o t ak e advant age of SQL
dat et im e local var iables t o com put e t he difference bet w een t w o dat et im e v alues.
That illust rat es dat e ar it hm et ic. This sect ion dr ills down m ore deeply int o t he
t opic.
Let ’s st art out w it h a sam ple t hat screens order s t o find t hose w it h an est im at ed
arr ival dat e t hat is lat er t han t he required dat e for t he order . These are lat e
orders because t hey arriv e at t he cust om er aft er t he r equired dat e. The SELECT
list for t he sam ple includes OrderI D and t hr ee dat et im e colum ns: OrderDat e,
RequiredDat e, and ShippedDat e. Because t he t im e of day t hat an order ships is
im m at erial, t he t hr ee dat et im e colum ns are in LEFT funct ions t hat st r ip off j ust
t he first 11 charact ers for display. This perm it s t he display of t he dat es in t hr ee
part s: a t hr ee- charact er part for t he m ont h, up t o t wo digit s for t he display of t he
day num ber in t he m ont h, and a four - digit field for t he year. A single blank
charact er delim it s t he first part from t he second part and t he second part from
t he t hird part .
The WHERE clause for t he follow ing SELECT st at em ent per form s t he dat e
arit hm et ic. The expression for t he clause r et urns all r ows from t he Orders t ables
whose RequiredDat e is less t han ShippedDat e plus 3. Values in dat et im e form at
represent one day w it h an int eger value of 1. By adding 3 t o t he ShippedDat e
colum n value, t he WHERE clause expression com put es a proj ect ed ar r ival dat e
t hat is t hree days aft er t he order ships. I f t he proj ect ed arr ival dat e is great er
t han t he Requir edDat e colum n value, t he order is lat e. The SELECT st at em ent
includes only lat e order s in it s result set .
--ListLateOrders
--List just date portion of datetime column values
--with a criterion based on day offset between two columns.
SELECT OrderID, Left(OrderDate,11) ’OrderDate’,
       Left(RequiredDate,11) ’RequiredDate’,
       Left(ShippedDate,11) ’ShippedDate’
FROM Orders
WHERE RequiredDate < ShippedDate + 3

The result set from t he preceding script is useful for get t ing a basic grasp of lat e
orders, but all it does is list t he orders. The v iewer of t he r esult set is r esponsible
for com put ing t he num ber of days t hat an order is lat e as well as finding t hose
orders t hat m issed t he r equired dat e by a wide m argin. The following script
rem edies bot h of t hese weak nesses. The rem edy fashions a solut ion based on
dat e ar it hm et ic.
The sam ple’s ar it hm et ic wit h dat et im e values relies on t he DATEADD and
DATEDI FF funct ions. I t uses t hese t w o syst em funct ions t o com put e t he num ber
of days t hat an order is lat e. Wit h t he DATEADD funct ion, t he follow ing script
adds 3 days t o ShippedDat e t o com put e a proj ect ed arr ival dat e. The script
com put es t he num ber of days an order is lat e by depending on t wo expressions.
First t he WHERE clause expr ession filt ers for j ust t hose r ows in w hich t he
proj ect ed ar r ival dat e v alue is great er t han t he RequiredDat e colum n v alue. The
orders on t hese rows fr om t he Orders t able are lat e. Second t he script com put es
t he num ber of days t hat an order is lat e. The ex pression for com put ing t his nest s
t he expression for t he proj ect ed ar r ival dat e v alue inside a DATEDI FF funct ion
wit h t he Requir edDat e colum n value. DATEDI FF explicit ly refer ences day s as t he
m et r ic for com put ing t he difference bet ween t he t w o values. This DATEDI FF
funct ion appears in t he SELECT list and in t he ORDER BY clause. The SELECT list
for t his DATEDI FF funct ion includes in t he result set t he num ber of days t hat an
order is lat e; t he nam e of t his calculat ed colum n is Days Lat e. The ORDER BY
clause includes t he DESC key word so t hat SQL Ser ver w ill sort t he r esult set w it h
t he lat est orders list ed first .
--CalculateDaysLate
--Demonstrates uses of DATEDIFF for Days Late calculation
--and DATEADD for day offset in criterion expression.
SELECT OrderID, Left(OrderDate,11) ’OrderDate’,
       Left(RequiredDate,11) ’RequiredDate’,
       Left(ShippedDate,11) ’ShippedDate’,
       DATEDIFF(day,RequiredDate,DATEADD(day, 3, ShippedDate)) ’Days Lat
e’
FROM Orders
WHERE RequiredDate < DATEADD(day, 3, ShippedDate)
ORDER BY DATEDIFF(day,RequiredDate,DATEADD(day, 3, ShippedDate)) DESC

The last sam ple script in t his sect ion illust rat es how t o aggregat e a calculat ed
value and t hen group it by quart er w it hin y ear . The sam ple also shows t he synt ax
for filt er ing gr oups defined by a GROUP BY clause wit h a HAVI NG clause.
The script does it s aggregat ing w it h a SUM funct ion defined on t he DATEDI FF
expression for com put ing t he num ber of days an order is lat e. This SUM funct ion
requir es a GROUP BY clause. The one in t he sam ple specifies an order’s year and
quart er as grouping colum n values. Tw o separat e DATEPART funct ions der ive t he
year and quart er for an OrderDat e. The SELECT list cont ains t hree it em s— t he t w o
DATEPART funct ions for t he y ear and quart er and t he SUM funct ion for t he
num ber of days lat e. A HAVI NG clause includes t wo separat e expr essions t o filt er
groups in t he r esult set . First , only groups w it h a y ear value great er t han 1996
can belong t o t he r esult set . Second, t he HAVI NG clause ex cludes t he group
corr esponding t o t he second quart er of 1998. The SELECT st at em ent ’s final line is
an ORDER BY clause t hat ensur es r ows appear in order by quart er w it hin y ear .
--DaysLatePerQuarter
--
Demo Sum aggregate function of DATEDIFF with GROUP BY and HAVING clau
ses.
SELECT DATEPART(yyyy, OrderDate) AS ’Year’,
      DATEPART(q, OrderDate) AS ’Quarter’,
      SUM(DATEDIFF(d, RequiredDate, DATEADD(day, 3, ShippedDate))) AS ’
Days Late’
FROM Orders
WHERE (DATEDIFF(d, RequiredDate, DATEADD(day, 3, ShippedDate)) > 0)
GROUP BY DATEPART(yyyy, OrderDate), DATEPART(q, OrderDate)
HAVING DATEPART(yyyy, OrderDate) > 1996 AND
      NOT(DATEPART(yyyy, OrderDate) = 1998 AND DATEPART(q, OrderDate) =
 2)
ORDER BY DATEPART(yyyy, OrderDate), DATEPART(q, OrderDate)




Join s a nd Su bqu e r ie s
Joins ar e a powerful t echnique for com bining t w o or m ore r ow sources in a single
SELECT st at em ent . This sect ion int roduces j oins wit h a r ev iew of T- SQL
t echniques for cr eat ing inner j oins bet w een t wo t ables. Then it goes on t o explore
ot her form ulat ions for inner j oins and ot her kinds of j oins. The sect ion closes w it h
a couple of sam ples dem onst rat ing ways of for m ulat ing SELECT st at em ent s w it h
subquer ies. This approach is a way of m ak ing SELECT st at em ent s dynam ic
because t he subquery can ret ur n t he m ost current value t o t he SELECT st at em ent
referencing it .

An I n n e r Join Be t w e e n Tw o Ta ble s

By using an inner j oin, your dat abase solut ions can r efer sim ult aneously t o t he
cont ent fr om t w o different row sources. So far, t he sam ples in t his chapt er have
focused on j ust one t able. For exam ple, som e sam ples used t he Order Det ails
t able t o dev elop an expr ession for ext ended pr ice. Ot her sam ples work ed wit h t he
days t hat an order was lat e. These sam ples used t he Orders t able. No sam ple
processed cont ent from bot h t he Orders and Or der Det ails t ables in a single
solut ion. I nner j oins enable t his t ype of funct ionalit y. An inner j oin m ost t ypically
m erges t wo t ables when t heir values m at ch on a com m on field, such as a prim ary
key fr om one t able and it s m at ching foreign key in anot her t able.
The first j oin sam ple list s t wo colum ns from t wo differ ent t ables— t he Or ders and
Order Det ails t ables. The SELECT st at em ent r et urns t he OrderI D colum n from t he
Orders t able and t he Pr oduct I D colum n from t he Order Det ails t able. The OrderI D
colum n appears in bot h t ables. Therefore, t he SELECT st at em ent m ust use a t able
qualifier t o indicat e fr om which t able t o ext ract t he OrderI D colum n values. The
JOI N key word in t he FROM clause designat es t he t w o t ables cont r ibut ing colum n
values t o t he r esult set from t he SELECT st at em ent . The ON k ey word point s t o
t he colum ns w it hin each t able on which t o j oin t he t ables.
--JoinColumns
--Join columns from two tables.
SELECT Orders.OrderID, ProductID
FROM Orders JOIN [Order Details]
ON (Orders.OrderID = [Order Details].OrderID)

The next sam ple uses t he OrderI D colum n values fr om t he Orders t able t o m erge
it s cont ent w it h m at ching records based on OrderI D in t he Order Det ails t able. An
inner j oin im plem ent s t he m erge. As a result of t he m erge, a single SELECT
st at em ent can access cont ent from bot h t ables. The r esult set for t he SELECT
st at em ent r et urns bot h t he Days Lat e calculat ed colum n from t he Orders t able
and t he Ex t . Pr ice calculat ed colum n fr om t he Order Det ails t able.
You can specify an inner j oin w it h eit her t he FROM clause or t he WHERE clause of
a SELECT st at em ent . The follow ing sam ple dem onst rat es t he synt ax for t he FROM
clause. Wit hin t he FROM clause, posit ion t he JOI N keyword bet ween t he t wo r ow
sources part icipat ing in t he inner j oin. I t is im m at er ial w hich t able is on t he left
and right sides of t he JOI N keyword. You can opt ionally r eplace JOI N w it h I NNER
JOI N. Your FROM clause also r equires an ON keyword. The argum ent for t he ON
keyw ord expr esses how t o m erge t he r ows from t he t w o sources for t he j oin. The
ON argum ent expression w ill oft en denot e an equivalence bet w een t wo colum n
nam es, one from each of t he row sources part icipat ing in t he j oin. The ON
keyw ord expr ession dict at es which colum ns t o com par e and how t o com pare
t hem bet w een t he t w o r ow sources. Not ice t hat t he expr ession includes a t able
nam e qualifier for t he colum n nam e. This is one way t o dist inguish t he source for
a colum n. I t is vit ally im port ant t hr oughout a SELECT st at em ent wit h a j oin t o
indicat e t he source for a colum n w hen t he colum n has t he sam e nam e for t he row
source on eit her side of t he JOI N k eyw ord. I f t he colum n doesn’t hav e t he sam e
nam e in bot h row sources, t he designat ion of a t able nam e qualifier is opt ional.
The sam ple script inst r uct s SQL Ser ver t o m at ch OrderI D colum n values from t he
Orders t able w it h Order I D colum n values fr om t he Order Det ails t able. The result
set cont ains j ust t hose r ows fr om t he Order Det ails t able w it h m at ching OrderI D
values fr om t he Orders t able. Because a single order can spread acr oss m ult iple
rows in t he Order Det ails t able, colum n values from t he Orders t able r epeat for
each of t he m ult iple rows wit hin an order.
As w it h any SELECT st at em ent , t he SELECT list specifies t he colum n nam es for
t he r esult set . The sam ple includes a m ix of r eal and calculat ed colum ns. OrderI D
from t he Orders t able is a r eal colum n. All t he ot her colum ns are calculat ed. The
colum ns w it h t he nam es OrderDat e, RequiredDat e, and ShippedDat e m er ely
apply a LEFT funct ion t o ext ract t he dat e port ion of a dat et im e value. The
colum ns w it h t he nam es Days Lat e and Ext . Pr ice inv ok e m or e sophist icat ed
expressions t o calculat e t heir colum n values. The last colum n, Ext . Pr ice,
references t he Order Det ails t able. The WHERE clause filt ers for orders proj ect ed
t o ar riv e aft er t he RequiredDat e value. The ORDER BY clause k eeps t he line it em
rows for an order t oget her. Because t he OrderI D colum n is in bot h r ow sources
for t he j oin, it is necessary t o use a t able nam e qualifier for t he colum n nam e.
--DaysLateUsingJoin
--List results from two tables based on day offset criterion.
SELECT Orders.OrderID, LEFT(Orders.OrderDate,11) AS ’OrderDate’,
       LEFT(Orders.RequiredDate,11) AS ’RequiredDate’,
       LEFT(Orders.ShippedDate,11) AS ’ShippedDate’,
      DATEDIFF(day,RequiredDate,DATEADD(day, 3, ShippedDate)) ’Days Lat
e’,
    CAST([Order Details].Quantity*[Order Details].UnitPrice*
    (1-[Order Details].Discount) AS dec(9,2)) AS ’Ext. Price’
FROM Orders JOIN [Order Details]
ON (Orders.OrderID = [Order Details].OrderID)
WHERE RequiredDate < DATEADD(day, 3, ShippedDate)
ORDER BY [Order Details].OrderID

Figur e 3- 5 displays an excerpt from t he r esult set for t he preceding script . The
OrderI D colum n is from bot h r ow sources. The OrderI D colum n value r epeat s for
each line it em wit hin an order. The OrderDat e, RequiredDat e, ShippedDat e, and
Days Lat e colum ns are from t he Orders t able. The values in t hese colum ns r epeat
across t he m ult iple r ow s wit hin an order. Wit hin t he excerpt , t he Ext . Pr ice
colum n values are unique for each r ow in t he r esult set . The scr ipt calculat es
t hese colum n values based on t hree colum ns in t he Order Det ails t able.

 Figu r e 3 - 5 . An ex ce rp t from a re su lt set t h at d ispla ys con t e n t from t w o
                                      row sou r ces.




Usin g Alia se s W it h in a n I n n e r Join

Because SELECT st at em ent s can get long and difficult t o r ead w it h t able nam e
qualifiers, it is com m on t o use aliases. An alias is an alt er nat ive nam e for a t able
t hat y ou specify w it hin your SELECT st at em ent . Use t he alias as a short nicknam e
for t he or iginal t able nam e. You can specify y our alias w it hin t he FROM clause
im m ediat ely aft er specifying a t able by it s nam e. Howev er, y ou can use an alias
anyw her e t hr oughout a SELECT st at em ent , such as in t he SELECT list or t he
ORDER BY clause.
The follow ing sam ple illust rat es a j oin for t he t it les and t it leaut hor t ables from t he
pubs dat abase. The FROM clause designat es t he alias t for t he t it les t able and t a
for t he t it leaut hor t able. You can also see t he use of t hese aliases in t he SELECT
list and ORDER BY clauses in t his excerpt fr om t he script on t he following page.
SELECT ta.au_id, t.title, t.ytd_sales, t.price
FROM pubs..titles t JOIN pubs..titleauthor ta
ON (t.title_id = ta.title_id)
ORDER BY ta.au_id

The sam ple also illust rat es t he synt ax for r efer r ing t o a r ow source out side t he
curr ent dat abase cont ex t . Recall t hat all t he sam ples t hroughout t his chapt er use
t he Nort hw ind dat abase, and t hey r ely on an a USE st at em ent fr om t he second
sam ple t o specify t he dat abase connect ion for t he sam ple. The follow ing sam ple
has t he sam e dat abase cont ext , but it uses t hr ee- part nam es t o reference a r ow
source in anot her dat abase— t he pubs dat abase. The first part is t he dat abase
nam e, and t he second part is t he r ow source ow ner’s nam e. When t he owner ’s
nam e is dbo ( as in t he cur r ent inst ance) , you can leav e t he second part null
( w hich m eans you end up w it h t w o consecut ive per iods) . The t hird part is t he r ow
source nam e. I n t his sam ple, t hat is eit her t it les or t it leaut hor.
Ther e is one ot her special feat ur e about t he sam ple. I t includes T- SQL code t o
print t o t he Messages Pane t he num ber of r ows in t he r esult set . An earlier
sam ple in t he “Specify ing Colum ns and Rows” sect ion describes t he approach
applied in t he sam ple below . The reason for ex plicit ly count ing t he row s is t o
com pare t he num ber of rows in t his result set , 25, w it h a subsequent sam ple t hat
uses a differ ent k ind of j oin.
--InnerJoinWithAliases
--Inner join between authors titles and titleauthor.
--Returns 25 matching rows from both tables.
SET NOCOUNT ON
Declare @strRows nvarchar(50)
SELECT ta.au_id, t.title, t.ytd_sales, t.price
FROM pubs..titles t JOIN pubs..titleauthor ta
ON (t.title_id = ta.title_id)
ORDER BY ta.au_id
SET @strRows = ’Rows returned = ’ + Cast(@@ROWCOUNT AS nvarchar)
PRINT @strRows
SET NOCOUNT OFF



An I n n e r Join Be t w e e n Th r e e Ta ble s

I t is oft en necessary t o m erge t he r esult s of m ore t han t w o row sources in a
single SELECT st at em ent . How ever, y ou can j oin only t wo r ow sources at a t im e.
The wor kar ound t o t his predicam ent is t o use a j oined r ow source as one of t he
row sources for a new j oin. This sect ion dem onst rat es how t o im plem ent t his logic
for t he j oining of t hree t ables fr om t he pubs dat abase. This k ind of j oin is
part icular ly appropr iat e for m odeling a pair of t ables in a m any- t o- m any
relat ionship wit h a j unct ion t able bet ween t hem . The general approach t o dev -
eloping j oins in t his sect ion is applicable for m or e t han t hree row sources. See t he
T- SQL scr ipt for t he I nv oices view in t he Nort hwind dat abase for a sam ple script
t hat j oins six t ables.

                                      N ot e
You can use Ent erpr ise Manager t o view t he scr ipt for a
dat abase obj ect . For m ore inform at ion on Ent erprise
Manager and ot her SQL Ser ver 2000 t ools, see Books Online.
The special synt ax for a t hr ee- t able j oin is in t he FROM clause of your SELECT
st at em ent . Add t ables t o t he FROM clause in t he order t hat you want t hem t o
j oin— st art ing from t he ext r em e left t able. Join t his t able t o one of y our r em aining
t wo t ables. Use t he sy nt ax pr ev iously present ed for j oining t wo t ables. Aft er t he
argum ent for t he ON key word, add a second inst ance of t he JOI N k eyw ord
follow ed by t he nam e of t he t hird t able. Next add a second inst ance of t he ON
keyw ord t hat specifies how t o j oin t he t hird t able w it h t he j oined first and second
t ables. Aft er specify ing t he FROM clause as described, y ou are fr ee t o r efer t o
colum ns fr om any of t he t hr ee t ables. You can ev en creat e calculat ed colum ns
t hat draw on colum ns fr om t wo or t hree t ables.
The FROM clause in t he follow ing scr ipt dem onst rat es how st raight for ward it is t o
j oin t hr ee t ables. This sam ple script j oins t he t it les t able w it h t he t it leaut hor
t able. Then t he scr ipt m erges t he j oined t it les and t it leaut hor t ables w it h t he
aut hors t able. The script illust rat es t he sy nt ax for j oining t he t hree t ables as well
as t he use of colum ns fr om all t hr ee t ables in t he SELECT list .
--InnerJoinWithThreeTables
--List results from three tables.
SELECT aut.au_fname, aut.au_lname, t.title, t.ytd_sales,
      t.royalty, ta.royaltyper
FROM pubs..titles t JOIN pubs..titleauthor ta
ON (t.title_id = ta.title_id) JOIN pubs..authors aut
ON (ta.au_id = aut.au_id)

I n addit ion t o list ing colum ns fr om all t hr ee t ables, y ou can use t he j oin t o
com put e calculat ed colum ns wit h input s fr om t wo or m ore t ables. The follow ing
script illust rat es t his design feat ur e wit h a calculat ed colum n for r oyalt y paid t o
an aut hor for a t it le. The calculat ed colum n draws on yt d_sales and roy alt y from
t he t it les t able and royalt yper fr om t he t it leaut hor t able. Bot h roy alt y and
roy alt yper represent percent ages as int egers. Ther efore, t he calculat ed field
div ides t he pr oduct for all t hr ee colum ns by 10,000.
--JoinWithCalculatedColumn
--List results from three tables, including a calculated column
--based on two tables.
SELECT aut.au_fname, aut.au_lname, t.title,
       CAST(t.ytd_sales * t.royalty * ta.royaltyper AS money)/10000,
       t.advance
FROM pubs..titles t JOIN pubs..titleauthor ta
ON (t.title_id = ta.title_id) JOIN pubs..authors aut
ON (ta.au_id = aut.au_id)
ORDER BY t.title, aut.au_lname, aut.au_fname


Ou t e r Join s

An out er j oin cont rast s wit h an inner j oin by adding in all t he rows fr om a r ow
source w het her or not t he r ow sat isfies an expr ession for t he ON keyw ord. There
are t hree t ypes of out er j oins: a left out er j oin, a right out er j oin, and a full out er
j oin. When perform ing one of t hese out er j oins, replace JOI N or I NNER JOI N wit h
an appropr iat e alt ernat ive t erm , such as LEFT OUTER JOI N, RI GHT OUTER JOI N,
or FULL OUTER JOI N. Wit h a left out er j oin, all t he r ows from t he row source on
t he left side of t he LEFT OUTER JOI N keyword phrase appear in t he r esult set
whet her or not t hey sat isfy t he expr ession in t he argum ent for t he ON keyw ord. A
right out er j oin w or ks sim ilar ly t o a left out er j oin, but it adds in all t he r ows from
t he r ow source on t he right of RI GHT OUTER JOI N. A full out er j oin adds in all t he
rows fr om r ow sources on bot h sides of FULL OUTER JOI N. Aside from t he
keyw ord phrase nam e, t he synt ax for t he t hr ee t ypes of out er j oins is t he sam e
as for an inner j oin.
The follow ing sam ple dem onst rat es t he synt ax for a left out er j oin bet w een t he
t it les t able and t he t it leaut hor t able in t he pubs dat abase. Not ice t hat t he synt ax
exact ly follows t he pr eceding inner j oin sam ple bet ween t hese t ables ex cept for
t he r eplacem ent of t he JOI N k ey word by t he LEFT OUTER JOI N k eyw or d phr ase.
I n addit ion, t he result set for t his SELECT st at em ent includes 26 r ows inst ead of
t he 25 rows in t he preceding sam ple. The ext ra row is fr om a book t it le t hat
doesn’t hav e an aut hor designat ed for it . The pr eceding SELECT st at em ent
screened out t his ex t ra row because t he t it les t able t it le_id colum n value had no
m at ch in t he t it leaut hor t able. However, because t he t it les t able is on t he left side
of t he LEFT OUTER JOI N, t he j oin forces in t he r ow fr om t he t it les t able, alt hough
it has no corr esponding t it le_id colum n value in t he t it leaut hor t able.
--LeftOuterJoin
--Left outer join between authors titles and titleauthor.
--Returns 26 rows (25 matching rows + 1 non-matching row
--from the titles table).
SET NOCOUNT ON
Declare @strRows nvarchar(50)
SELECT ta.au_id, t.title, t.ytd_sales, t.price
FROM pubs..titles t LEFT OUTER JOIN pubs..titleauthor ta
ON (t.title_id = ta.title_id)
ORDER BY ta.au_id
SET @strRows = ’Rows returned = ’ + Cast(@@ROWCOUNT AS nvarchar)
PRINT @strRows
SET NOCOUNT OFF

One pract ical use for left and r ight out er j oins is t hat of list ing rows on one side of
a j oin w it hout a m at ching row on t he ot her side. For exam ple, w e can use an
adapt at ion of t he preceding sam ple t o list t he specific r ow in t he t it les t able t hat
has no m at ching t it le_id colum n value in t he t it leaut hor t able. The following script
dem onst rat es t he synt ax for t he solut ion. Not ice t hat t he basis for t he solut ion is
a WHERE clause t hat screens for a null value fr om t he t able w it hout t he m at ching
row .
--RowsWithNoMatch
--Find rows in the left table without a match in the right table.
SELECT ta.au_id, t.title, t.ytd_sales, t.price
FROM pubs..titles t LEFT OUTER JOIN pubs..titleauthor ta
ON (t.title_id = ta.title_id)
WHERE ta.au_id IS NULL



Se lf Join s a n d Cr oss Joins

Two special k inds of j oins, w hich serv e cont rast ing purposes, ar e self j oins and
cross j oins. A self j oin m erges a t able w it h it self. Use a self j oin w hen you need t o
relat e t he v alues in one colum n t o t he values in anot her colum n of t he sam e
t able. A cr oss j oin cr eat es a r esult set t hat com bines colum n values from all t he
rows in one row source wit h colum n values from all t he rows in a second row
source. This is differ ent from an out er j oin because a cross j oin doesn’t creat e any
null values in it s result set . You w ill t ypically use t his k ind of j oin w hen at least
one of your row sources is v er y sm all, such as a scalar value or a r ow source w it h
j ust a couple of rows.
Wit hin t he cont ext of t he Nort hw ind dat abase, t he classic sit uat ion calling for t he
applicat ion of a self j oin is t he t ask of r et ur ning t he nam es of t he m anagers from
t he Em ploy ees t able. This t able cont ains a separat e r ow for each em ploy ee, wit h
t wo set s of colum ns t hat cont r ibut e t o t he t ask. The first set includes t he
Em ploy eeI D, First Nam e, and Last Nam e colum ns. The second set includes a single
colum n, Report sTo. The Report sTo colum n cont ains t he Em ploy eeI D value for t he
m anager t o w hom an em ployee r eport s. You can find t he m anager nam es by
m erging t he Report sTo colum n values in t he second set w it h t he Em ployeeI D
values in t he first set . The First Nam e and Last Nam e colum n values for t he
m at ching records ar e t he m anager nam es. Manager nam es w ill r epeat for as
m any direct report s as t hey hav e. Therefore, adding a DI STI NCT pr edicat e t o t he
SELECT st at em ent rem oves t he duplicat es.
The sy nt ax for a self j oin is t he sam e as for an inner j oin. How ev er, t he sam e r ow
source appears on bot h sides of t he JOI N keyw ord. Wit h a self j oin, t he use of
aliases is m andat ory . I t is t hrough t he aliases t hat you designat e t he left and
right row sources. The follow ing sam ple shows t he T- SQL for finding t he
m anagers from t he Em ployees t able. Not ice t hat t he ex pr ession for t he ON
keyw ord m at ches t he Report sTo colum n values t o t he Em ploy eeI D colum n values.
The DI STI NCT pr edicat e aft er SELECT r em ov es t he m ult iple inst ances of m anager
nam es fr om t he r esult set .
--SelfJoin
--Self join to find managers in Employees table.
SELECT DISTINCT em.ReportsTo, e.FirstName, e.LastName
FROM Employees em JOIN Employees e
ON (em.ReportsTo = e.EmployeeID)

The cr oss j oin does hav e it s ow n key word phrase t o denot e it s j oin t ype. ( Not
surprisingly , t he keywor d phr ase is CROSS JOI N.) The sy nt ax is dist inct ive as
well. This is because t he FROM clause doesn’t need t he ON k ey word t o specify
colum ns for com par ing bet ween t he t wo r ow sources. A cross j oin aut om at ically
m erges all t he rows fr om one source w it h each row from t he ot her source; in
ot her words, it generat es one row for each possible pairing of rows fr om t he t wo
sources. That m eans it ’s im port ant t hat at least one of t he row sources hav e j ust
one row or very few rows. A cross j oin of t wo t ables w it h j ust 10,000 rows each
generat es a result set w it h 100,000,000 r ows! You can lim it t he size of t he r esult
set t hr ough WHERE clause argum ent s t hat r est rict t he rows part icipat ing in t he
cross j oin from eit her t he left or t he r ight row source.
The follow ing sam ple shows a sim ple cr oss j oin t hat m erges Com pany Nam e
colum n values fr om each row in t he Shippers t able w it h OrderI D colum n values
from t he Orders t able t hat are less t han or equal t o 10,249. Only t wo OrderI D
values m at ch t his condit ion, and t here ar e j ust t hr ee r ows in t he Shippers t able,
so t he r esult set for t he cross j oin cont ains only six r ows. The sy nt ax for t he cross
j oin appears below , and Figur e 3- 6 shows t he result set .
--CrossJoin
--Cross join selected rows from one table with all
--selected rows from a second table based on a
--WHERE clause.
SELECT OrderID, CompanyName
FROM Orders CROSS JOIN Shippers
WHERE OrderID <= 10249


  Figu r e 3 - 6 . Th e re su lt set fr om a cr oss j oin of Com pa n yN a m e fr om t h e
      Sh ipp er s t a ble w it h t w o Ord er I D va lu e s fr om t h e Or de r s t ab le .




Su bque r ie s

A subquer y is m erely a SELECT st at em ent nest ed in anot her SELECT st at em ent .
Som et im es t he SQL lit erat ure calls t he nest ed SELECT st at em ent t he inner query
and t he cont ainer for t he nest ed SELECT query t he out er query . You can nest
quer ies at m ore t han t w o levels, but t her e ar e m em ory and com plex it y lim it s for
parsing st at em ent s t hat you m ight incur before reaching t he specified lim it of 32
levels of nest ing. You can use m any of t he st andard SELECT st at em ent feat ur es in
a subquer y, but t here are som e r est rict ions; see “Subquery Fundam ent als” and
“Subquery Rules” in Books Online for t he det ails. This sect ion w ill illust rat e a
couple of appr oaches t hat do w ork.
Befor e div ing int o t he specifics of t he synt ax, it is im port ant t o underst and a
couple of point s about subqueries. First , for m ost SELECT st at em ent s t hat use a
subquery , t here’s alm ost always an alt er nat iv e t hat doesn’t r equir e a subquery.
Frequent ly a j oin w ill pr ov ide t he sam e funct ionalit y. I n any ev ent , SQL Ser ver
searches for t he fast est way t o execut e t he quer y no m at t er how you st at e t he
query . Second t her e are t wo basic kinds of subquer ies. The first of t hese is a
st and- alone SELECT st at em ent t hat execut es once inside anot her quer y. The
second subquery t ype is a SELECT st at em ent t hat SQL Serv er m ust execut e once
for each r ow in t he out er query. This t ype of inner quer y is k now n as a corr elat ed
subquery . A corr elat ed subquery can degrade perform ance if SQL Serv er cannot
find an alt er nat iv e t o com put ing t w o SELECT st at em ent s for each r ow in t he r ow
source for t he out er query.
The follow ing scr ipt illust rat es a subquery form ulat ion for finding t he nam es of
t he m anagers in t he Nort hw ind dat abase. The inner query finds t he Em ployeeI D
for t he t w o m anagers— but it doesn’t r et ur n t heir nam es. The out er query ret urns
t he First Nam e and Last Nam e colum n v alues for t he Em ploy eeI D values r et urned
by t he inner query.
--SubqueryForManagers
--Subquery to find managers in Employees table.
SELECT FirstName, LastName
FROM Employees
WHERE EmployeeID IN
      (SELECT DISTINCT ReportsTo FROM Employees)

The self j oin sam ple in t he pr eceding sect ion illust rat es an alt er nat iv e form ulat ion
for r et urning t he nam es of com pany m anagers. Because t he inner query ex ecut es
j ust once in t he form ulat ion in t his sect ion, t her e is no part icular disadv ant age t o
t he subquery form ulat ion. Also, t here is no perform ance penalt y w it h eit her
opt ion. Look at bot h designs, and consider which one m akes t he m ost sense t o
you.
The next sam ple dem onst rat es t he applicat ion of a corr elat ed subquery. The
out er SELECT st at em ent r et urns t he OrderI D colum n value as well as t he num ber
of line it em s and t he t ot al ext ended price for all orders w it h m ore t han four line
it em s. This out er query com put es t he ext ended price for each line and groups t he
line it em s for each order. The inner query com put es t he num ber of line it em s in
t he cur rent order for t he out er quer y, and t he out er query t ak es t his r esult and
com pares it w it h 4 t o det erm ine w het her it should include or exclude t he order .
As y ou can see, t he out er quer y m ust r ecom put e t he inner query for each r ow in
it s r esult set .
--CorrelatedSubquery
--Correlated subquery to filter on an aggregated column value.
SELECT OrderID, COUNT(OrderID) ’Line items’,
        ’$’ +
        CONVERT(varchar,CAST(SUM(Quantity*UnitPrice*(1-
Discount)) AS money),1)
FROM [Order Details] odout
WHERE (SELECT COUNT(OrderID) FROM [Order Details] odin
        WHERE odin.OrderID = odout.OrderID) > 4
GROUP BY OrderID
ORDER BY COUNT(OrderID)

Alt er nat ively, w e could r eplace t he inner query wit h a HAVI NG clause, as shown
in t he follow ing script . Cor relat ed subquer ies usually car ry a perform ance penalt y,
so you hav e t o evaluat e carefully whet her any benefit der ived fr om t he correlat ed
subquery is w ort h t he penalt y . When y ou ar e form ulat ing ad hoc quer ies for use a
lim it ed num ber of t im es, cor relat ed quer ies m ay m ak e sense if t he subquery
for m ulat ion is easier for you t o st at e t han ot her, m ore efficient , appr oaches.
--CorrelatedSubqueryWithHaving
--HAVING clause alternative to the preceding
--correlated subquery sample.
SELECT OrderID, COUNT(OrderID) ’Line items’,
    ’$’ +
        CONVERT(varchar,CAST(SUM(Quantity*UnitPrice*(1-
Discount)) AS money),1)
FROM [Order Details]
GROUP BY OrderID
HAVING COUNT(OrderID) > 4
ORDER BY COUNT(OrderID)
Cha pt e r 4 . Pr ogr a m m ing Vie w s a nd
St or e d Pr oce dur e s
The preceding chapt er int r oduced y ou t o program m ing dat a access wit h T- SQL.
This chapt er builds on and goes beyond t he int r oduct ion in t w o explicit ways:
First it int roduces v iews by descr ibing t heir uses wit h various t ypes of r ow
sources. Second it int r oduces you t o st ored procedur es by rev iew ing t heir uses
and t he st at em ent s for creat ing and alt ering t hem , and by focusing on t he use of
param et ers and local variables t hat are oft en found in st or ed pr ocedur es.
A view is a cont ainer for a single SELECT st at em ent . Your SQL Serv er applicat ions
can r efer t o t he v iew nam e as a short cut t o t he SELECT st at em ent w it hin t he
view. I n t his chapt er, y ou w ill lear n t he sy nt ax for creat ing and using v iews.
Special at t ent ion goes t o cr eat ing views for dat a on rem ot e serv ers and for dat a
in ot her dat abase form at s, such as Access and any ODBC dat a source.
St or ed pr ocedur es are com piled set s of T- SQL st at em ent s. Aft er int r oducing t he
synt ax for creat ing st or ed pr ocedures, t he chapt er drills dow n on t he sy nt ax for
m anipulat ing param et er s and ret ur n st at us values, pr ogram m ing t he insert ion
and delet ion of r ows as well as t he updat ing of colum n values in row sources, and
t he r et ur n of condit ional r esult set s fr om a st or ed procedure.
The resources for t his chapt er include a dat abase, Chapt er04, w it h com plet ed
versions of t he sam ple views and st or ed procedur es discussed as well as T- SQL
script s for creat ing t he views and st or ed procedur es from scrat ch. Unless
explicit ly st at ed, all script s should be r un fr om t he Chapt er04 dat abase. See t he
“Chapt er Resources” sect ion in Chapt er 2 for m or e det ail on at t aching dat abase
files t o a serv er and cr eat ing a new blank dat abase fr om w hich you can inv ok e
t he script s. The chapt er also r efer ences ot her com m only available dat abases,
including t he SQL Ser ver Nort hw ind dat abase, t he pubs dat abase, and t he Access
Nort hwind dat abase. The first t wo dat abases ar e inst alled w it h SQL Ser ver; t he
t hird dat abase is inst alled w it h Access. For t he references t o r em ot e serv ers, y ou
will need an inst ance of SQL Ser ver r unning on t wo different com put ers or t w o
inst ances of SQL Serv er r unning on t he sam e com put er .




I n t r odu ct ion t o View s
A SQL Serv er v iew is a virt ual t able. As w it h a t able, y ou can use a v iew in m any
way s, but unlik e a t able, a v iew doesn’t act ually st ore r ows of dat a. I nst ead, w hat
it st or es is a SELECT st at em ent , such as one of t hose cover ed in Chapt er 2. The
result set of t he SELECT st at em ent const it ut es t he dat a available t hr ough a v iew .
The FROM clause of t he view’s SELECT st at em ent can r efer ence ot her v iews as
well as base t ables.

Use s for Vie w s

You can use v iews as a way of insulat ing users from t he dat abase design in t he
schem a of a cust om applicat ion. This benefit m akes y our applicat ions m or e robust
in t he face of ongoing r equirem ent s t o updat e schem a designs. The
I NFORMATI ON_SCHEMA views discussed in sev eral sect ions t hroughout Chapt er 2
illust rat e t his use for v iews. This appr oach t o ex posing dat a perm it s your cust om
solut ions t o change an applicat ion’s schem a but st ill prov ide t he sam e inform at ion
t o t he end users of an applicat ion. All y ou need is t o updat e t he view so t hat it
select s t he sam e dat a as before t he schem a change.
You also can use v iews t o secure eit her t he r ows or t he colum ns from a base
t able. Wit h t he SELECT list and t he WHERE clause for a v iew’s SELECT st at em ent ,
you can filt er dat a from a base t able. I n ot her w ords, a v iew perm it s you t o
expose a subset of a row source. For exam ple, you could base a Visual Basic .Net
applicat ion on a v iew inst ead of a t able if y ou want ed t o rest r ict t he access of t he
applicat ion users t o j ust rows t hat m at ch t he cr it eria in t he WHERE clause. This
approach “secures” t he rows filt er ed out of t he view. I nst ead of filt er ing rows wit h
a WHERE clause, y ou can exclude select ed colum ns w it h sensit iv e dat a from a
SELECT list , such as colum ns for salary and bonus. Again, by excluding dat a, y ou
“secur e” t he dat a from t hose w it hout aut hor it y t o v iew it .
A view is part icular ly valuable for com bining t he dat a for t w o or m ore base t ables
int o a single r ow source. The various j oin clauses enable t his capabilit y very
flex ibly. You can also use a UNI ON operat or t o com bine t he dat a from t wo or
m or e t ables. A UNI ON operat or cont rast s wit h j oin clauses by concat enat ing one
row source aft er anot her. Join clauses st it ch r ow sources t oget her side by side.

                                     N ot e
See “Com bining Result s w it h UNI ON” in Books Online as a
st ar t ing point for m ore coverage of UNI ON queries.
Using t he OPENROWSET funct ion allows access t o rem ot e, het erogeneous dat a
sources t hrough a v iew. This funct ion perm it s you t o access non- SQL Ser ver dat a
from SQL Ser ver v iews. I n addit ion, you can ret ur n dat a and ev en j oin dat a fr om
ot her com put ers. The OPENROWSET funct ion depends on an OLE DB prov ider for
connect ing t o a dat a source; t he prov ider det er m ines t he t ype of funct ionalit y
available from t he source. This funct ion is part icularly appr opr iat e for ad hoc
quer ies. The OPENROWSET funct ion w or ks wit h what ev er user nam e and
password your applicat ion supplies it .
Alt er nat ives t o t he OPENROWSET funct ion include t he OPENDATASOURCE
funct ion and link ed serv ers. Books Online r ecom m ends link ed ser vers for
fr equent ly used connect ions t o dat a sources out side t he scope of t he act iv e SQL
Ser ver inst ance. ( See t he “Rem ar ks” sect ion of t he “ OPENDATASOURCE” t opic.)
Adm inist er ing a link ed ser ver requir es a login t hat belongs t o t he sysadm in or
set upadm in fix ed server role.
Anot her purpose for a v iew is t he represent at ion of aggr egat ions fr om a base
t able. A view can count or sum colum n values in a base t able ov er all or by
groups. This capabilit y of present ing dat a sum m aries confirm s a v iew as a -
decision- support t ool. Because views encapsulat e SELECT st at em ent s for r euse,
you can add new v iews t o a dat abase based on T- SQL quer ies dev eloped by, or in
coordinat ion w it h, t he end users of an applicat ion. This feat ure m ak es views
desirable for ex t ending t he funct ionalit y of applicat ions in ways t hat you know
hav e user appeal.
I t is im port ant t hat you grasp t he not ion of a v iew as a virt ual t able because t his
conv eys som e pow erful clues about t he needs t hey can fulfill in a cust om solut ion.
Your applicat ions can insert , updat e, and delet e dat a t hrough a view . These
capabilit ies depend on t he char act er ist ics of t he v iew . For exam ple, you can
perform insert / updat e/ delet e funct ions for v iews of a single base t able but not for
views t hat expose aggregat es of a base t able. The “ Rem ar ks” sect ion of t he
“CREATE VI EW” t opic in Books Online det ails r ules for t he m odificat ion of t he row
source behind a v iew.
You can index views t o speed t heir perform ance— j ust as y ou can w it h t ables.
I ndexed v iews deliv er benefit s w hen you’re w ork ing w it h v ery large t ables. See
t he “Creat ing an I ndexed View” t opic in Books Online for a st art ing point for
lear ning m ore about index ed v iews.
Part it ioned v iews repr esent a m eans of segm ent ing a t able over m ult iple
com put ers each r unning SQL Serv er ; you aggregat e t he part it ions of a v iew wit h
UNI ON operat ors. Thr ough part it ioned v iews, a view on each serv er w it h a
segm ent can browse, add, updat e, and delet e r ows in t he w hole t able ( across all
serv ers) . Part it ioned v iews are a r obust way of wor k ing w it h very large
dat abases. See t he “Cr eat ing a Part it ioned View ” t opic in Books Online for help
wit h pr eparing part it ioned v iews.

St a t e m e nt s for Cr e a t in g a nd Alt e r ing Vie w s

You can generat e and m odify v iews w it h t he T- SQL CREATE VI EW and ALTER
VI EW st at em ent s. I n it s m ost basic form , a CREATE VI EW st at em ent specifies a
nam e for t he v iew and a SELECT st at em ent t o designat e it s r esult set . Posit ion
t he v iew’s nam e aft er a space delim it er follow ing t he CREATE VI EW key word
phrase. Then use t he AS keyword t o separ at e t he v iew’s nam e fr om it s SELECT
st at em ent . For exam ple, y ou can cr eat e a new view wit h t his synt ax :
CREATE VIEW
view_name

AS
SELECT
list_of_columns

FROM
base_table_name


View nam es are st andar d SQL Serv er ident ifiers. Ther efor e, t hey m ust follow t he
rules for all obj ect ident ifiers. Refer t o t he “Using I dent ifiers” t opic in Books
Online for a sum m ary of t he rules for specify ing ident ifiers. I n addit ion, user -
defined v iews are obj ect s like ot her syst em and user - defined SQL Serv er obj ect s.
Because SQL Serv er obj ect s share a com m on nam espace, y ou m ay car e t o use
prefixes t o r eflect t he t y pe of obj ect and avoid nam e conflict s. For exam ple, t his
chapt er uses t he vew pr efix for all user- defined views.
Just as wit h t ables and ot her dat abase obj ect s, you cannot creat e a new v iew
wit h t he sam e nam e as an ex ist ing v iew. You m ust r em ov e t he pr ior v ersion of
t he v iew before creat ing a new v iew w it h t he sam e nam e as an ex ist ing one in a
dat abase. The DROP VI EW st at em ent support s t he r em oval of an ex ist ing v iew. A
couple of I NFORMATI ON_SCHEMA v iews r et ur n t he nam es of t he v iews in a
dat abase. This chapt er dem onst rat es t he use of t hese v iews.
You can inv ok e t he ALTER VI EW st at em ent t o change an ex ist ing v iew wit hout
delet ing it t ot ally. The ALTER VI EW st at em ent preserv es perm issions set on a
view and doesn’t alt er t he dependency of an I NSTEAD OF t r igger or a st or ed
procedur e on a view.

Re st r ict ions on SELECT St a t e m e n t s f or Vie w s

While y ou do have access t o m ost of t he SELECT st at em ent funct ionalit y, t here
are som e design lim it at ions as w ell as som e differ ences in behav ior for SELECT
st at em ent s in v iews. For exam ple, a SELECT st at em ent in a v iew cannot cont ain a
COMPUTE or COMPUTE BY clause because eit her clause can r et ur n m ult iple r esult
set s. Views m ust always r et urn a single r esult set . I n t his way, a v iew em ulat es a
t able. The single r esult set fr om a v iew can ser ve as a t able in m any ot her T- SQL
st at em ent s.
You cannot use an ORDER BY clause by it self in t he SELECT st at em ent for a v iew.
The Books Online docum ent at ion at sev eral point s m akes t his assert ion wit hout
bot her ing t o not e an im port ant case t hat perm it s t he use of an ORDER BY clause
inside t he SELECT st at em ent for a v iew. I n t his special case, y ou use t he TOP
predicat e inside t he SELECT st at em ent . Subsequent sam ples will dem onst rat e t he
synt ax for t his.
The WI TH CHECK OPTI ON clause is a special clause t hat applies t o SELECT
st at em ent s inside v iews. This clause can rest r ict a user’s abilit y t o insert new
records t hrough a view or m odify t he values in t he r esult set t hat a view exposes.
The WI TH CHECK OPTI ON clause r equir es t hat all m odificat ions t o t he r ow source
for a v iew com ply w it h crit er ia st at em ent s in t he SELECT st at em ent for a v iew .

Vie w At t r ibut e s

Three v iew at t r ibut es help t o r efine t he funct ionalit y t hat a v iew prov ides. A
view’s at t ribut e specificat ion can appear follow ing it s nam e in a CREATE VI EW or
ALTER VI EW st at em ent . Use WI TH as a k eyw ord befor e t he at t r ibut e nam e.
Using t he ENCRYPTI ON at t ribut e encrypt s t he SELECT st at em ent for t he v iew.
Users get t he sam e result set for an encrypt ed or unencr ypt ed view , but t he
encr ypt ed v iew prot ect s t he T- SQL st at em ent for t he v iew . I f y ou need t o m odify
a v iew in t he fut ur e, save out side t he dat abase an unencrypt ed v ersion of t he
view’s CREATE VI EW st at em ent . You can do t his wit h Quer y Analyzer by saving
t he unencry pt ed T- SQL st at em ent t hat was used for cr eat ing t he encr y pt ed v iew.
The SCHEMABI NDI NG v iew at t r ibut e int egrat es a v iew w it h it s row sour ces so
t hat y ou cannot r em ove or change a r ow source for a v iew in a way t hat will
m odify t he r esult set . To specify t he SCHEMABI NDI NG at t r ibut e for a view, you
m ust designat e all underly ing r ow sources for t he v iew w it h a t w o- part nam ing
conv ent ion t hat designat es t he owner nam e and t he nam e for t he r ow source. I f
you cr eat e index es for a view, y ou m ust also designat e t he SCHEMABI NDI NG
at t ribut e for t he v iew.

                                      N ot e
The SELECT st at em ent for a v iew wit h SCHEMABI NDI NG
cannot include a SELECT list wit h * in it if it is an index ed
view.
The VI EW_METADATA at t ribut e is t he t hird at t r ibut e for a v iew. Specify t his
at t ribut e for v iews t hat are int ended for use w it h SQL Ser ver 2000 Met a Dat a
Ser vices. You can invok e t hese serv ices fr om eit her Ent erpr ise Manager or a
special st and- alone Micr osoft Managem ent Console snap- in. Met a Dat a Ser vices is
a specialized t opic out side t he scope of t his book . See t he “ Met a Dat a Ser vices
Ov erv iew” t opic in Book s Online for an int r oduct ion t o t he uses for Met a Dat a
Ser vices.




Cr e a t in g a n d Usin g View s
As explained ear lier , creat ing a v iew perm it s y ou t o expose a subset of a row
source t hrough t he v iew. The SELECT st at em ent for a v iew det erm ines t he subset
t hat a v iew r et urns. Nest ing a SELECT st at em ent in a CREATE VI EW st at em ent
generat es a new v iew w it h a result set det erm ined by t he SELECT st at em ent . This
sect ion illust rat es t ypical sy nt ax conv ent ions for t he CREATE VI EW st at em ent . I t
also present s som e special r equirem ent s for SELECT st at em ent s nest ed in
CREATE VI EW st at em ent s.

Cr e a t in g a n d Se le ct ing f r om a Vie w
To cr eat e a v iew, y ou m ust hav e an init ial r ow source. This row source can reside
in t he current dat abase or in anot her dat abase t o w hich y our v iew can connect .
The m ost st raight forwar d solut ion is t o use a r ow source in t he curr ent dat abase.
The follow ing scr ipt creat es a r ow source as a t able nam ed Em ailCont act s in t he
dat abase for t his chapt er and t hen populat es t he t able w it h a couple of rows.
Next , aft er dropping t he view if it already ex ist s, t he script cr eat es a v iew based
on t he t able. Finally, a SELECT st at em ent pr ov ides a r esult set based on t he v iew.
The port ion of t he script creat ing and populat ing t he t able is excerpt ed from
Chapt er 2 w it h a m inor adapt at ion for it s use in t he dat abase for t his chapt er.
Aft er t he I NSERT I NTO st at em ent s, t he script displays new code specific t o v iews.
Befor e inv ok ing t he CREATE VI EW st at em ent , t he script uses t he
I NFORMATI ON_SCHEMA.VI EWS v iew t o v er ify w het her a v iew already exist s wit h
t he nam e for t he new v iew. I f t he v iew does ex ist , t he script dr ops t he prior
version. You can also use t he I NFORMATI ON_SCHEMA.TABLES v iew for t he sam e
purpose.
Aft er ensuring t hat t he nam e for t he new v iew won’t conflict wit h an ex ist ing one,
t he script invokes t he CREATE VI EW st at em ent . This st at em ent dem onst rat es t he
synt ax for nam ing a v iew. Not ice t he vew pr efix . While t his pr efix isn’t st rict ly
necessary , r ecall t hat nam es for views and t ables occupy t he sam e nam espace.
Ther efor e, y ou m ust specify a view ’s nam e dist inct ly fr om a t able serv ing as t he
view’s row source. Because t he Em ailCont act s t able r esides in t he sam e dat abase
as t he view and it s ow ner is t he dbo user, you can use a one- part nam e t hat
sim ply refer ences t he t able’s nam e in t he FROM clause of t he v iew ’s SELECT
st at em ent . Aft er t he creat ion of t he v iew, t he script inv ok es a new SELECT
st at em ent t o ret ur n t he view’s result set . Not ice t hat t he FROM clause in t he
concluding SELECT st at em ent refers t o t he v iew’s nam e, vewEm ailCont act s.
--CreatevewEmailContacts
USE Chapter04
GO

--Remove prior version of EmailContacts if it exists.
IF EXISTS
    (
    SELECT *
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = ’EmailContacts’
    )
DROP TABLE EmailContacts

--Create EmailContacts with three columns.
CREATE TABLE EmailContacts
(
ContactID int Not Null PRIMARY KEY,
FirstName nvarchar(20) NULL,
LastName nvarchar(35) NULL,
Email1 nvarchar (255) NULL
)
GO

--Populate EmailContacts.
INSERT INTO EmailContacts
    VALUES(1,’Rick’, ’Dobson’, ’rickd@cabinc.net’)
INSERT INTO EmailContacts
    VALUES(2,’Virginia’, ’Dobson’, ’virginia@cabinc.net’)
GO

--Drop prior version of view if it exists.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
        WHERE TABLE_NAME = ’vewEmailContacts’)
     DROP VIEW vewEmailContacts
GO

--Create view to select all columns for
--all rows from the EmailContacts table.
CREATE VIEW vewEmailContacts
AS
SELECT *
FROM EmailContacts
GO

--Select all columns for all rows from
--the vewEmailContacts view.
SELECT *
FROM vewEmailContacts


Con t r a st ing Un e n cr ypt e d a n d Encr ypt e d Vie w s

Wit h m inor ext ensions, t he preceding sam ple can serv e as a t em plat e for t he
creat ion of any v iew. The following script illust rat es one of t hese ext ensions. I t
creat es a view in t he Chapt er04 dat abase t hat has t he Shippers t able in t he
Nort hwind dat abase as it s base t able. While t he row source for a v iew can reside
in anot her dat abase, t he CREATE VI EW st at em ent can creat e a v iew only in t he
curr ent dat abase. Sim ilarly, t he DROP VI EW st at em ent can r em ove a view only
from t he cur rent dat abase.
An easy way t o r efer ence a row source fr om anot her SQL Serv er dat abase is t o
use a t hree- part nam e. The first part refers t o t he alt ernat e dat abase nam e,
Nort hwind in t his case. The second part designat es t he owner of t he obj ect
prov iding t he row source. When t he row source ow ner is t he default dbo user,
you can om it it s ex plicit designat ion ( as in t he follow ing script ) . The t hird nam e
part denot es t he nam e of t he dat abase obj ect prov iding t he r ow source for a
view. Figure 4- 1 shows t he r esult set from t he SELECT st at em ent based on t he
vew Shippers v iew. Not ice t hat it m at ches t he values in t he Nort hwind..Shippers
t able, which is t he source for t he v ew Shippers v iew.
Not ice t hat unlik e t he fir st code sam ple, t his one doesn’t include a specific
reference t o t he Chapt er04 dat abase. That ’s because Query Analyzer w ill cont inue
t o use Chapt er04 unt il y ou specify a different dat abase wit h a new USE
st at em ent .
--CreatevewShippers
--Search for, and remove if found, the
--vewShippers view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
       WHERE TABLE_NAME = ’vewShippers’)
       DROP VIEW vewShippers
GO

--Create a new version of the vewShippers
--view in the Chapter04 database from the
--Shippers table in the Northwind database.
CREATE VIEW vewShippers
AS
SELECT *
FROM Northwind..Shippers
GO

--Select all rows and columns from the
--vewShippers view in Chapter04.
SELECT * FROM vewShippers
Figu re 4 - 1 . Th e r e su lt se t from a vie w ba se d on t h e Sh ip pe rs t a ble in t h e
                                    N or t h w in d da t ab ase .




The ENCRYPTI ON at t r ibut e isn’t set by default . Set t ing encrypt ion doesn’t change
t he r esult set from a SELECT st at em ent . I nst ead, it encodes t he T- SQL for a
view’s definit ion. You can v erify t his by t r y ing t o display t he script for a view. The
VI EW_DEFI NI TI ON colum n for t he I NFORMATI ON_SCHEMA.VI EWS v iew r et urns
t he script for a v iew on each of it s r ows.
The follow ing scr ipt dem onst rat es t he synt ax for inv ok ing t he ENCRYPTI ON
at t ribut e. The script also dem onst rat es t he sy nt ax for ret urning t he script t hat
defines a view . This script includes all com m ent s as well as t he operat ional T- SQL
st at em ent s for creat ing t he v iew; t hese st at em ent s include t he CREATE VI EW
st at em ent for generat ing a new v iew and t he SELECT st at em ent for defining a
view’s result set . I n t his case, t he SELECT st at em ent is ident ical t o t he one in t he
preceding v iew. How ev er, t he CREATE VI EW st at em ent includes t he WI TH
ENCRYPTI ON clause t hat encodes t he T- SQL for t he v iew. Aft er cr eat ing t he v iew,
t he script perfor m s a sim ple SELECT quer y t o v er ify t he cont ent s of t he view ’s
result set . The final port ion of t he script creat es anot her r esult set w it h t he
definit ion for each user- defined v iew in t he curr ent dat abase, w hich is Chapt er04
in t he sam ple. Om it t ing all rows beginning w it h “sys” for t heir TABLE_NAME
colum n value in t he I NFORMATI ON_SCHEMA.VI EWS v iew excludes all sy st em
views from t he final result set .
--CreatevewShippersEncrypted
--Search for, and remove if found, the
--vewShippersEncrypted view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
            WHERE TABLE_NAME = ’vewShippersEncrypted’)
        DROP VIEW vewShippersEncrypted
GO

--Create a new version of the vewShippersEncrypted
--view in the Chapter04 database from the
--Shippers table in the Northwind database.
CREATE VIEW vewShippersEncrypted
WITH ENCRYPTION
AS
SELECT *
FROM Northwind..Shippers
GO

--Select all rows and columns from the
--vewShippersEncrypted view in Chapter04.
SELECT * FROM vewShippersEncrypted

--List user-defined view names in Chapter04 database
--along with their scripts.
SELECT TABLE_NAME, VIEW_DEFINITION
FROM INFORMATION_SCHEMA.VIEWS
WHERE LEFT(TABLE_NAME,3) <> ’sys’
Figur e 4- 2 shows an ex cerpt from t he result set s for t he pr eceding script s. This
excerpt is from t he Result s pane of Query Analy zer w it h a Result s To Grids
set t ing. The t op r esult set shows t he sam e t hree rows as in Figure 4- 1. This
confirm s t hat encr ypt ing a v iew doesn’t alt er t he result fr om it s SELECT
st at em ent . The second result set in Figur e 4- 2 displays t he nam es of t he t hree
views creat ed t o t his point in t he chapt er . Next t o each v iew nam e is t he
beginning of t he script for t he v iew. Because t he script s st art w it h com m ent s, t he
VI EW_DEFI NI TI ON colum n values st art w it h t hese com m ent s. Wit h a Result s To
Text set t ing for t he Result s pane, y ou can exam ine t he w hole script for each v iew
except v ew ShippersEncr ypt ed. The WI TH ENCRYPTI ON clause in t he CREATE
VI EW st at em ent for t his view secur es it s script so t hat t he VI EW_DEFI NI TI ON
colum n of t he I NFORMATI ON_SCHEMA.VI EWS v iew cannot expose t he T- SQL t hat
generat es t he view .

Figu re 4 - 2 . An e xce r pt sh ow in g t h e re su lt set fr om a n e n cr yp t e d vie w a s
           w e ll as t h e VI EW _ D EFI N I TI ON colu m n va lu es fr om t h e
   I N FORM ATI ON _ SCH EM A.V I EW S vie w for t h re e vie w s in a d at a ba se .




Sor t in g a n d Gr oupin g W it h in a V ie w

The SELECT st at em ent t hat defines a v iew has generally t he sam e synt ax as t hat
wit hin a st and- alone script . For exam ple, gr ouping rows t o aggr egat e a colum n
value w or ks t he sam e in bot h st and- alone script s and t hose inside v iew s.
Sim ilar ly , t he I N keyword in a WHERE clause w ork s t he sam e as well.
I n cont rast , t he ORDER BY clause in a SELECT st at em ent requir es slight ly
different sy nt ax inside a view t han it does out side a view . I n part icular, ORDER
BY inside a v iew requir es t he TOP pr edicat e aft er t he SELECT k eyw ord. The TOP
predicat e, in t urn, r equires an argum ent t o designat e how m any r ecords t o
ret ur n. I f you want all t he rows from a source, follow TOP w it h 100 PERCENT. You
can designat e any ot her percent age as w ell as a num ber for any num ber of rows.
Trailing TOP w it h t he num ber 10 w it hout t he PERCENT k eyw ord ret ur ns t he first
10 rows in t he r esult set . When you use an ORDER BY clause, t hose r ows will be
t he highest or low est colum n values on a sort dim ension depending on t he sort
order . The synt ax for designat ing a sort order in an ORDER BY clause is t he sam e
in a SELECT st at em ent in or out of a v iew.
The follow ing scr ipt shows t he cr eat ion and r et urn of values from a v iew t hat
groups and sort s colum n values. The SELECT st at em ent for t he v iew also includes
a crit er ion t hat filt ers ex clusively for count r ies beginning wit h t he let t er B or C.
Chapt er 3 included a sim ilar st and- alone script for count ing t he num ber of
cust om ers by cit y w it hin count r y. The SELECT st at em ent in t he follow ing script is
dist inct because of it s use of t he TOP pr edicat e. While t he TOP predicat e w ill w or k
in a st and- alone scr ipt , it isn’t necessary.
--CreatevewCustomersInCountryCity
--Search for, and remove if found, the
--vewCustomersInCountryCity view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
            WHERE TABLE_NAME = ’vewCustomersInCountryCity’)
     DROP VIEW vewCustomersInCountryCity
GO

--Create a new version of the vewCustomersInCountryCity
--view in the Chapter04 database.
--To use ORDER BY clause in view you need TOP predicate
--with modifier of 100 PERCENT.
CREATE VIEW vewCustomersInCountryCity
AS
SELECT TOP 100 PERCENT Country, City,
    Count(CustomerID) ’# of Customers’
FROM Northwind..Customers
WHERE LEFT(Country,1) IN (‘B’,’C’)
GROUP BY Country, City
ORDER BY Country, City
GO

--Select all rows and columns from the
--vewCustomersInCountryCity view in Chapter04.
SELECT * FROM vewCustomersInCountryCity




Vie w s for Re m ot e a n d H e t er oge n e ou s Sou r ce s
I t is oft en necessary t o view dat a r esiding on anot her SQL Serv er inst ance or
ev en in anot her t ype of dat abase form at . T- SQL prov ides sev er al appr oaches t o
sat isfying t hese k inds of r equirem ent s. The OPENROWSET funct ion is a flex ible
approach because it can accom m odat e ad hoc quer ies as w ell as t hose perform ed
on a regular basis. As m ent ioned prev iously, Books Online r ecom m ends t hat y ou
use link ed ser vers w hen it is necessary t o query a r em ot e or het er ogeneous
source on a regular basis. Howev er, you can inv ok e t he OPENROWSET funct ion
for a user id t hat doesn’t hav e m em bership in t he sysadm in or set upadm in fix ed
serv er r oles. The OPENROWSET funct ion depends only on t he perm issions for t he
user id passed t o t he ot her dat a source. This sect ion present s a ser ies of
OPENROWSET sam ples designed t o help you underst and r em ot e dat a access.

Cr e a t in g a Vie w f or An ot he r SQL Se r ve r I n st a n ce

One t ypical requir em ent is t o v iew a SQL Serv er row source, such as a t able, on
anot her serv er. You can use t he OPENROWSET funct ion t o perform t his t ask, wit h
argum ent s t hat specify a prov ider, ot her elem ent s of a connect ion st ring, and a
SELECT st at em ent . The OPENROWSET funct ion can serv e as an argum ent for t he
FROM clause of a SELECT st at em ent . This out er SELECT st at em ent , in t urn, m ust
reside in a CREATE VI EW st at em ent w hen y our goal is t o cr eat e a v iew in t he
curr ent dat abase t hat exposes a row source in anot her dat abase.
When t he inner SELECT st at em ent — t he one in t he call t o t he OPENROWSET
funct ion— point s at anot her SQL Serv er inst ance, t he prov ider for t he funct ion
should be SQLOLEDB. Next y ou can denot e t he rem aining elem ent s of t he
connect ion st r ing for t he ot her ser ver in t he follow ing order : t he ser ver inst ance
nam e, a SQL Serv er login for t he serv er , and a password for t he login. Follow t he
prov ider nam e by a com m a, but use a sem icolon for a delim it er aft er t he ser ver
nam e and login nam e. A com m a separat es t he password fr om t he SELECT
st at em ent .
The follow ing scr ipt creat es a v iew on one SQL Ser ver running SQL Server 2000
t hat point s at a t able on t he cabxli ser ver running t he MSDE v ersion com pat ible
wit h SQL Ser ver 7. You need t w o inst ances of SQL Ser ver t o evaluat e t his script ,
but y ou can nam e t he inst ances anyt hing y ou want . Just change t he r eferences t o
cabxli t o t he nam e of a SQL Ser ver inst ance t o which you can connect . By t he
way , t he t able is t he aut hors t able in t he pubs dat abase; MSDE doesn’t rout inely
inst all w it h t he pubs dat abase. Because cabx li is an int er nal t est serv er running
Windows 98, t he serv er is available w it h sa and an em pt y password. Pr oduct ion
serv ers should always have a password for t he sa login if you ar en’t for cing
Windows aut hent icat ion. The SELECT st at em ent r efer ences t he aut hors t able in
t he pubs dat abase on t he cabx li ser ver. The ORDER BY clause along wit h t he TOP
predicat e sort s t he result set by aut hor first nam e w it hin aut hor last nam e.
The out er SELECT st at em ent t ak es t he OPENROWSET funct ion as t he ar gum ent
for it s FROM clause. The SELECT list for t he out er SELECT st at em ent list s t he
aut hors by first nam e, last nam e, and phone num ber, in t hat order.
--CreatevewAuthorsSortedOnCabxli
--Search for, and remove if found, the
--vewAuthorsSortedOnCabxli view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
              WHERE TABLE_NAME = ’vewAuthorsSortedOnCabxli’)
       DROP VIEW vewAuthorsSortedOnCabxli
GO

--Create a new version of the vewAuthorsSortedOnCabxli
--view in the Chapter04 database from the
--Shippers table in the Northwind database.
CREATE VIEW vewAuthorsSortedOnCabxli
AS
SELECT au_fname, au_lname, phone
FROM OPENROWSET(‘SQLOLEDB’,’cabxli’;’sa’;’’,
    ’SELECT TOP 100 PERCENT * FROM pubs..authors ORDER BY au_lname, a
u_fname’)
GO

--Select all rows and columns from the
--vewAuthorsSortedOnCabxli view in Chapter04.
SELECT * FROM vewAuthorsSortedOnCabxli
GO



Cr e a t in g a Vie w f or a n Acce ss D a t a ba se

I t isn’t uncom m on t o need t o upgrade Access applicat ions for t he use of an
Access dat abase via a SQL Ser ver solut ion. While y ou can perform a full- scale
upsizing, it is possible t hat t he OPENROWSET funct ion can dram at ically r educe
t he effort of w ork ing w it h Access dat a from SQL Ser ver. That ’s because t he
funct ion perm it s a SQL Ser ver solut ion t o v iew Access dat a wit hout t he need of
t ransport ing t he dat a from Access t o SQL Serv er. Ther efore, y ou save t he
conv ersion effort . I n addit ion, your client s av oid t he disrupt ion t hat could ar ise if
t heir fam iliar Access solut ion wer e unavailable because y ou replaced it wit h a SQL
Ser ver applicat ion. At t he sam e t im e, new applicat ions can expose dat a from t he
Access dat abase. So long as you don’t expect t o exper ience bot t lenecks relat ed t o
t he capacit y of t he Access dat abase, t his appr oach bears considerat ion. I n any
ev ent , t he approach support s t he easy av ailabilit y of Access dat a from SQL
Ser ver v iews.
You can use an OPENROWSET funct ion t o connect wit h an Access dat abase m uch
lik e y ou use t he funct ion t o connect w it h a SQL Ser ver dat abase on anot her SQL
Ser ver inst ance. The OPENROWSET funct ion is t he argum ent for t he FROM clause
of a SELECT st at em ent . When connect ing t o an Access dat abase, you m ust
specify t he Jet dat a provider followed by t he pat h t o t he Access dat abase file, a
login nam e, and a password. The OPENROWSET funct ion also has it s own SELECT
st at em ent t hat specifies t he r ow source in t he Access dat abase as well as any
special set t ings, such as a WHERE clause.
The follow ing scr ipt dem onst rat es a connect ion t o an Access dat abase file on t he
current com put er. The pat h point s t o t he default inst allat ion of t he Nor t hw ind
sam ple dat abase for Access 2002. The connect ion st ring specifies a login by t he
adm in user w it h an em pt y password. This is norm al for an unsecur ed Access
dat abase file, such as t he Access Nort hw ind sam ple. The SELECT st at em ent inside
t he OPENROWSET funct ion call designat es t he r et ur n of all rows w it h a Count ry
colum n value of USA. When designat ing a st ring in t his inst ance, t he norm al
synt ax is t o enclose t he st ring argum ent , USA, wit h a pair of single quot at ion
m arks. How ev er, w it hin t he OPENROWSET funct ion, single quot at ion m arks ar e
alr eady used around t he SELECT st at em ent , so it ’s necessary t o use t w o single
quot at ion m arks on each side of USA. I n t he follow ing script , t he out er SELECT
st at em ent displays all t he colum ns from t he inner SELECT st at em ent .
--CreatevewUSACustomersFromAccess
--Search for, and remove if found, the
--vewUSACustomersFromAccess view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
           WHERE TABLE_NAME = ’vewUSACustomersFromAccess’)
       DROP VIEW vewUSACustomersFromAccess
GO

--Create a new version of the vewUSACustomersFromAccess
--view in the Chapter04 database from the Customers table
--in the Access Northwind database. (You should install the
--Northwind sample if it isn’t already installed. Also, you
--may need to change the path to Northwind.)
CREATE VIEW vewUSACustomersFromAccess
AS
SELECT *
FROM OPENROWSET(
    ’Microsoft.Jet.OLEDB.4.0’,
    ’c:\Program Files\Microsoft Office\Office10\Samples\Northwind.mdb
’;
    ’admin’;’’,
    ’SELECT * FROM Customers WHERE Country=‘‘USA’’’)
GO

--Select all rows and columns from the
--vewUSACustomersFromAccess view in Chapter04.
SELECT * FROM vewUSACustomersFromAccess
GO



Cr e a t in g a Vie w f or a n OD BC Row Sou r ce

View ing an ODBC dat a source m ay be t he ult im at e in flex ibilit y because ODBC
drivers are available for so m any different t ypes of dat abases. I n addit ion, t he
MSDASQL prov ider, w hich is inst alled w it h Micr osoft Dat a Access Com ponent s,
offers a st andard int erface t o ODBC dat a sources. The OPENROWSET funct ion
t hr ough it s SELECT st at em ent let s your applicat ions choose a specific row source
wit hin a dat a source or ev en filt er a r ow source t o der iv e a new cust om source for
an applicat ion.
Using t he OPENROWSET funct ion t o connect w it h a row source in an ODBC dat a
source bears a st rong r esem blance t o using t he funct ion t o connect w it h SQL
Ser ver and Jet r ow sour ces. The m ain differences ar e in t he connect ion st ring
specificat ions. First y ou m ust designat e t he MSDASQL prov ider inst ead of t he
SQLOLEDB or Jet prov ider . Second you specify connect ion st ring elem ent s t hat
are appr opr iat e for t he dat a source t o which y ou want t o connect .
The follow ing scr ipt shows t he sy nt ax for an applicat ion of t he OPENROWSET
funct ion wit h t he MSDASQL prov ider for an ODBC dat a source. I n fact , t he sam ple
connect s t o a SQL Serv er dat a source wit h t he ODBC dr iv er, but t he general
synt ax issues ar e t he sam e as for any dat a source. This sam ple requir es t wo
inst ances of SQL Serv er . For exam ple, t he connect ion st r ing elem ent s point t o t he
cab2000 server running a SQL Serv er dat abase. You can r eplace t he r efer ence t o
cab2000 wit h t he nam e of any ot her inst ance of SQL Serv er on y our net wor k. The
user id and password ar e, respect iv ely, sa and password. The inner SELECT
st at em ent for t he OPENROWSET funct ion chooses all t he rows from t he Orders
t able in t he Nort hw ind dat abase whose OrderDat e is in 1998. A WHERE clause
and a DATEPART funct ion part icipat e in t he designat ion of an appropr iat e cr it er ion
for t he SELECT st at em ent . The out er SELECT st at em ent ret ur ns all colum ns fr om
t he Orders t able.
--Createvew1998OrdersOnCab2000
--Search for, and remove if found, the
--vew1998OrdersOnCab2000 view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
             WHERE TABLE_NAME = ’vew1998OrdersOnCab2000’)
       DROP VIEW vew1998OrdersOnCab2000
GO

--Create a new version of the vew1998OrdersOnCab2000
--view in the Chapter04 database from the Orders table
--in the Northwind database on the Cab2000 server.
CREATE VIEW vew1998OrdersOnCab2000
AS
SELECT *
FROM OPENROWSET(‘MSDASQL’,
    ’DRIVER={SQL Server};SERVER=cab2000;UID=sa;PWD=password’,
    ’SELECT *
    FROM Northwind..Orders
    WHERE DATEPART(yyyy, OrderDate) = 1998’)
GO

--Select all rows and columns from the
--vew1998OrdersOnCab2000 view in Chapter04.
SELECT * FROM vew1998OrdersOnCab2000



Join ing Row Sou r ce s for a Vie w

The value of being able t o pr ocess rem ot e and het erogeneous dat a sources
m ult iplies when y ou can j oin t wo r ow sources fr om different serv ers or different
dat abases. Ther e are at least t wo approaches t o t his t ask. The first one is t o
creat e a SELECT st at em ent t hat cont ains a JOI N operat or. I n t his appr oach, each
side of t he j oin has it s own explicit OPENROWSET funct ion. The ot her approach is
t o creat e t w o new v iews, each based on it s ow n OPENROWSET funct ion. Then y ou
can creat e a new, t hird, view t hat j oins t he t wo views. Eit her appr oach em pow ers
an applicat ion t o process concurrent ly r ow sour ces from differ ent dat abase
serv ers in differ ent dat abase form at s!
The follow ing scr ipt shows t he sy nt ax for t he fir st approach. Lik e sev er al of t he
prev ious OPENROWSET funct ion sam ples, t his one r equir es t wo inst ances of SQL
Ser ver. The scr ipt j oins rows fr om t he Orders t able in a SQL Ser ver dat abase wit h
rows fr om t he Cust om er s t able in an Access dat abase file. The OPENROWSET
funct ion declarat ions follow t he sy nt ax of pr ev ious sam ples t hat used t he
funct ions separat ely as t he source for a view . This script sam ple j oins t he
Cust om ers r ows w it h t he Orders rows based on t heir Cust om erI D colum n values.
An advant age of nest ing t he t wo OPENROWSET funct ions as t he argum ent for t he
FROM clause of t he out er SELECT st at em ent is t hat y our applicat ion doesn’t
requir e separat e v iews for each r ow source obj ect t hat get s j oined. This saves
your applicat ion from opening t he v iews.
--CreatevewAccessCustomersCab2000Orders
--Search for, and remove if found, the
--vewAccessCustomersCab2000Orders view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
           WHERE TABLE_NAME = ’vewAccessCustomersCab2000Orders’)
     DROP VIEW vewAccessCustomersCab2000Orders
GO

--Create the vewAccessCustomersCab2000Orders view
--in the Chapter04 database from the
--OPENROWSET of CustomersFromAccess and
--OPENROWSET of 1998OrdersOnCab2000.
CREATE VIEW vewAccessCustomersCab2000Orders
AS
SELECT TOP 100 PERCENT c.CompanyName, c.ContactName, c.Phone,
    o.OrderID, LEFT(o.OrderDate, 11) ’Order Date’
FROM OPENROWSET(‘Microsoft.Jet.OLEDB.4.0’,
    ’C:\Program Files\Microsoft Office\Office10\Samples\Northwind.mdb
’;
    ’admin’;’’,
    ’SELECT *
    FROM Customers
    WHERE Country=‘‘USA’’’) AS c JOIN
    OPENROWSET(‘MSDASQL’,
         ’DRIVER={SQL Server};SERVER=cab2000;UID=sa;PWD=password’,
    ’SELECT *
    FROM Northwind.dbo.Orders
    WHERE DATEPART(yyyy, OrderDate) = 1998’)
    AS o
    ON c.CustomerID = o.CustomerID
ORDER BY c.CompanyName, o.OrderID
GO

--Select all rows and columns from the
--vewAccessCustomersCab2000Orders view in Chapter04.
SELECT * FROM vewAccessCustomersCab2000Orders

The next script shows t he synt ax for t he alt er nat iv e appr oach t o j oining t wo
het er ogeneous dat a sources. Again, y ou need t wo SQL Server inst ances t o r un
t he sam ple. This alt er nat iv e j oins t wo pr ev iously creat ed v iews. I n t his inst ance,
each v iew is fr om a pr ior sam ple in t his chapt er. I n addit ion, t he t wo v iews
corr espond t o t he SELECT st at em ent s for each of t he nest ed OPENROWSET
funct ions in t he pr ior sam ple. Ther efore, t he r esult is ident ical for t he next script
and t he prior scr ipt . Howev er , t he code for t he next script is dram at ically sim pler.
By segm ent ing t he t wo OPENROWSET funct ions int o separat e v iews, t he second
approach m ak es it easier t o debug t he synt ax . On t he ot her hand, wit h t his
approach your applicat ion r equir es t he addit ional ov er head of m anaging t wo
separat e v iews. This includes cr eat ing, m aint aining, and opening t he v iews.
--Createvew2JoinedViews
--Search for, and remove if found, the
--vew2JoinedViews view in the Chapter04 database.
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
           WHERE TABLE_NAME = ’vew2JoinedViews’)
      DROP VIEW vew2JoinedViews
GO
--Create a new version of the vew2JoinedViews
--view in the Chapter04 database from
--two other previously existing views.
CREATE VIEW vew2JoinedViews
AS
Select TOP 100 PERCENT c.CompanyName, c.ContactName, c.Phone,
    o.OrderID, LEFT(o.OrderDate, 11) ’Order Date’
FROM vewUSACustomersFromAccess c JOIN vew1998OrdersOnCab2000 o
    ON (c.CustomerID = o.CustomerID)
ORDER BY c.CompanyName, o.OrderID
GO

--Select all rows and columns from the
--vew2JoinedViews view in Chapter04.
SELECT *
FROM vew2JoinedViews
GO




I n t r odu ct ion t o St or e d Pr oce dur es
St or ed pr ocedur es are com piled bat ches of T- SQL st at em ent s. The bat ch of
st at em ent s can cont ain near ly all t he T- SQL st at em ent t ypes. While a st or ed
procedur e can r et ur n a result set t he sam e way a v iew does, st ored pr ocedur es
are m ore pow erful in several r espect s. A v iew is a v irt ual t able; a st or ed
procedur e is m or e lik e a procedure in Visual Basic. You can pass it param et ers,
and it can r et urn values t hrough it s result set , out put param et ers, and r et urn
st at us values. I n fact , st or ed procedur es can ret ur n m ult iple r esult set s, while
views ar e lim it ed t o a single r esult sim ilar t o a t able.

Use s for St or e d Pr oce du r e s

St or ed pr ocedur es have four m ain uses. First , t hey can r et urn one or m or e result
set s. You can program a st ored procedure t o r et ur n m ult iple r esult set s as easily
as including m ult iple SELECT st at em ent s w it hin a single st ored procedure.
Anot her way st ored pr ocedur es can ret urn r esult set s is via out put param et ers.
An out put param et er is a scalar value. A scalar value is a single value, such as a
st ring or an int eger , t hat isn’t a part of a rowset . While a r esult set can cont ain a
scalar value, r esult set s norm ally cont ain set s of values. Out put param et ers
prov ide an efficient m eans for st ored pr ocedures t o r et ur n scalar values. St ored
procedur es can also ret ur n int eger values t hat indicat e how a st or ed pr ocedur e
t erm inat es. SQL Serv er docum ent at ion r efers t o t hese r et ur n values as ret ur n
st at us values. When a st or ed pr ocedur e can follow any of sev eral int er nal
processing pat hs, ret ur n st at us values can indicat e t o a calling r out ine which pat h
a st ored pr ocedur e pursued.
A second m aj or use of st or ed pr ocedur es is t he processing of input param et ers.
These param et ers enable y our applicat ions t o cont rol dynam ically t he t hings t hat
a st ored pr ocedur e ret urns. Not all T- SQL st at em ent s t ak e param et ers. I n t hese
circum st ances, you can com bine t he use of param et ers w it h cont rol- of- flow
st at em ent s, such as I F…ELSE st at em ent s, t o det erm ine what a st or ed procedure
ret ur ns. One com m on use for param et ers is in t he WHERE clause of SELECT
st at em ent s. By using input param et er values as crit er ion values for WHERE
clause expr essions, y our applicat ions can dy nam ically cont rol a st or ed
procedur e’s result set . When users set t he par am et er values, y ou enable users t o
cont r ol an applicat ion dynam ically at run t im e.
A t hird m aj or use for st ored procedur es is t he m anagem ent of
insert / updat e/ delet e operat ions for r ow sources. I n t his cont ext , a st ored
procedur e prov ides v alue t o an applicat ion w it hout r et ur ning a r esult set , a
param et er value, or a r et urn st at us v alue. The procedur e sim ply m odifies a r ow
source. Because st ored procedur es can set param et ers based on user input and
t he procedures can use param et ers for insert / updat e/ delet e operat ions, users can
cont r ol t he m odificat ions t o a r ow source at r un t im e.
Fourt h, y ou w ill lear n how t o use st or ed procedur es as pr ogram s im plem ent ed
wit h a bat ch of T- SQL st at em ent s. This fourt h use under lies and ext ends t he
ot her t hree uses for st ored pr ocedures. These st at em ent s can include SELECT
st at em ent s, ot her st at em ent s for insert / updat e/ delet e operat ions, and cont r ol- of-
flow st at em ent s, such as I F…ELSE st at em ent s. I n addit ion, you can specify any of
four t ypes of values— local variables, global var iables, param et ers, and ret ur n
st at us values— t o cont rol t he dy nam ic behav ior of a st or ed pr ocedur e and how it
com m unicat es wit h it s calling procedure.

                                       N ot e
See t he “Cont rol- of- Flow” t opic in Book s Online for a good
st ar t ing point t hat helps you t o learn about t radit ional
program m ing t echniques for st or ed procedures. Anot her
especially useful Books Online t opic for learning about st ored
procedure pr ogr am m ing is “Pr ogram m ing St ored
Procedures.”

Re u sin g T- SQL St a t e m e n t s w it h St or e d Pr oce du r e s

One of t he m aj or advant ages of st ored pr ocedures is t hat t hey can package T-
SQL st at em ent s for r euse. Four T- SQL st at em ent s help y ou m anage t hese blocks
of code. Two st at em ent s, CREATE PROCEDURE and ALTER PROCEDURE, enable
t he definit ion and refinem ent of t he code wit hin a st or ed pr ocedur e. Wit h t he
DROP PROCEDURE st at em ent , you can rem ov e a st or ed pr ocedur e fr om a
dat abase. The EXECUTE st at em ent perm it s you t o run a st ored pr ocedure.
The CREATE PROCEDURE st at em ent let s you creat e a st or ed procedur e. You can
abbrev iat e t his st at em ent as CREATE PROC. Follow t he st at em ent nam e wit h t he
nam e for your st or ed pr ocedur e. SQL Serv er has a r ich collect ion of syst em
st ored procedures, which t ypically st art w it h sp_. Chapt er 2 includes ex am ples of
how t o use syst em st or ed pr ocedur es w it h t ables. Syst em st ored pr ocedur es are
available for m anaging ev ery aspect of SQL Ser ver perform ance and
adm inist rat ion. To avoid conflict s wit h syst em st or ed procedur es, av oid st art ing
your own user - defined st or ed pr ocedur es w it h t he sp_ prefix. This chapt er uses
udp as a prefix for user - defined st ored pr ocedur es. Lik e view nam es, st or ed
procedur es should follow t he st andard rules for SQL Serv er ident ifiers.
The CREATE PROC st at em ent s t ypically hav e t hr ee or four m ain elem ent s. First ,
CREATE PROC declares t he st or ed pr ocedur e and assigns a nam e t o it . Second,
you can specify one or m or e param et ers for t he pr ocedur e. The param et er
declarat ions ar e opt ional. Third, t he AS keyword serv es as a t ransit ional word
bet ween t he declarat ion elem ent s and t he T- SQL code ( t he fourt h elem ent ) t hat
enables a st or ed procedur e t o perform a t ask. The follow ing t em plat e illust rat es
how t o ar range t hese st or ed procedur e elem ent s.
CREATE PROC
procedurename
Parameter specifications

AS
T-SQL code


Aft er y ou creat e a st ored procedure, y ou can change it s code in at least t wo
different way s. First , y ou can inv ok e t he DROP PROCEDURE ( or DROP PROC)
st at em ent t o rem ov e t he pr ior v ersion and t hen inv ok e a new CREATE PROC
st at em ent wit h t he sam e nam e as t he rem ov ed procedure. To delet e an ex ist ing
st ored procedure w it h t he DROP PROC st at em ent , sim ply follow t he keyword
phrase w it h t he nam e of t he st ored procedure t hat y ou want t o r em ov e. Wit h t his
approach, y ou w ipe out any perm issions assigned t o users for t he dropped st or ed
procedur e. Alt ernat iv ely , y ou can inv ok e t he ALTER PROCEDURE ( or ALTER PROC)
st at em ent . This allows y ou t o respecify t he param et ers and t he code w it hin a
st ored procedure w hile it m aint ains any perm ission set t ings for t he st or ed
procedur e t hat y ou m odify . Except for t he keyw ord declar ing it , t he ALTER PROC
st at em ent has t he sam e form at as t he CREATE PROC st at em ent .
Your applicat ions can use t he EXECUTE ( or EXEC) st at em ent t o inv ok e a st ored
procedur e init ially cr eat ed w it h a CREATE PROC st at em ent . I n it s m ost basic
represent at ion, follow t he EXEC k eyw ord w it h t he nam e of t he st ored procedur e
t hat y ou want t o r un. The synt ax for t he EXEC st at em ent perm it s y ou t o assign
values for input param et ers as well as accept out put param et er and ret ur n st at us
values. I n addit ion, t he EXEC st at em ent can also r et ur n one or m ore result set s—
depending on t he T- SQL code t hat populat es t he st ored procedure. This chapt er
includes num erous sam ples t hat illust rat e t he synt ax for inv ok ing st or ed
procedur es w it h t he EXEC st at em ent .

Usin g Pa r a m e t e r s, Loca l Va r ia bles, a n d Globa l V a r ia ble s

Alt hough param et ers, local variables, and global var iables can, of course, be used
elsewhere, using t hem wit h st or ed procedures especially enhances t he value of
t he procedures in an applicat ion. Ther e are t wo basic kinds of param et ers— input
param et ers and out put param et ers. Param et er nam es m ust begin w it h t he @
sym bol. The r em ainder of a param et er’s nam e m ust follow t he st andar d SQL
Ser ver ident ifier convent ions. Param et ers have dat a t ypes t hat correspond t o
t hose for t able colum n v alues. ( See Chapt er 3. )
I nput param et ers perm it y ou t o cust om ize t he operat ion of a st or ed procedur e at
run t im e. For exam ple, you can use input param et ers t o specify t he colum n
values for a st ored procedure t hat adds a new r ow t o a row source. The CREATE
PROC and ALTER PROC st at em ent s perm it y ou t o assign default values for input
param et ers. These default values allow a st ored procedure t o use a param et er
wit hout t est ing for a null v alue ev en if t he user om it s t he specificat ion of a
param et er when inv ok ing t he st or ed procedur e.
Out put param et ers repr esent values developed from w it hin a st or ed pr ocedur e.
These can be values com put ed by t he pr ocedur e or SQL Serv er . A st ored
procedur e can pass back as an out put param et er t he I DENTI TY value for a new
row in a t able so t hat anot her st ored pr ocedur e can use t he out put par am et er as
a foreign k ey value for a new row in a relat ed t able. I n t his scenar io, t he out put
param et er value from one st or ed pr ocedur e ser ves as t he input param et er value
for a second one.
A local var iable is a m em or y v ar iable t hat you assign for use inside a st or ed
procedur e. Use t he DECLARE keyword for designat ing local var iables and t he SET
keyw ord for assigning v alues t o a local var iable. You can also assign a v alue t o a
local v ar iable w it h a SELECT st at em ent t hat ret urns a scalar value, such as t he
count of t he num ber of rows in a t able. The scope of a local v ariable is t he st ored
procedur e t hat declares t he var iable.
Like param et ers, local v ariable ident ifiers m ust begin wit h t he @ sym bol. The
rem ainder of t he local v ariable nam e m ust follow st andard SQL Serv er ident ifier
conv ent ions. The DECLARE st at em ent for a local var iable m ust include a dat a
t ype for t he var iable. You can use any dat a t ype except for t ext , nt ex t , and
im age. A local var iable’s dat a t ype specificat ion det erm ines t he t ype of cont ent
t hat t he var iable can hold. Local var iables can be used in expr essions and as
argum ent s for cont r ol- of- flow st at em ent s t o cont r ol t he operat ion of a st ored
procedur e. Local var iables can w or k in coordinat ion wit h param et ers by accept ing
values fr om param et ers and passing values t o t hem .
Dev elopers fam iliar w it h SQL Serv er v ersions pr ior t o 7.0 m ay be fam iliar wit h t he
t erm global var iables. SQL Ser ver 2000 r efers t o t hese global var iables as
funct ions. A global var iable funct ion nam e st art s wit h @@. These global var iable
funct ions ret ur n values t o st or ed pr ocedur es t hat cont ain syst em infor m at ion. You
can display t he full list of 33 @@ var iable funct ions from t he I ndex t ab in Books
Online by ent er ing @@ as t he keyword. This chapt er illust rat es t he use of t he
@@ROWCOUNT funct ion, which ret ur ns t he num ber of r ows affect ed by t he last
T- SQL st at em ent . Ot her @@ funct ions t hat I r egular ly find part icular ly conv enient
include @@I DENTI TY, @@ERROR, and @@DBTS. These t hr ee funct ions ret ur n
t he last I DENTI TY value insert ed, t he er ror num ber associat ed wit h t he last T- SQL
st at em ent , and t he cur rent t im est am p value w it hin a dat abase.




Cr e a t in g a n d Usin g St or e d Pr ocedu r e s
The purpose of t his sect ion is t o int roduce you t o synt ax for creat ing and using
st ored procedures. This sect ion shows you t ypical ways of apply ing t he CREATE
PROC st at em ent . I n addit ion, you learn com m on ways of specify ing t he EXEC
st at em ent t o run a st or ed pr ocedur e. The sect ion illust rat es t echniques for
designat ing input param et ers when y ou cr eat e a st ored pr ocedur e as w ell as
way s of specify ing input param et er values when you r un a st or ed procedur e.

D yna m ica lly Se le ct in g f r om a Row Sou r ce

One of t he m ain advant ages of st or ed pr ocedur es com par ed w it h v iews is t hat
st ored procedures perm it t he use of param et ers. Bot h views and st or ed
procedur es can inv ok e SELECT st at em ent s. Howev er , st or ed procedur es let y ou
assign values t o param et ers in WHERE clause expressions at r un t im e. This
capabilit y m eans y our applicat ions can t ak e input from users t o designat e w hich
rows a st ored pr ocedur e ret urns in it s result set . Wit h v iews, you would hav e t o
preprogram a differ ent view for each set of r ow s you want ed.
The follow ing scr ipt has t hr ee bat ches of T- SQL code. The first bat ch r em ov es any
prior v ersion of t he udpList ShippersRow in t he curr ent dat abase. The first bat ch
uses t he I NFORMATI ON_SCHEMA.ROUTI NES view t o search for an ex ist ing st ored
procedur e wit h t he nam e udpList ShippersRow. I f one alr eady exist s wit h t hat
nam e, t he bat ch invokes t he DROP PROCEDURE st at em ent t o rem ov e it .
The second bat ch inv ok es t he CREATE PROC st at em ent t o creat e a new st or ed
procedur e nam ed udpList ShippersRow. This procedur e t ak es a single param et er
nam ed @RowI D w it h an int dat a t ype. The pr ocedur e uses t he param et er t o
specify t he ShipperI D colum n value for t he r ow it ret urns; see t he WHERE clause
for t he sy nt ax of how t o do t his. The basic SELECT st at em ent ret urns all t he
colum ns fr om t he Shippers t able in t he Nort hwind dat abase. You can t ell from t he
synt ax t hat t his is t he SQL Ser ver v ersion of t he dat abase. ( Not ice t he FROM
clause argum ent .) All t he rem aining st ored pr ocedur e sam ples use j ust SQL
Ser ver dat abases.
The final bat ch consist s of a single EXEC st at em ent . The st at em ent r uns t he
st ored procedure creat ed in t he pr ev ious bat ch and designat es a v alue for t he
RowI D par am et er . Failing t o specify a RowI D param et er value causes t he
procedur e t o fail wit h an er ror m essage. Designat ing a nonex ist ent ShipperI D
colum n value w it h RowI D produces an em pt y result set . On t he ot her hand,
specify ing any of t he ex ist ing ShipperI D colum n values causes t he procedure t o
generat e a r esult set w it h all t he colum ns for t hat row in t he Shippers t able.
--CreateudpListShippersRow
--Delete previous version of udpListShippersRow
--stored procedure if it exists.
IF EXISTS (SELECT ROUTINE_NAME
           FROM INFORMATION_SCHEMA.ROUTINES
           WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
           ROUTINE_NAME = ’udpListShippersRow’)
     DROP PROCEDURE udpListShippersRow
GO

--Create udpListShippersRow with an
--input parameter to specify a row.
CREATE PROC udpListShippersRow
@RowID int
AS
SELECT *
FROM Northwind..Shippers
WHERE ShipperID = @RowID
GO

--Run udpListShippersRow with an
--input parameter of 2.
EXEC udpListShippersRow 2



Re t u r n ing a Sor t ed Re su lt Se t

Ev en a basic SELECT st at em ent can y ield benefit s when it is m ade available from
a st ored pr ocedur e. For exam ple, t he use of t he ORDER BY clause in a v iew
requir es t he concurr ent use of t he TOP predicat e. While t his is cert ainly not
com plicat ed, it is j ust one m or e t hing you hav e t o rem em ber t o get r ight . The
synt ax for using t he ORDER BY clause in a st or ed pr ocedur e is j ust like t hat in a
st and- alone T- SQL script . I n ot her w ords, you don’t need a TOP pr edicat e for your
SELECT st at em ent .
The follow ing scr ipt shows t he ORDER BY clause w it hin a SELECT st at em ent t hat
det erm ines t he result set fr om a st ored pr ocedure. The SELECT st at em ent
generat es a result set based on t he Shippers t able, w it h t he r ows sort ed by
Com panyNam e colum n values. This r et urns t he rows in a different order t han t he
default one based on t he ShipperI D colum n values. The scr ipt again relies on a
t hr ee- part st rat egy. The first part rem ov es an old version of t he
udpShippersSort edBy Com panyNam e st ored procedur e. The second part inv ok es
t he CREATE PROC st at em ent t o add t he new st or ed procedur e. The t hird part
runs t he new ly cr eat ed st ored procedure w it h t he EXEC st at em ent . Because t his
st ored procedure doesn’t t ake any param et ers, you can j ust follow t he EXEC
keyw ord wit h t he nam e of t he st or ed pr ocedur e. There is no need for anyt hing
else aft er t he EXEC k ey word.
--CreateudpShippersSortedByCompanyName
--Delete previous version of udpShippersSortedByCompanyName
--stored procedure if it exists.
IF EXISTS (SELECT ROUTINE_NAME
            FROM INFORMATION_SCHEMA.ROUTINES
            WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
            ROUTINE_NAME = ’udpShippersSortedByCompanyName’)
       DROP PROCEDURE udpShippersSortedByCompanyName
GO

--Create udpShippersSortedByCompanyName with an
--input parameter to specify a row.
CREATE PROC udpShippersSortedByCompanyName
AS
SELECT *
FROM Northwind..Shippers
ORDER BY CompanyName
GO

--Run udpShippersSortedByCompanyName.
EXEC udpShippersSortedByCompanyName
GO



Re t u r n ing t h e Scr ipt f or a V ie w

St or ed pr ocedur es are an ext r em ely flex ible t ool. You can use SELECT st at em ent s
in t he full range of cases t hat use v iews and st and- alone T- SQL st at em ent s. For
exam ple, y ou can quer y I NFORMATI ON_SCHEMA views t o uncov er infor m at ion
about t he obj ect s in a dat abase. An advant age of a st or ed pr ocedur e is t hat t he
T- SQL it cont ains is com piled. A st and- alone T- SQL st at em ent m ust be com piled
befor e SQL Server can use it . Therefore, t he st or ed procedur e can r un t he sam e
T- SQL code fast er.

                                    N ot e
The sp_execut esql sy st em st ored procedur e offers som e of
t he benefit s of st ored procedur es for st and- alone T- SQL
SELECT st at em ent s.
The follow ing scr ipt dem onst rat es t he use of a st ored pr ocedur e t o quer y t he
I NFORMATI ON_SCHEMA.VI EWS v iew. The r esult set for t his v iew cont ains a r ow
for each v iew in t he cur rent dat abase. The v iew ’s VI EW_DEFI NI TI ON colum n
ret ur ns t he T- SQL script defining a v iew. The TABLE_NAME colum n r et ur ns t he
nam e for a v iew.
The st or ed procedure accept s a param et er t hat designat es a v iew ’s nam e. The
st ored procedure’s SELECT st at em ent passes t he T- SQL scr ipt for a v iew t o a local
variable, @st rDefinit ion. The local variable accept s t he value in t he
VI EW_DEFI NI TI ON colum n value for t he row wit h a TABLE_NAME colum n value
equal t o t he param et er passed t o t he st or ed pr ocedur e. Then a PRI NT st at em ent
displays t he cont ent s of t he local var iable in t he Messages pane.
The st or ed procedure’s approach works for v iews wit h up t o 8000 charact ers fr om
t he default code page for t he com put er on w hich y ou dev eloped t he st ored
procedur e. This is because t he varchar dat a t y pe for t he @st rDefinit ion local
variable has a m ax im um lengt h of 8000 charact ers in t he default code page for a
com put er. I f y ou expect your v iew script s t o have m or e charact ers or y our
applicat ion r uns on com put ers using m ult iple code pages, you need anot her
approach for st or ing t he view’s T- SQL script . For exam ple, y ou can use an out put
param et er inst ead of a local var iable. Assign a t ext or an nt ext dat a t ype t o t he
param et er. When using t he out put param et er approach, y ou can pr int t he script
in t he calling rout ine for t he st or ed procedur e. Recall t hat a t ext dat a t ype can
hold up t o 2 31 - 1 charact ers, and a dat a t ype value can hold up t o 2 30 - 1
charact ers.
Users can alt er t he r et urn value t hat appears in t he Messages pane by changing
t he nam e of t he v iew passed t o t he st or ed procedur e. The EXEC st at em ent t o
inv oke t he st ored pr ocedur e encloses t he param et er in single quot at ion m arks.
This is because t he st or ed pr ocedur e assigns a varchar dat a t ype t o t he
param et er st or ing a view’s nam e.
--CreateudpScriptForView
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
          FROM INFORMATION_SCHEMA.ROUTINES
          WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
          ROUTINE_NAME = ’udpScriptForView’)
     DROP PROCEDURE udpScriptForView
GO

--Create stored procedure to print definition
--for a view in the current database.
CREATE PROC udpScriptForView
@vewName varchar(128)
AS
DECLARE @strDefinition varchar(8000)
SET @strDefinition = (SELECT VIEW_DEFINITION
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = @vewName)
PRINT @strDefinition
GO

--Run stored procedure and pass view name.
EXEC udpScriptForView ’vewShippers’
GO




Pr ocessing St or e d Pr ocedu r e Ou t pu t s
One of t he t asks t hat st or ed procedur es ser ve especially w ell is get t ing dat a back
t o a calling procedur e. St or ed pr ocedur es can achiev e t his goal in sev eral ways.
First , t hey perm it t he t r ansfer of dat a back t o t he calling pr ocedur e in t he form of
result set s. You can r et ur n m ult iple r esult set s from a single st or ed procedur e.
Second, a st ored pr ocedur e can r et ur n scalar values v ia out put param et ers.
Third, code calling a st ored pr ocedure can process ret ur n st at us values. I n any
one applicat ion, y ou can concurr ent ly use any com binat ion of t hese t hr ee
processes for ret ur ning v alues. This sect ion elaborat es on t hem and dem onst rat es
t he synt ax for im plem ent ing each.

Re t u r n ing Tw o Re sult Se t s fr om a St or e d Pr oce du r e

I t ’s sim ple t o r et ur n m ult iple r esult set s fr om a single st ored pr ocedur e: j ust
include a separat e SELECT st at em ent for each r esult set t hat y ou want a st ored
procedur e t o ret urn. I n cont rast , v iews can hav e only a single SELECT st at em ent .
Once y ou st art using m ult iple SELECT st at em ent s in a st or ed pr ocedur e, you’ll
find t hat it has consider ably m ore flex ibilit y t han ret ur ning rows from a t able or
view.
The follow ing scr ipt creat es a st ored pr ocedur e wit h t w o r esult set s. The first
result set cont ains a r ow w it h t he nam e and cr eat ion dat e for each user- defined
st ored procedure in a dat abase. Recall t hat t he dat abase cont ext for t hese
sam ples is Chapt er04. ( You can set t he cont ext wit h a USE st at em ent .) To ret urn
j ust t he user - defined st or ed procedur es from t he
I NFORMATI ON_SCHEMA.ROUTI NES v iew, you need t wo cr it er ia expr essions. One
expression select s j ust r ows w it h a ROUTI NE_TYPE colum n value of PROCEDURE.
This expression filt ers out any user - defined funct ions. The second expr ession
rem ov es any rows w it h a ROUTI NE_NAME colum n value t hat begins w it h dt _.
Because SQL Serv er uses dt _ as a pr efix for t he st or ed procedures t hat it cr eat es
in a dat abase, t his expr ession leav es only user - defined st ored procedures.
The second SELECT st at em ent ret urns t he value of t he @@ROWCOUNT funct ion.
This funct ion is always t he value of r ecords affect ed by t he last T- SQL st at em ent .
I n t his case, t he last one ret ur ns t he nam es and creat ion dat es of t he user-
defined st ored procedures in a dat abase, so t he second SELECT st at em ent
ret ur ns t he num ber of user- defined st or ed procedur es in t he curr ent dat abase
cont ext .
--CreateudpReturn2ResultSets
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
             FROM INFORMATION_SCHEMA.ROUTINES
             WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
             ROUTINE_NAME = ’udpReturn2ResultSets’)
       DROP PROCEDURE udpReturn2ResultSets
GO

--Create stored procedure to return one result
--set for listing stored procedure names and dates
--and another with the count of the stored procedures.
CREATE PROC udpReturn2ResultSets
AS
SELECT ROUTINE_NAME, CREATED
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
    LEFT(ROUTINE_NAME,3) <> ’dt_’
ORDER BY CREATED DESC
SELECT @@ROWCOUNT ’Number of stored procedures’
GO

--Run stored procedure that returns two result sets.
EXEC udpReturn2ResultSets
GO

Figur e 4- 3 shows t he out put from r unning t he udpRet urn2Result Set s st ored
procedur e. ( This is t he out put from t he preceding script .) Not ice t hat t he t op
result set cont ains ROUTI NE_NAME and CREATED colum n values. This result has
a row for each user - defined st ored pr ocedur e. The last row includes t he nam e and
creat ion dat e for t he elevent h st or ed pr ocedur e. The second r esult set cont ains a
num ber t hat is t he count of t he num ber of user - defined st ored pr ocedur es— 11.

     Figu r e 4 - 3 . Th e re t u r n fr om a u ser - d e fin e d st or ed pr oced u r e t h a t
                                  spe cifie s t w o r esu lt se t s.
Re t u r n ing On e Re su lt Se t a n d One Pa r a m e t e r Va lu e

The preceding sam ple uses a SELECT st at em ent t o ret urn a scalar value, nam ely
t he cur rent value for @@ROWCOUNT. By ent er ing t he @@ROWCOUNT global
variable funct ion in a SELECT st at em ent , t he sam ple r et ur ns t he current value of
@@ROWCOUNT in a result set . The next sam ple illust rat es how t o ret ur n t he
@@ROWCOUNT value as an out put param et er from a st or ed procedure. This
inv olves a special declar at ion for t he param et er inside t he st ored pr ocedur e as
well as an assignm ent expression in t he EXEC st at em ent t o r et r iev e t he value for
t he out put param et er. I n t he T- SQL code t hat calls t he st or ed procedur e, you
need t o t ransfer t he out put param et er t o a local var iable for use locally. I n
addit ion, t he EXEC st at em ent m ust explicit ly designat e t he out put param et er.
The follow ing code shows t he exact synt ax for ret ur ning @@ROWCOUNT as an
out put param et er . First not ice t he line im m ediat ely aft er t he CREATE PROC
st at em ent :
@NumberOfRows int OUTPUT

This line declares t he param et er. Not ice t hat it ends wit h t he k eyw ord OUTPUT.
This k eyw ord designat es t he @Num berOfRows param et er as an out put
param et er. Lat er in t he st ored procedure, a SET st at em ent assigns t he curr ent
value of @@ROWCOUNT t o t he @Num berOfRows param et er , lik e t his:
SET @NumberOfRows = (SELECT @@ROWCOUNT)

This st or ed pr ocedur e div erges from t he preceding one by ex plicit ly inv oking t he
SET NOCOUNT st at em ent w it h t he value ON. This st at em ent suppresses t he
aut om at ic SQL Server m essage about t he num ber of r ows affect ed, which
happens t o be t he value of @@ROWCOUNT. At t he conclusion of t he st ored
procedur e, t he sam ple inv ok es t he SET NOCOUNT st at em ent a second t im e w it h
t he set t ing OFF. This second invocat ion of t he SET NOCOUNT st at em ent r est ores
t he default behav ior of print ing t he rows affect ed by a T- SQL st at em ent .
Using a param et er ret ur ned by a st ored pr ocedure also r equir es special synt ax.
First y ou need a local v ariable t o accept t he out put param et er value. This is
because y ou cannot w ork dir ect ly wit h t he out put param et er in t he code t hat calls
t he st or ed pr ocedur e. The sam ple code declar es a local v ariable nam ed
@Ret ur nedParam Value t o st or e t he out put param et er value locally. Second you
need an assignm ent st at em ent . This st at em ent m ust end w it h t he OUTPUT
keyw ord. I n addit ion, t he local var iable m ust be on t he r ight side of t he equal
sign, and t he out put par am et er should appear on t he left side. Third t he out put
param et er ret ur ns an int dat a t ype value. How ever, t he Pr int st at em ent t hat
report s t he num ber of st ored procedur es r equir es a char act er dat a t ype, nam ely
varchar. Therefore, t he code applies t he CAST funct ion t o t he local variable
st oring t he out put param et er v alue; t he funct ion represent s t he int eger value as
a st ring. The expression for @st rFor Pr int er com bines a st r ing const ant wit h t he
CAST funct ion value. The PRI NT st at em ent t akes @st rForPr int er as it s argum ent
t o pr int t he num ber of st or ed pr ocedur es w it h a br ief descr ipt ive label.
--CreateudpReturn1ResultSet1Parameter
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
              FROM INFORMATION_SCHEMA.ROUTINES
              WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
              ROUTINE_NAME = ’udpReturn1ResultSet1Parameter’)
       DROP PROCEDURE udpReturn1ResultSet1Parameter
GO

--Create stored procedure to return one result
--set for listing stored procedure names and dates along
--with another containing the count of the stored procedures.
CREATE PROC udpReturn1ResultSet1Parameter
@NumberOfRows int OUTPUT
AS
SET NOCOUNT ON
SELECT ROUTINE_NAME, CREATED
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
    LEFT(ROUTINE_NAME,3) <> ’dt_’
ORDER BY CREATED DESC
SET @NumberOfRows = (SELECT @@ROWCOUNT)
SET NOCOUNT OFF
GO

--Run stored procedure that returns two result sets.
DECLARE @ReturnedParamValue int
DECLARE @strForPrinter varchar(100)
EXEC udpReturn1ResultSet1Parameter
    @NumberOfRows = @ReturnedParamValue OUTPUT
SET @strForPrinter = ’Number of stored procs: ’ +
    Cast(@ReturnedParamValue AS varchar(3))
PRINT @strForPrinter
GO



Re t u r n ing On e St r ing Pa r a m e t e r

The code y ou use t o r et urn a st ring value as an out put param et er is essent ially
t he sam e code y ou use t o r et urn a num ber value. The m ain dist inct ion is t he
declarat ion of t he dat a t ype for t he param et er.
The follow ing scr ipt r et urns t he nam e of t he oldest user- defined st or ed procedur e
in a dat abase. I t passes back t he nam e of t he st or ed pr ocedur e v ia an out put
param et er nam ed @st r Nam eOfOldest SPr oc. Not ice t hat t he out put par am et er
declarat ion uses a varchar dat a t ype t hat is consist ent w it h t he m ax im um lengt h
of a SQL Serv er ident ifier . I f your applicat ion runs in m ult iple locat ions t hat use
different code pages, you m ay want t o use an nvarchar r at her t han a v archar
dat a t ype specificat ion for t he param et er.
I n t his case, t he t echnique for finding t he st or ed procedure is as int erest ing as
t he t echnique for declaring t he out put param et er. The SET ROWCOUNT st at em ent
t ells SQL Ser ver t o st op processing a st at em ent aft er t he designat ed num ber of
records. The ORDER BY clause in t he SELECT st at em ent sort s t he st or ed
procedur es so t hat t he nam e of t he oldest st ored pr ocedur e appears first .
Ther efor e, st opping aft er pr ocessing t he first r ow r et urns t he oldest st ored
procedur e.
The t echnique for processing an out put param et er in t he calling r out ine is about
t he sam e whet her t he out put param et er has an int or a varchar dat a t y pe. This
part icular sam ple appears slight ly sim pler t han t he preceding one m ost ly because
it doesn’t label t he ret ur n value t hat is pr int ed in t he Messages pane. Because t he
local v ar iable for holding t he out put param et er is alr eady a st ring, t her e is no
need t o conv ert it so t hat it can be used as an argum ent for t he PRI NT st at em ent .
--CreateudpReturn1StringParameter
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
            FROM INFORMATION_SCHEMA.ROUTINES
            WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
            ROUTINE_NAME = ’udpReturn1StringParameter’)
      DROP PROCEDURE udpReturn1StringParameter
GO

--Create stored procedure to return one
--parameter with a string value.
CREATE PROC udpReturn1StringParameter
@strNameOfOldestSProc varchar(128) OUTPUT
AS
SET ROWCOUNT 1
SET @strNameOfOldestSProc = (SELECT TOP 1 ROUTINE_NAME
FROM INFORMATION_SCHEMA.ROUTINES
WHERE LEFT(ROUTINE_NAME,3) <> ’dt_’
    AND ROUTINE_TYPE = ’PROCEDURE’
ORDER BY CREATED)
GO

--Run stored procedure that returns one string parameter.
DECLARE @ReturnedParamValue varchar(128)
EXEC udpReturn1StringParameter
    @strNameOfOldestSProc = @ReturnedParamValue OUTPUT
PRINT @ReturnedParamValue
GO


W or k ing w it h Re t ur n St a t u s V a lu e s

St or ed pr ocedur es considered t o t his point in t he chapt er proceed in a st raight
line fr om t he first t o t he last st at em ent in t he pr ocedur e. However, t his isn’t a
requir em ent . Cont rol- of- flow st at em ent s, such as t he I F…ELSE st at em ent , m ake it
possible for a st ored procedur e t o ex ecut e condit ionally. You can end t he
processing w it hin a st or ed pr ocedur e w it h one or m or e RETURN st at em ent s at t he
end of each of several pat hs t hr ough t he code. Each RETURN st at em ent can pass
back an int dat a t ype value t o t he calling procedure as it closes t he st or ed
procedur e. Alt hough you can have m ult iple RETURN st at em ent s wit h different
ret ur n st at us values, any one invocat ion of a st or ed procedur e can r et urn j ust one
ret ur n st at us value. This m akes it possible for code inv ok ing a st or ed pr ocedur e
t o k now pr ecisely at w hich line t he st ored pr ocedur e closed.
The follow ing code sam ple creat es a st or ed procedur e t hat searches for a st or ed
procedur e by a nam e in a dat abase. I f t he search finds a st ored pr ocedur e w it h
t he t arget nam e, t he r et ur n st at us value is 1. Ot herw ise, t he ret urn st at us value
is 0. I t is com m on t o set ret ur n st at us values w it h a RETURN st at em ent inside an
I F…ELSE st at em ent ( alt hough t his sam ple’s design is ext raordinar ily sim ple) .
The calling T- SQL code for t he st or ed procedure in t he follow ing sam ple causes
t he procedure t o search for eit her of t wo nam es: udpList ShippersRow or SP1.
Make sur e your dat abase has a st ored procedur e nam ed udpList Shipper sRow and
t hat y our dat abase doesn’t hav e a st or ed pr ocedur e nam ed SP1. I f you hav e been
doing t he sam ples in t he order t hat t hey appear in t his chapt er, y our Chapt er04
dat abase will hav e a st ored pr ocedure nam ed udpList ShippersRow. This let s you
use t he sam ple T- SQL code t hat calls t he st ored procedure t o ver ify t hat t he
ret ur n st at us values r eflect t he pr esence or absence of a st ored pr ocedur e. The
calling T- SQL code for t he st or ed pr ocedur e displays t he r et ur n st at us value in a
result set t hat cont ains eit her 0 or 1. These values m at ch each of t he r et ur n
st at us values set in t he st ored procedure.
The sy nt ax for capt uring a r et ur n st at us value in a calling pr ocedure deviat es
slight ly fr om t hat for an out put param et er. I n bot h cases, y ou need a local
variable t o r epr esent t he v alue r et ur ned from t he st or ed pr ocedur e. Howev er , t o
capt ure t he ret ur n st at us value, y ou use an assignm ent expression t hat set s t he
st ored procedure equal t o t he local var iable for t he ret ur n st at us value. This
assignm ent expr ession is act ually int egrat ed int o t he call of t he st or ed procedur e
as an argum ent for an EXEC st at em ent .
I n t he sam ple, a local v ariable specifies t he v alue for t he procedure t o pass t o t he
st ored procedure. As t he code appears, t he calling code passes t he nam e
udpList ShippersRow. Howev er, y ou can com m ent out ( w it h t wo leading hyphens)
t he assignm ent st at em ent for t he @st r ProcNam e local var iable and rem ov e t he
hyphens from t he assignm ent st at em ent t hat set s t he local variable t o SP1. This
t ransit ion w ill cause t he r et urn st at us value t o swit ch fr om 1 t o 0.
--CreateudpReturnStatusValue
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
             FROM INFORMATION_SCHEMA.ROUTINES
             WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
             ROUTINE_NAME = ’udpReturnStatusValue’)
       DROP PROCEDURE udpReturnStatusValue
GO

--Create stored procedure to pass back
--a return status value of 0 or 1.
CREATE PROC udpReturnStatusValue
@strName varchar(123)
AS
SELECT ROUTINE_NAME
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = @strName AND ROUTINE_TYPE = ’PROCEDURE’
IF @@ROWCOUNT = 0
     RETURN 0
ELSE
     RETURN 1
GO

--Pass a procedure name to udpReturnStatusValue.
DECLARE @strProcName varchar(128)
DECLARE @return_status int

--Use the following SET statement for a 1.
SET @strProcName = ’udpListShippersRow’

--Use the following SET statement for a 0.
--SET @strProcName = ’SP1’

EXEC @return_status = udpReturnStatusValue @strProcName
SELECT @return_status AS ’Return Status’
I nse r t in g, Upda t in g, a n d D e le t in g Row s
Dat a m anipulat ion is anot her ar ea in which st or ed pr ocedures shine— unlike
views, w hich cannot ex ecut e t he I NSERT I NTO, UPDATE, or DELETE st at em ent .
The capabilit y of t ak ing param et ers as argum ent s wit h t hese st at em ent s perm it s
a single st ored procedur e t o m odify a dat abase in different ways at r un t im e
based on user input . This sect ion has t w o m ain goals. First it int r oduces t he
synt ax for t he SQL Serv er dat a m anipulat ion st at em ent s w it hin a st or ed
procedur e. Second it illust rat es how t o perform dat a m anipulat ion w it h param et er
values for st or ed procedur es.

Alt e r in g a St or e d Pr oce du r e for D a t a M a n ipu la t ion

The sy nt ax for insert ing, updat ing, and delet ing rows fr om a row source is
st raight forward. The sam ple for t his sect ion separat ely illust rat es how t o perform
each t ask for a t able in t he local dat abase. I n order t o k eep t he sam ple easy t o
underst and, t he insert / updat e/ delet e code uses const ant s t o w ork w it h specific
values for a specific r ow .
I n addit ion t o clar ify ing t he synt ax for per form ing t he t ask, t he sam ple
dem onst rat es how t o alt er an ex ist ing st ored pr ocedur e t o perform a different
funct ion. Recall t hat alt er ing a st ored pr ocedur e w it h t he ALTER PROC st at em ent
allows you t o preserv e t he perm issions assigned for t he st ored procedure. I f you
drop and r e- cr eat e a st ored pr ocedure, any user perm issions for t he old version
of t he st ored pr ocedur e are lost unless you r eassign t hem t o t he new v ersion of
t he st or ed pr ocedur e. I don’t necessar ily recom m end y ou alt er a single st ored
procedur e t hat y ou m odify for each of t hr ee differ ent funct ions in pr oduct ion
syst em s. The sam ple design has t he t ut or ial value of reinforcing your
underst anding of t he t echnique for alt er ing a st or ed procedur e.
The sam ple r euses t he sam e st or ed procedure for t hree t asks successively. First
t he script st art s t o cr eat e a new copy of t he udpI nsert Updat eDelet eSam ples
st ored procedure by rem ov ing any ex ist ing v ersion of t he obj ect from t he
dat abase. Then t he script inv ok es t he CREATE PROC st at em ent t o m ak e a fresh
version of t he st ored pr ocedur e wit h t he code t o add a r ecord t o t he
Em ailCont act s t able. ( See t he “ Cr eat ing and Select ing fr om a View ” sect ion earlier
in t his chapt er for t he sam ple code t o creat e and init ially populat e t his t able.) The
st ored procedure adds a new record t o t he t able for Tony Hill.
The st or ed procedure dem onst rat es t he use of t he I NSERT I NTO st at em ent for
adding a new row t o t he Em ailCont act s t able, lik e t his:
CREATE PROC udpInsertUpdateDeleteSamples
AS
INSERT INTO vewEmailContacts
(ContactID, FirstName, LastName, Email1)
VALUES (3, ’Tony’, ’Hill’, ’tony@cabinc.net’)
GO

The st at em ent can w or k direct ly wit h t ables, but t he sam ple illust rat es it s
capabilit y of work ing w it h a v iew — nam ely , v ew Em ailCont act s. An ear lier sam ple
in t his chapt er creat ed t his v iew . The I NTO k ey word is opt ional. I n ot her words,
you can specify I NSERT wit h or wit hout I NTO. Not ice t he list of colum n nam es in
parent heses following t he I NTO k eyword and t he v iew nam e. The sy nt ax r ules for
t he st at em ent r equir e t his list w hen you are insert ing values for som e but not all
colum ns or you ar e insert ing colum n values in a differ ent order t han t he one in
which t hey appear in t he row source. Because t he sam ple assigns a value t o each
colum n in t he order t hat t he colum ns appear in t he t able, t he list isn’t m andat ory.
Howev er, including t he list is a good pract ice because it m ak es it clear which
values t he st at em ent assigns t o indiv idual colum ns. The VALUES k eyw ord is
m andat ory. This keyw or d m arks t he st art of t he values for t he new r ow. I nclude
t he values t hat y ou want t o add w it hin par ent heses.

                                    N ot e
Ther e are several int er est ing adapt at ions of t he I NSERT I NTO
or I NSERT st at em ent . For exam ple, you shouldn’t specify
colum n values for colum ns w it h an I DENTI TY pr opert y or
com put ed colum ns because SQL Server aut om at ically
det er m ines t he values for t hese colum ns. I n addit ion, y ou
can t ransfer dat a fr om one t able t o anot her by using a
SELECT clause wit hin an I NSERT I NTO st at em ent . See t he
“I NSERT” t opic in Books Online for t he pr ecise synt ax t o
im plem ent t his. When you com bine t his feat ure wit h t he
OPENROWSET funct ion or anot her m eans of select ing rows
fr om a het er ogeneous or r em ot e dat a source, t he I NSERT
I NTO st at em ent prov ides a conduit for t ransferr ing dat a
bet ween dat abases.
The init ial version of t he Em ailCont act s t able has j ust t wo rows, for Rick Dobson
and Virginia Dobson. I nvok ing t he st or ed pr ocedur e w it h an EXEC st at em ent adds
a t hird r ow. The sam ple script r uns t he EXEC st at em ent for t he st ored procedur e
and t hen per form s a SELECT st at em ent t hat ret ur ns all r ows from t he
Em ailCont act s t able. The result set fr om t he SELECT st at em ent confirm s t he
addit ion of t he new r ow t o t he t able.
Aft er insert ing a new r ow, t he sam ple script pr ogresses by invok ing t he ALTER
PROC st at em ent :
ALTER PROC udpInsertUpdateDeleteSamples
AS
UPDATE vewEmailContacts
SET FirstName = ’Anthony’, Email1 = ’anthony@cabinc.net’
WHERE ContactID = 3
GO

This st at em ent m odifies t he synt ax for t he udpI nsert Updat eDelet eSam ples st ored
procedur es from an insert pr ocedur e t o an updat e procedure. The new version of
t he st or ed pr ocedur e changes t he First Nam e and Em ail1 colum n values for t he
row added wit h t he I NSERT I NTO dem onst rat ion.
The sy nt ax for t he UPDATE st at em ent r ev eals how t o change t w o colum n values
wit hin a single UPDATE st at em ent . St art by follow ing t he UPDATE keyw ord wit h
t he nam e of a t able or v iew t hat point s at a t able w it h colum n values y ou want t o
updat e. To use a v iew in t his way ( as t he sam ple does) , t he v iew m ust perm it
updat ing of it s underly ing colum n values. Aft er t he UPDATE k ey word and it s
t arget row source, y ou can st art a new line w it h t he SET k eyw ord. Each updat e
for a colum n value r equires an assignm ent st at em ent w it h t he new value for t he
colum n. Delim it successiv e assignm ent st at em ent s wit h com m as. The WHERE
clause is part icularly cr it ical w it h UPDATE and DELETE st at em ent s because it
specifies t o which row ( s) t o apply t he st at em ent . I n t he script below, using t he
WHERE clause expression ContactID = 3 indicat es t hat t he UPDATE st at em ent
applies t o j ust t he row for Tony Hill, w ho has a Cont act I D colum n value of 3.
Aft er alt ering t he st or ed procedure, y ou m ust r un it for t he change t o have an
effect . The EXEC st at em ent achieves t his. A SELECT st at em ent confirm s t hat t he
updat e occur red. The row for Tony Hill includes new values for it s First Nam e and
Em ail1 colum ns.
The last part of t he sam ple script shows how t o alt er a st ored procedur e for t he
addit ion of a DELETE st at em ent . This st at em ent doesn’t requir e a list , as is
com m on w it h t he SELECT st at em ent . That ’s because t he DELETE st at em ent
rem ov es one or m ore rows at a t im e; t he st at em ent doesn’t operat e on indiv idual
colum ns w it hin a row . The FROM clause in t he sam ple denot es t he r ow source
from w hich t o r em ov e r ows. The WHERE clause is cr it ical. Use y our WHERE clause
expression t o designat e which r ows t o r em ov e from t he row source. Wit hout a
WHERE clause, t he DELETE st at em ent r em oves all r ows fr om it s r ow source.

                                    N ot e
I f you do want t o r em ove all r ows, you can specify t he
st at em ent as DELETE row sourcenam e, such as DELETE
pubs..authors t o rem ove all t he r ows from t he aut hors
t able in t he pubs dat abase. However , when y ou want t o
rem ove all t he rows fr om a t able w it h m any rows, t wo ot her
t echniques will do t he j ob fast er . I nv oke t he TRUNCATE
TABLE st at em ent t o rem ove all t he rows fr om a t able w it hout
logging t he delet ions t o t he log file while preserv ing t he
t able’s design. Alt er nat iv ely , you can inv ok e t he DROP TABLE
st at em ent t o rem ove concur rent ly t he cont ent s and t he
design for a t able.
The last part of t he following script cr eat es a st or ed procedur e t hat rem ov es t he
row wit h a Cont act I D colum n v alue of 3 by applying t he DELETE st at em ent . Then
t he script execut es t he st ored procedure t o r em ov e t he r ow w it h a Cont act I D
value of 3. Finally t he script concludes by inv ok ing a SELECT st at em ent t hat
displays t he r em aining r ows in t he Em ailCont act s t able. Figure 4- 4, aft er t he
script , shows t he t hr ee result set s it produces.
--CreateudpInsertUpdateDeleteSamples
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
           FROM INFORMATION_SCHEMA.ROUTINES
           WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
           ROUTINE_NAME = ’udpInsertUpdateDeleteSamples’)
      DROP PROCEDURE udpInsertUpdateDeleteSamples
GO

--Insert into a table via a view.
CREATE PROC udpInsertUpdateDeleteSamples
AS
INSERT INTO vewEmailContacts
(ContactID, FirstName, LastName, Email1)
VALUES (3, ’Tony’, ’Hill’, ’tony@cabinc.net’)
GO

--Confirm new result set.
EXEC udpInsertUpdateDeleteSamples
SELECT * FROM EmailContacts
GO

--Modify table column values via a view.
ALTER PROC udpInsertUpdateDeleteSamples
AS
UPDATE vewEmailContacts
SET FirstName = ’Anthony’, Email1 = ’anthony@cabinc.net’
WHERE ContactID = 3
GO

--Confirm new result set.
EXEC udpInsertUpdateDeleteSamples
SELECT *
FROM vewEmailContacts
GO

--Delete newly added row directly from table.
ALTER PROC udpInsertUpdateDeleteSamples
AS
DELETE
FROM EmailContacts
WHERE ContactID = 3
GO

--Confirm new result set.
EXEC udpInsertUpdateDeleteSamples
SELECT * FROM EmailContacts
GO


 Figu re 4 - 4 . Th e r et u r n from view s t h a t su cce ssive ly in ser t , u pd at e , a n d
                             de le t e r ow s from a row sou r ce .




Pe r f or m in g D a t a ba se M a in t e n a n ce w it h Pa r a m e t e r s

Ty pically, y ou won’t r un dat a m anipulat ion st at em ent s, such as I NSERT I NTO,
UPDATE, and DELETE, wit h const ant s as in t he preceding sam ple. The purpose for
t he preceding scr ipt was t o pr ov ide a basis for describing t he sy nt ax for including
dat a m anipulat ion st at em ent s in st ored procedures. The real pow er of st ored
procedur es w it h t hese st at em ent s is t hat y ou can pass param et ers t o t he
procedur es t o specify t he rows t hat t he st at em ent s insert , updat e, or delet e fr om
a row source.
The sam ple script in t his sect ion builds on t he prior one by dem onst rat ing t he
synt ax for using param et ers w it h dat a m anipulat ion st at em ent s. Again, t he
em phasis is on clarit y, so t he scr ipt accom plishes t he sam e k ind of t ask s as t he
preceding one. A significant change, how ev er , is t hat t he t arget row source is
from anot her dat abase on t he sam e serv er— t he Nort hwind SQL Ser ver dat abase.
The script in t his sect ion follows t he m odel of t he pr ev ious one by alt er ing one
st ored procedure inst ead of cr eat ing t hr ee separat e st ored pr ocedur es— one for
insert ing, anot her for updat ing, and a t hird for delet ing. Because of t he sim ilar it y
of t his script ’s design t o t he pr eceding one, I w ill explain j ust t he first part of t he
script for insert ing a new r ecord. Lik e t he preceding sam ple, t his one swit ches
back and fort h bet w een using a t able and a v iew as a r ow source for t he dat a
m anipulat ion st at em ent s. This is t o reinforce y our underst anding t hat y ou can
perform dat abase m aint enance chores w it h eit her t ype of obj ect serv ing as a row
source.
Aft er rem ov ing any prior v ersion of t he udpPar am sForI nsert Updat eDelet e st or ed
procedur e, t he script cr eat es a new v ersion t hat includes an I NSERT I NTO
st at em ent . The CREATE PROC st at em ent for creat ing t he st ored procedure has
t wo input param et ers— one for t he Com pany Nam e colum n value and anot her for
t he Phone colum n value. A com m a delim it s t he t wo par am et er declarat ions. The
dat a t ype set t ings follow t hose for t he colum ns in t he Nort hw ind Shippers t able.
The param et er nam es appear again in parent heses aft er t he VALUES k eyword.
These param et ers replace t he st r ing const ant s used in t he pr eceding script
sam ple. The code illust r at ing t he sy nt ax for t he UPDATE and DELETE st at em ent s
follows t he sam e pat t er n. First it declares t he param et er . Second it uses t he
param et ers as var iables in dat abase m aint enance st at em ent s.
The EXEC st at em ent for t he st or ed procedur e specifies values for passing t o t he
st ored procedure. This is one way y our Visual Basic .NET applicat ions can use
values ent ered by users as part of dat a m anipulat ion st at em ent s. Chapt er 10
illust rat es how t o use Visual Basic .Net for t his kind of t ask. The user input set s
t he param et er v alues in t he code t hat calls t he st ored procedure. Aft er adding t he
new record t o t he Shippers t able in t he Nort hw ind dat abase by calling t he st or ed
procedur e, t he script invok es a SELECT st at em ent t o display all t he r ows in t he
Shippers t able.
--CreateudpParamsForInsertUpdateDelete
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
             FROM INFORMATION_SCHEMA.ROUTINES
             WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
             ROUTINE_NAME = ’udpParamsForInsertUpdateDelete’)
       DROP PROCEDURE udpParamsForInsertUpdateDelete
GO

--Insert values into a table in another database.
CREATE PROC udpParamsForInsertUpdateDelete
@newCompanyName nvarchar(40),
@newPhone nvarchar (24)
AS
INSERT INTO Northwind..Shippers
(CompanyName, Phone)
VALUES (@newCompanyName, @newPhone)
GO

--Confirm new result set.
EXEC udpParamsForInsertUpdateDelete
    ’CAB Delivers’, ’(123) 456-7890’
SELECT *
FROM Northwind..Shippers
GO

--Modify table column values in another database
--via a view pointing at the table in this database.
ALTER PROC udpParamsForInsertUpdateDelete
@newPhone nvarchar(24),
@newCompanyName nvarchar(40)
AS
UPDATE vewShippers
SET Phone = @newPhone
WHERE CompanyName = @newCompanyName
GO

--Confirm new result set.
EXEC udpParamsForInsertUpdateDelete
    ’(234) 567-8901’, ’CAB Delivers’
SELECT *
FROM vewShippers
GO

--Delete newly added row in other database
--from view pointing at row in this database.
ALTER PROC udpParamsForInsertUpdateDelete
@newCompanyName nvarchar(40)
AS
DELETE
FROM vewShippers
WHERE CompanyName = @newCompanyName
GO

--Delete newly added row directly from table.
EXEC udpParamsForInsertUpdateDelete ’CAB Delivers’
SELECT * FROM Northwind..Shippers
GO




Pr ogra m m in g Con dit iona l Resu lt Se t s
Ev en t hough a st or ed pr ocedure is com piled, it can st ill ex ecut e in differ ent ways
at run t im e, depending on t he v alues of param et ers. The preceding sect ion
show ed how t o accom plish t his for insert / updat e/ delet e operat ions. This sect ion
shows how you can m odify t he out put fr om a procedur e at r un t im e in a m ore
advanced way t han set t ing values for WHERE clause expressions. This sect ion
st art s wit h a sam ple t hat list s t he v iews in a dat abase. I f t her e are no views in
t he dat abase, it doesn’t display t he colum n headers for it em izing v iews. The
second and t hird sam ples show how t o ret urn t he t op x rows wit h a SELECT
st at em ent . Users can vary t he num ber of r ows r et ur ned.

Con dit iona lly List in g Obj e ct s

A SELECT st at em ent displays t he colum n headers for a r esult set ev en if t he
result set is em pt y. I f y ou happen t o be ret ur ning m ult iple result set s from a
st ored procedure, t he w rit ing of headers for em pt y result set s can clut t er t he
Result s pane and dist ract at t ent ion from populat ed r esult set s. I n any event , y ou
m ay pr efer t o avoid pr int ing t he colum n headers for an em pt y result set — aft er
all, t her e’s not hing t o it em ize below t he header s.
The sam ple for t his sect ion t est s whet her t he result set for a SELECT st at em ent
has any r ows before sending it s out put t o t he Result s pane. The logic is t o
perform an aggregat e query t hat t est s for t he exist ence of it em s sat isfy ing a
WHERE clause cr it er ion. I f t he count of r et urned rows is gr eat er t han 0, t he
procedur e ex ecut es a SELECT st at em ent t hat r et urns t he indiv idual it em s.
Ot herwise, t he st or ed procedur e j ust wr it es a st at em ent t o t he Messages pane
saying t her e are no it em s in t he result set .
This sam ple enum erat es t he views in a dat abase connect ion. A USE st at em ent at
t he t op of t he script specifies t he t arget dat abase. This book has t w o cust om
dat abases so far. The dat abase for t his chapt er, Chapt er04, has nine v iews.
Chapt er01, t he dat abase for t his book ’s first chapt er, has zer o v iews. Ther efor e,
by changing t he USE st at em ent t o point at one or t he ot her dat abase, t he sam ple
script can dem onst rat e condit ional out put s fr om t he sam ple st ored pr oj ect .
The st or ed procedure uses a local var iable, @int Views, t o st ore t he result fr om a
SELECT st at em ent w it h a COUNT funct ion. The funct ion aggregat es t he num ber of
virt ual t ables ( or v iews) in a dat abase. The I NFORMATI ON_SCHEMA.TABLES v iew
is t he row source for t he SELECT st at em ent . An I F…ELSE st at em ent branches t o
t he I F block or t he ELSE st at em ent depending on t he value of @int View s. I f t he
local v ar iable is great er t han 0, t he pr ocedur e execut es t he BEGI N…END block in
t he I F clause of t he I F…ELSE st at em ent . Whenever y ou need t o condit ionally
ex ecut e m ore t han one st at em ent in eit her clause of an I F…ELSE st at em ent , y ou
m ust group t he st at em ent s bet w een BEGI N and END k eywords as t he sam ple
dem onst rat es.
The t wo st at em ent s in t he BEGI N…END block pr int t he num ber of v iews in t he
dat abase connect ion t o t he Messages pane and show t he r esult set for a SELECT
st at em ent list ing t he indiv idual v iew nam es in t he Result s pane. I f @int Views is 0,
t he procedure m er ely pr int s a sent ence t o t he Messages pane say ing t her e are no
views. Because t his requir es j ust one st at em ent , t he ELSE clause doesn’t require
a BEGI N…END block. To unclut t er t he Messages pane, t he procedure invok es t he
SET NOCOUNT ON st at em ent at it s st art and rest or es t he default set t ing ( SET
NOCOUNT OFF) at it s close.
Because t he st ored procedur e for t his sam ple is m eant for a one- t im e execut ion,
t he script dr ops t he st or ed pr ocedur e at it s conclusion. Ther efore, t he st or ed
procedur e isn’t st r ict ly necessary for t his sam ple. Feel free t o m odify t he sam ple
t o r em ov e t he creat ion of t he st or ed pr ocedur e. I n any ev ent , lear n t he I F…ELSE
design guidelines pr esent ed in t he sam ple.
--CreateudpCountAndListViews
--Designate database context.
USE Chapter04
GO

--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
        FROM INFORMATION_SCHEMA.ROUTINES
        WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
        ROUTINE_NAME = ’udpCountAndListViews’)
    DROP PROCEDURE udpCountAndListViews
GO

--Create procedure to count and list views in the
--current database connection.
CREATE PROC udpCountAndListViews
AS
SET NOCOUNT ON
DECLARE @intViews int
SET @intViews = (SELECT COUNT(TABLE_NAME)
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = ’VIEW’ AND
        LEFT(TABLE_NAME,3) <> ’sys’)
IF (@intViews) > 0
BEGIN
    PRINT ’There were ’ +
        CAST(@intViews AS varchar(3)) + ’ views in the connection.’
    SELECT TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = ’VIEW’ AND
           LEFT(TABLE_NAME,3) <> ’sys’
END
ELSE
    PRINT ’There are no views in the connection.’
SET NOCOUNT OFF
GO

--Run the procedure to report on the views in
--the current database connection.
EXEC udpCountAndListViews
GO

--Drop the procedure from the current database connection.
DROP PROCEDURE udpCountAndListViews
GO


Re t u r n ing X I t e m s w it h t he TOP Pr e dica t e

A t y pical r equest on SQL Serv er newsgr oups is, “How do I r et ur n j ust t he t op x
it em s, where I can var y t he value of x?” The quest ion is som et im es phr ased as,
“How do I use t he TOP predicat e t o r et ur n a variable num ber of it em s from a row
source?” The TOP pr edicat e alone can’t solv e t his problem because it can accept
only a const ant as t he num ber of it em s t o ret ur n.
One w ay t o use a TOP predicat e t o ret ur n m ore t han a single num ber of it em s
from a row source is t o nest SELECT st at em ent s wit h TOP predicat es w it hin t he
clauses of an I F…ELSE st at em ent . Because y ou can nest I F…ELSE st at em ent s
wit hin one anot her indefinit ely , t his approach perm it s y ou t o fine- t une t he lev el of
precision on how m any rows t o r et ur n if y ou ar e w illing t o nest enough I F…ELSE
st at em ent s w it hin one anot her.
The next sam ple ret urns eit her t he t op 5 or 10 orders w it h t he longest delay in
shipping aft er t he required dat e for an order. An input param et er value cont r ols
which of t hese t w o result set s t he st ored pr ocedur e ret urns. I f t he input
param et er, @Num berOfOrders, is less t han or equal t o 5, t he st or ed pr ocedur e
ret ur ns t he 5 orders w it h t he longest delays in shipping. I f t he value of
@Num berOfOrders is 6 or gr eat er, t he pr ocedur e ret urns t he 10 orders wit h t he
longest delays in shipping. This is t he first sam ple in t he chapt er t o assign a
default v alue t o a param et er. The equal sign in t he param et er declarat ion shows
t he synt ax for assigning a default value of 5. Because of t his default value, t he
procedur e ret urns t he 5 r ecords w it h t he longest delays if t he EXEC st at em ent
t hat invokes t he udpLongest Lat eOrdersWit hTop st ored procedure fails t o
designat e a param et er value.
A single I F…ELSE st at em ent passes cont rol t o one of t he t wo SELECT st at em ent s
in it s clauses based on t he @Num ber OfOrders param et er value. The SELECT
st at em ent in t he I F clause uses a TOP pr edicat e wit h an argum ent of 5. On t he
ot her hand, t he SELECT st at em ent in t he ELSE clause has exact ly t he sam e
synt ax except t hat it s TOP predicat e has an argum ent of 10.
The EXEC st at em ent for inv ok ing t he st or ed pr ocedur e passes t he param et er
value 7. Because t his is great er t han 5, t he procedur e ret ur ns t he 10 or ders w it h
t he longest shipping delays aft er t he required dat e. The param et er value 100,
1,000, or 10,000 w ill st ill ret ur n j ust 10 r ows in t he r esult set . This is because t he
st ored procedure support s j ust t wo different TOP pr edicat e argum ent v alues. You
can alt er t he procedure by adding nest ed I F…ELSE st at em ent s t o accom m odat e
m or e TOP pr edicat e argum ent values.
--CreateudpLongestLateOrdersWithTop
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
             FROM INFORMATION_SCHEMA.ROUTINES
         WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
         ROUTINE_NAME = ’udpLongestLateOrdersWithTop’)
     DROP PROCEDURE udpLongestLateOrdersWithTop
GO

--Create proc for itemizing late orders
--with one of two TOP predicates.
CREATE PROC udpLongestLateOrdersWithTop
@NumberOfOrders int = 5
AS
IF @NumberOfOrders <= 5
SELECT TOP 5 OrderID,
     CAST((RequiredDate - ShippedDate) AS int)
         ’Days shipped after required’,
     CustomerID
FROM Northwind..Orders
WHERE (RequiredDate - ShippedDate) IS NOT NULL
ORDER BY (RequiredDate - ShippedDate)
ELSE
SELECT TOP 10 OrderID,
     CAST((RequiredDate - ShippedDate) AS int)
         ’Days shipped after required’,
     CustomerID
FROM Northwind..Orders
WHERE (RequiredDate - ShippedDate) IS NOT NULL
ORDER BY (RequiredDate - ShippedDate)
GO

--Run proc to list orders with the shipped
--date farthest behind the required date with
--one of two TOP predicates.
EXEC udpLongestLateOrdersWithTop 7
GO



Re t u r n ing X I t e m s w it h SET ROW COUN T

The SET ROWCOUNT st at em ent provides a m or e flex ible t echnique for ret ur ning a
variable num ber of r ecords fr om som e SELECT st at em ent s. The SET ROWCOUNT
st at em ent can st op a T- SQL st at em ent aft er a fixed num ber of rows.
Furt herm or e, t he argum ent for t he SET ROWCOUNT st at em ent can be a
param et er. This perm it s your applicat ion t o set t he num ber of r ows t o r et ur n at
run t im e.
The follow ing scr ipt dem onst rat es t he synt ax for r et urning a var iable num ber of
rows shipped aft er t heir r equired dat e. Because t his script uses t he SET
ROWCOUNT st at em ent , it can r et urn a var iable num ber of rows wit h j ust a single
SELECT st at em ent . Before t he SELECT st at em ent , t he st or ed procedure assigns
t he @Num ber OfOrders param et er as t he argum ent for t he SET ROWCOUNT
st at em ent . The declarat ion for t he @Num berOfOrders param et er again assigns
t he default value 5 t o t he param et er . Ther efor e, t he pr ocedur e w ill ret ur n five
rows ev en if a user fails t o set a param et er w hen inv ok ing t he st ored pr ocedur e.

                                    N ot e
The SET ROWCOUNT st at em ent will overr ide a TOP predicat e
argum ent if t he SET ROWCOUNT argum ent is t he sm aller of
t he t wo.
The EXEC st at em ent for t he st or ed procedur e designat es t he param et er value 7—
j ust lik e t he pr eceding sam ple script . How ev er, in t his inst ance, t he st or ed
procedur e ret urns precisely 7 r ows inst ead 10 r ows. Furt herm or e, t he SELECT
st at em ent will always ret ur n t he pr ecise num ber of r ows designat ed by t he
param et er value up t o t he m ax im um num ber of rows available fr om t he SELECT
st at em ent wit hout a SET ROWCOUNT st at em ent .
--CreateudpLongestLateOrdersWithoutTop
--Remove prior version of stored procedure.
IF EXISTS (SELECT ROUTINE_NAME
              FROM INFORMATION_SCHEMA.ROUTINES
              WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
              ROUTINE_NAME = ’udpLongestLateOrdersWithoutTop’)
       DROP PROCEDURE udpLongestLateOrdersWithoutTop
GO

--Create proc for itemizing late orders.
CREATE PROC udpLongestLateOrdersWithoutTop
@NumberOfOrders int = 5
AS
SET ROWCOUNT @NumberOfOrders
SELECT OrderID,
    CAST((RequiredDate - ShippedDate) AS int)
        ’Days shipped after required date’,
    CustomerID
FROM Northwind..Orders
WHERE (RequiredDate - ShippedDate) IS NOT NULL
ORDER BY (RequiredDate - ShippedDate)
GO

--Run proc to list seven orders with the shipped
--date farthest behind the required date.
EXEC udpLongestLateOrdersWithoutTop 7
GO
Cha pt e r 5 . Pr ogr a m m ing Use r - D e fine d
Fun ct ions a nd Tr igge r s
This chapt er com plet es t he book’s review of dat abase obj ect s t hat facilit at e t he
reuse of T- SQL code. The beginning of t he chapt er int roduces user - defined
funct ions ( UDFs) . Your applicat ions can apply UDFs as if t hey wer e built - in
funct ions. The chapt er ex plor es t he different kinds of UDFs t hat you can creat e
and illust rat es scenar ios for dev eloping and applying t hem . The last part of t he
chapt er deals w it h t riggers. Visual Basic dev elopers ar e lik ely t o find it useful t o
t hink of t r iggers as event pr ocedur es for t ables and v iews. This chapt er ’s
coverage of t r iggers st art s wit h an ov er view of t he key concept s for designing and
apply ing t riggers and concludes w it h a ser ies of four sam ples t hat dem onst rat e
t he k inds of uses t o which you can put t r iggers. The m ain purpose of t he sam ples
is t o highlight sy nt ax conv ent ions for different t ypes of t r iggers and illust rat e
broad design issues. The T- SQL inside a t r igger can r eference ot her dat abase
obj ect s. For exam ple, t he last t r igger sam ple r eferences a UDF defined earlier in
t he chapt er.
The resources for t his chapt er include t he Chapt er05 dat abase, wit h com plet ed
versions of t he sam ple UDFs discussed as well as T- SQL scr ipt s for creat ing t he
UDFs and t r iggers from scrat ch. Unless explicit ly st at ed, all script s are t o be r un
from t he Chapt er05 dat abase. I f you r un t he script s from anot her dat abase
cont ext , such as t he m ast er dat abase, you can generat e err ors unr elat ed t o t he
sam ple logic and sy nt ax . See t he “ Chapt er Resources” sect ion in Chapt er 2 for
m or e det ail on at t aching dat abase files t o a server and creat ing a new blank
dat abase fr om w hich you can inv ok e t he script s. This chapt er also refer ences t he
SQL Ser ver Nort hwind dat abase. This dat abase is inst alled w it h SQL Ser ver 2000.




I n t r odu ct ion t o User - D e fin ed Fu n ct ion s
A user- defined funct ion perm it s a dev eloper t o save a body of T- SQL code and
t hen reuse it . UDFs can ret ur n bot h scalar values and t ables. I n fact , SQL Serv er
2000 int roduces a new dat a t ype, t able, for represent ing t he ret urn of a t able
from a UDF. Visual Basic developers w ill feel com fort able w it h UDFs because in
m any ways t hey perform lik e funct ion pr ocedur es in Visual Basic. You can pass
UDF values t hrough par am et ers, and t hey r et urn a value— nam ely, a scalar value
or a t able.

                                    N ot e
The t able dat a t y pe wasn’t discussed in t he rev iew of dat a
t y pes in Chapt er 2 because t hat chapt er focuses on t he
cr eat ion of perm anent t ables t hat ar e part of a dat abase. You
can refer t o a per m anent t able dir ect ly. Perm anent t ables
cannot include colum ns wit h a t able dat a t y pe. A t able
ret ur ned by a UDF isn’t perm anent . The ret urned t able is
available only t hrough t he UDF t hat ret ur ns it . Many uses for
t em por ary t ables can be served by t ables ret urned from
UDFs. You can also use t he t able dat a t ype in st ored
procedures and T- SQL bat ches. Sear ch for “t able dat a t ype”
fr om t he I ndex t ab of Books Online for m ore det ails on t his
dat a t ype.

Ov e r vie w of UD F Type s

SQL Ser ver 2000 offers t hree t ypes of UDFs:

    •   You can wr it e a scalar funct ion t o ret ur n a scalar value, such as a
        conv ersion rout ine for r epr esent ing t he value of Br it ish pounds in U.S.
        dollars or Fahr enheit degrees in Cent igrade degrees.
    •   A UDF can ret urn a t able based on a single SELECT st at em ent . SQL Server
        calls t his an inline t able- valued funct ion.
    •   Wit h a m ult ist at em ent t able- valued funct ion, y ou can declar e t he colum ns
        and com pose a UDF ret ur n based on m ult iple st at em ent s. For exam ple,
        you can insert r esult set s from t wo or m or e SELECT st at em ent s in t he
        t able r et ur ned by a UDF. I n addit ion, m ult ist at em ent t able- valued
        funct ions don’t rest r ict you t o SELECT st at em ent s for populat ing t he
        ret ur ned t able.

Sca la r UD Fs

A scalar UDF r et urns a single value. The com put at ions inside a UDF cannot affect
any ent it y out side t he UDF. SQL Serv er docum ent at ion refers t o t his pr opert y as
UDFs hav ing no side effect s. The num ber of input param et ers for a UDF can range
from 0 t hr ough 1024. Just as wit h input param et ers for st ored pr ocedures, you
can assign default values for UDF input param et ers. UDF param et ers don’t
support user - defined or t im est am p dat a t ypes. I n addit ion, UDF param et ers
cannot be nonscalar, such as a t able- valued UDF. The r et urn from a UDF can
hav e any colum n dat a t ype except t ext , nt ext , im age, and t im est am p. UDFs don’t
support out put param et ers. A UDF’s r et urn value is it s sole form of out put .
You can use a scalar UDF any wher e in a UDF t hat you can use a scalar value,
such as t he list for a SELECT st at em ent . Ot her uses for scalar UDFs include
argum ent s in WHERE, HAVI NG, ORDER BY, and GROUP BY clause expr essions.
Your code can also put scalar UDFs t o use in SET st at em ent s for local v ariables in
st ored procedures and T- SQL bat ch scr ipt s wit hin Query Analy zer. I n addit ion,
UDFs are useful wit hin dat a m anipulat ion st at em ent s for adding new v alues and
updat ing ex ist ing ones. Yet anot her UDF applicat ion is inside t able declarat ions
for check const raint s and com put ed values. When using UDFs for com put ed
colum ns w it h indexes, t he UDF m ust be det erm inist ic— t hat is, it m ust always
ret ur n t he sam e value giv en t he sam e input .

                                    N ot e
Det er m inism is a r elat ively new concept for funct ions, v iews,
and st or ed procedures. See t he “Det er m inist ic and
Nondet er m inist ic Funct ions” t opic in Book s Online for an
int roduct ion t o t his t opic for SQL Ser ver 2000.

I nlin e Ta ble - V alu e d UDFs

An inline t able- valued UDF perform s sim ilar ly t o a v iew. I t differs from a scalar
UDF in t hat t he inline UDF r et ur ns a t able inst ead of a scalar value. Bot h t ypes of
UDF can accept input param et ers. Because a v iew and an inline UDF depend on a
single SELECT st at em ent — but t he UDF accept s a param et er— t he inline UDF
offers t he funct ionalit y of a param et erized v iew . I n addit ion, a v iew can serv e as
t he source for an inline UDF. I f your v iew inv olv es a com plex JOI N st at em ent w it h
index es and t herefore schem a binding, t he inline UDF can deliv er t he power of
t he v iew wit h a m uch sim pler sy nt ax t han t he T- SQL st at em ent under ly ing t he
view, and it offers t he advant ages of select ions based on param et ers. You can
inv oke I NSERT, UPDATE, and DELETE st at em ent s wit h inline t able- valued UDFs
serv ing as a source in t he FROM clause prov ided t he inline t able- valued UDF
draws on a SELECT st at em ent or a v iew t hat perm it s dat a m anipulat ion.

                                        N ot e
See a discussion of issues t hat enable updat able views in t he
“Rem arks” sect ion of t he Books Online “CREATE VI EW” t opic.
See also t he “Rules for Updat ing Result s” t opic in Book s
Online for guidance on SELECT st at em ent s t hat gener at e
updat able result set s.

M u lt ist a t em e n t Tab le - V alu e d UD Fs

Mult ist at em ent t able- valued UDFs and inline t able- v alued UDFs bot h r et ur n
t ables, but t her e are t w o im port ant differ ences. First , as t he nam e im plies, y ou
can use m ult iple st at em ent s t o define t he r esult set fr om a m ult ist at em ent t able-
valued UDF. I n addit ion t o m ult iple SELECT st at em ent s, y ou can draw on ot her T-
SQL st at em ent s, such as DECLARE and assignm ent st at em ent s; I F…ELSE
st at em ent s; and I NSERT, UPDATE, and DELETE st at em ent s for t able variables
local t o t he funct ion. Second, m ult ist at em ent t able- valued UDFs ret ur n read- only
t ables. Recall t hat inline t able- valued UDFs per m it updat ing t heir base t ables
t hr ough t he UDF.

St a t e m e nt s for Cr e a t in g a nd M a n a gin g UD Fs

You can cr eat e and m anipulat e UDFs w it h st at em ent s perform ing fam iliar
funct ions for ot her SQL Ser ver dat abase obj ect s. These st at em ent s ar e CREATE
FUNCTI ON, ALTER FUNCTI ON, and DROP FUNCTI ON. Because of t he divergence
in t ypes of UDFs, t he sy nt ax for t he CREATE FUNCTI ON and ALTER FUNCTI ON
st at em ent s differs as w ell; t her e ar e t hr ee variat ions of each of t hese t wo
st at em ent s t o m at ch t he corr esponding UDF t y pes. I n cont rast , a single DROP
FUNCTI ON sy nt ax suffices for all t hr ee UDF t ypes. Trail t he keyword phrase w it h
t he nam e of t he funct ion t hat y ou want r em ov ed fr om a dat abase. You can use
t he I NFORMATI ON_SCHEMA. ROUTI NES v iew t o det ect t he ex ist ence of a
prev iously exist ing version of a UDF.
The CREATE FUNCTI ON st at em ent for a scalar UDF has sev eral im port ant
argum ent s wit h a variet y of var iat ions bey ond t hose depict ed in t he follow ing
t em plat e. The funct ion_nam e argum ent is a st andard SQL Serv er ident ifier .
Howev er, as w it h ot her obj ect s, you m ay care t o use a prefix t o m ak e it easy t o
ident ify UDF obj ect s vs. ot her t ypes of obj ect s. This chapt er uses udf as t he first
t hr ee charact ers of all UDF nam es.
The input param et ers for a UDF r eside w it hin parent heses follow ing t he funct ion
nam e. St art each param et er nam e wit h t he @ sign, and t hen m ake t he rest of t he
param et er nam e charact ers follow SQL Serv er ident ifier r ules. Designat e a dat a
t ype for each par am et er wit h a space delim it er aft er t he param et er nam e. Delim it
m ult iple param et er declarat ions wit h com m as. You can opt ionally designat e a
default v alue for param et ers wit h an equal sign ( = ) follow ed by a value aft er t he
dat a t ype specificat ion for any param et er w it h a default v alue.
Designat e a dat a t ype for t he scalar UDF w it h t he RETURNS keyword. The
RETURNS k eyw ord and it s t railing dat a t ype specificat ion m ake up t he RETURNS
clause w it hin t he CREATE FUNCTI ON st at em ent . Use t he AS keyword t o m ark t he
t ransit ion from funct ion declar at ions t o T- SQL code for t he funct ion.
The T- SQL code for a scalar UDF m ust appear bet ween BEGI N and END keywords.
The RETURN k eyw ord w it hin t he BEGI N…END block m ar ks t he ex pr ession t hat
specifies t he ret urn value from t he scalar UDF. The RETURN k eyw ord and it s
expression argum ent ar e anot her cr it ical clause wit hin t he CREATE FUNCTI ON
st at em ent , as show n in t his code t em plat e:
CREATE FUNCTION
function_name (parameter_names and data types)

RETURNS
data type for return value
AS
BEGIN

T-SQL statements for UDF
    RETURN (expression for scalar return value)

END

The follow ing CREATE FUNCTI ON st at em ent t em plat e illust rat es t he sy nt ax for
creat ing an inline t able- valued UDF. The funct ion nam e and param et er
declarat ions follow t he sam e conv ent ions as for t he CREATE FUNCTI ON st at em ent
for a scalar UDF. The RETURNS and TABLE key words t oget her m ake up t he
RETURNS clause for an inline UDF. This clause designat es a t able as t he r et urn
dat a t ype fr om t he UDF. The t em plat e follows t he ret ur n dat a t ype specificat ion
wit h t he AS k eyw ord t hat m arks t he t ransit ion bet ween t he declarat ions and t he
T- SQL code for t he funct ion. When you’r e gener at ing an inline t able- v alued UDF,
t he only T- SQL code is a single SELECT st at em ent t hat serv es as t he argum ent
for t he RETURN k eyw ord. The SELECT st at em ent is t he equiv alent of t he
expression for t he scalar r et urn v alue in t he pr eceding t em plat e.
CREATE FUNCTION
function_name (parameter_names and data types)
RETURNS TABLE
AS
RETURN
(SELECT statement)


The CREATE FUNCTI ON t em plat e for a m ult ist at em ent t able- v alued UDF t hat
appears next has a different design from t hat of eit her of t he t wo pr eceding
t em plat es. I n fact , t he t em plat e bor r ows elem ent s fr om each of t he pr eceding
t em plat es and adds it s own unique elem ent . The funct ion nam e and param et er
declarat ions ar e t he sam e as in t he preceding t wo t em plat es. The RETURNS
keyw ord denot es a t able dat a t ype ( w it h t he TABLE keyw ord) as t he ret ur n dat a
t ype for t he funct ion. The synt ax of a CREATE FUNCTI ON st at em ent for a
m ult ist at em ent t able- valued UDF r equires a t able nam e bet w een t he RETURNS
keyw ord and t he TABLE keyword. The t able nam e follows t he sam e conv ent ions
as param et ers and local var iables. ( Don’t forget t he leading @ sign. ) Anot her
unique elem ent of t he CREATE FUNCTI ON t em plat e for a m ult ist at em ent t able-
valued UDF is t he colum n declarat ions ar ea t hat appears aft er t he TABLE k eyw ord
specify ing t he ret urn dat a t ype and t he AS k ey word. Colum n declarat ions include
colum n nam es, dat a t ype specificat ions, and opt ional colum n specificat ions for
t he prim ary key , a unique index, or a check const raint . The RETURNS clause for a
m ult ist at em ent t able- valued UDF st art s wit h t he RETURNS k eyw ord and r uns
t hr ough t he colum n specificat ions. The T- SQL st at em ent s in t he BEGI N…END
block m ust include one or m ore I NSERT st at em ent s t hat r efer back t o t he t able
nam e in t he RETURNS clause. These I NSERT st at em ent s populat e t he t able
ret ur ned by t he UDF. The T- SQL code in your BEGI N…END block can opt ionally
include UPDATE and DELETE st at em ent s t hat assist in r efining t he result set
ret ur ned by t he UDF. The RETURN keyw ord wit hin t he BEGI N…END block signals
t he end of processing in t he UDF.
CREATE FUNCTION
function_name (parameter_names and data types)
RETURNS
table_name TABLE

(column declarations)
AS
BEGIN

T-SQL statements for UDF
RETURN
END

CREATE FUNCTI ON st at em ent s support t he assignm ent of t w o opt ional funct ion
specificat ions, using t he keywords ENCRYPTI ON and SCHEMABI NDI NG. Designat e
eit her of t hese specificat ions follow ing a WI TH k eyw ord. Place t he designat ion
j ust befor e t he AS k eyw ord. I f you inv ok e t he ENCRYPTI ON opt ion, r em em ber t o
preserv e an unencrypt ed version of y our funct ion for fut ure edit ing. Aft er
inv ok ing t he SCHEMABI NDI NG opt ion for a UDF, any t ables or v iews on which t he
funct ion relies cannot change unt il y ou eit her drop t he UDF or m odify t he UDF
wit h t he ALTER FUNCTI ON st at em ent . Sev eral special r ules apply when y ou apply
t he SCHEMABI NDI NG opt ion t o a funct ion. See t he “ Argum ent s” sect ion of t he
“CREATE FUNCTI ON” t opic in Books Online for t he r ules.

Com pa r ing UD Fs w it h Vie w s a n d St or e d Pr oce du r e s

UDFs share elem ent s in com m on w it h bot h v iew s and st or ed procedur es. On t he
ot her hand, UDFs also differ from v iews and st ored pr ocedures in som e im port ant
way s. Underst anding t hese sim ilar it ies and differences will help you decide w hen
t o choose each k ind of obj ect for a dat abase chore and whet her it is appropr iat e
t o r eform ulat e an obj ect in one form at t o anot her form at .
Views and t able- valued UDFs bot h hav e result set s. I n addit ion, t he inline t able-
valued UDF ev en r elies on a single SELECT st at em ent j ust lik e a v iew. The
sim ilar it ies bet w een inline t able- valued UDFs and v iews m eans t hat y ou can use
eit her for v iew ing and updat ing dat a. An im port ant dist inct ion is t hat t he inline
t able- v alued UDF perm it s input param et ers in it s SELECT st at em ent . Ther efor e,
an inline t able- valued funct ion deliv ers t he feat ures of a v iew w it h t he added
flex ibilit y afforded by param et ers. The m ult ist at em ent t able- valued funct ion has
it s ow n colum n declarat ions, and it can cont ain m ult iple SELECT st at em ent s as
well as ot her k inds of T- SQL st at em ent s t hat m odify t he values ret urned by t he
funct ion. These ext ra st at em ent s pr ov ide added flex ibilit y for t he creat ion of t he
result set from a m ult ist at em ent t able- valued UDF r elat ive t o eit her an inline
t able- v alued UDF or a view. On t he ot her hand, your applicat ions can never
m odify t he base t ables for a m ult ist at em ent t able- valued UDF t hrough t he UDF.
St or ed pr ocedur es can r et ur n scalar values and result set s j ust as UDFs can. I n
addit ion, bot h st or ed pr ocedur es and UDFs accept param et ers t hat t he obj ect s
can use t o help com put e out put s. St ored pr ocedur es can ret ur n one or m ore
result set s, but t able- valued UDFs always r et ur n a single result set . The result
set s from a st or ed procedure ar e available for view ing in Quer y Analyzer when
you run a st or ed pr ocedur e, and you can pass t he r esult set s t o t em por ary t ables
for addit ional pr ogram m at ic m anipulat ion. The r esult set from t able- valued UDFs
is available for use direct ly in t he FROM clause of SELECT st at em ent s.
Addit ionally, you m ust pass scalar r et urns from st ored procedures t o local
variables befor e y ou can program m at ically m anipulat e t hem out side t he st or ed
procedur e. On t he ot her hand, you can use a scalar UDF j ust lik e a scalar value in
a T- SQL script . St or ed procedures do count er t hese UDF advant ages by offer ing a
richer array of out put t y pes. I n addit ion t o offer ing m ult iple result set s, a st ored
procedur e can concur rent ly ret ur n a r esult set , m ult iple out put param et ers, and a
ret ur n st at us value. UDFs don’t offer t his r ichness of out put t ypes.




Cr e a t in g a n d I nvok in g Sca la r UD Fs
Scalar UDFs are a flex ible developm ent t ool. This is for t wo prim ary r easons.
First , t hey m ak e it easy t o encapsulat e T- SQL st at em ent s for reuse. Second, it is
sim ple t o r eference scalar UDFs in T- SQL script s and ot her SQL Serv er obj ect s.
Three scalar funct ion sam ples in t his sect ion confir m how easy it is t o encapsulat e
T- SQL expr essions in UDF funct ions. The sect ion also highlight s ways of
referencing scalar UDFs in different T- SQL cont ext s.

Cr e a t in g a Sca la r UD F W it hou t Pa r a m e t e r s

Scalar funct ions can com put e all k inds of result s. I t is com m on in dat abase
applicat ions t o need t he next higher num ber in a ser ies, such as w hen one or
m or e rows in a child t able need a for eign k ey value m at ching t he ident it y colum n
value for t he row m ost r ecent ly insert ed int o a parent t able. The @@I DENTI TY
funct ion can supply t his value aut om at ically w hen y ou ar e insert ing new r ows int o
a t able. However, t her e are t im es w hen t he r et urn value from t he @@I DENTI TY
funct ion isn’t desir able because y our applicat ion needs t o add r efinem ent s t o t he
basic behav ior. Ev en out side t he aut oincrem ent ing cont ext , an applicat ion can
readily r equir e t he next higher value in a series. The sam ple in t his sect ion shows
how t o sat isfy t his requirem ent w it h a scalar UDF.
The follow ing scr ipt creat es a t able w it h a single colum n, col1, and t hen populat es
t he colum n w it h five row values: 1, 5, 9, 4, 12. I NSERT I NTO st at em ent s add t he
values t o t he t able. Because t he r ow values ar e pr im ar y k ey values, any SELECT
st at em ent wit hout an ORDER BY clause for t he t able ar ranges t he r ows in
ascending order fr om 1 t hr ough 12.
Aft er creat ing and populat ing t he t able, t he script adds a new scalar UDF t o t he
Chapt er05 dat abase. The USE st at em ent at t he t op of t he scr ipt set s t he dat abase
cont ext for t his sam ple. All t he ot her sam ples in t his chapt er ar e for t he sam e
dat abase cont ext , alt hough subsequent sam ples don’t explicit ly include t he USE
st at em ent for t he Chapt er05 dat abase. By checking t he
I NFORMATI ON_SCHEMA.ROUTI NES v iews, t he script can det ect w het her a pr ior
version of t he udfOneHigherThanMax UDF ex ist s in t he Chapt er05 dat abase. I f
one already ex ist s, t he script r em oves it w it h t he DROP FUNCTI ON st at em ent .
Next t he CREATE FUNCTI ON st at em ent dem onst rat es t he applicat ion of basic UDF
specificat ions. Befor e dwelling on t he st at em ent ’s form at , not ice t he GO k eyw ord
im m ediat ely pr eceding it . A CREATE FUNCTI ON st at em ent m ust st art it s ow n T-
SQL bat ch. Not ice also t hat par ent heses follow t he funct ion nam e. Par ent heses
are necessary w het her or not y our UDF has par am et ers. The RETURNS st at em ent
declares t he scalar ret ur n value from t he funct ion as an int dat a t ype. This is
consist ent w it h t he dat a t ype for t he col1 colum n in t he MyTable t able creat ed
and populat ed ear lier in t he sam ple. The scalar UDF has j ust a single operat ional
st at em ent t hat select s t he m ax im um v alue fr om t he col1 colum n in t he My Table
t able and t hen adds 1 t o it . However, t he synt ax r ules for all scalar UDFs requir e
t he st andard AS keyw or d and a BEGI N…END block. The SELECT st at em ent for
com put ing t he int eger 1 higher t han t he m ax im um in col1 appears w it hin
parent heses in t he RETURN clause for t he CREATE FUNCTI ON st at em ent . The
expression w it hin t he clause com put es t he value t hat t he scalar UDF r et ur ns.
Aft er t he CREATE FUNCTI ON st at em ent , a T- SQL script inv ok es t he scalar UDF
inside a SELECT st at em ent . This r et ur ns t he value 13 in a result set w it h one row
and one colum n. Not ice t he ow ner specificat ion for t he UDF— nam ely , dbo. Recall
t hat dbo designat es any m em ber of t he sysadm in fix ed serv er r ole w ho creat es
an obj ect . Funct ion nam es m ust be unique for a dat abase by t he funct ion’s
owner.

                                    N ot e
By default , per m ission t o creat e a UDF is available t o
m em bers of t he sy sadm in fix ed server role as well as t he
db_owner and db_ddladm in fixed dat abase roles. Mem ber s of
t he sysadm in and db_owner roles can grant per m ission t o
cr eat e UDFs t o ot her logins. See t he “Perm issions” sect ion in
t he “CREATE FUNCTI ON” Books Online t opic for m or e det ail
about perm issions t o creat e and adm inist er UDFs. The Books
Online t opics for all dat a definit ion language ( DDL) T- SQL
st at em ent s hav e a “Per m issions” sect ion. Chapt er 7 drills
down on SQL Serv er securit y .
--udfHigherThanMax
--Specify database context.
USE Chapter05

--Remove prior version of table MyTable.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = ’MyTable’)
DROP TABLE MyTable

--Create table MyTable.
CREATE TABLE MyTable
(
col1 int PRIMARY KEY
)
GO

--Populate MyTable with either 4 or 5 rows.
--Comment out last INSERT INTO statement for 4 rows.
INSERT INTO MyTable VALUES(1)
INSERT INTO MyTable VALUES(5)
INSERT INTO MyTable VALUES(9)
INSERT INTO MyTable VALUES(4)
INSERT INTO MyTable VALUES(12)
GO

--Drop old version of user-defined function if it exists.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_NAME = ’udfOneHigherThanMax’)
    DROP FUNCTION udfOneHigherThanMax
GO

--Create function to find value 1 greater than maximum.
CREATE FUNCTION udfOneHigherThanMax()
RETURNS int
AS
BEGIN
    RETURN(SELECT MAX(col1)+1 FROM MyTable)
END
GO

--Must reference function owner’s name (dbo) for syntax to work.
SELECT dbo.udfOneHigherThanMax()
GO



Cr e a t in g a Sca la r UD F w it h a Pa r a m e t e r

Redesigning t he udfOneHigher ThanMax UDF w it h an input param et er can achiev e
t wo benefit s. First , t he r edesign dem onst rat es t he det ailed synt ax for passing
param et ers t o funct ions. Second, t he redesign offers t he opport unit y t o cr eat e a
new scalar UDF t hat r et ur ns a value t hat is x unit s higher t han t he cur rent
m axim um col1 colum n value.
The follow ing scr ipt illust rat es how t o achiev e bot h of t hese benefit s. The script
st art s by dropping any prior v ersions of t he udfXHigher ThanMax UDF if it ex ist s.
Next t he CREATE FUNCTI ON st art s t he design of a new scalar UDF. The
parent heses aft er t he funct ion nam e include a param et er declarat ion. Recall t hat
t he init ial sam ple included t he par ent heses, but t hey didn’t enclose any t hing. The
nam e of t he param et er for t his UDF is @x, and it s dat a t ype is int , which m at ches
t he dat a t ype of t he values in col1. The m at ching dat a t ype specificat ion for t he
colum n values and t he param et er elim inat es t he need for a conv ersion when t he
funct ion adds @x t o t he m ax im um value in t he col1 colum n.
Wit h t he udfXHigherThanMax UDF, users can specify t he r et urn of a value @x
unit s higher t han t he m axim um value in col1. The SELECT st at em ent aft er t he
CREATE FUNCTI ON st at em ent illust rat es t he sy nt ax for passing a param et er t o a
funct ion. Sim ply enclose t he value in par ent heses aft er t he funct ion nam e. The
sam ple denot es a param et er value of 2, but any param et er value t hat yields a
legit im at e int value for t he UDF is accept able. All part s of t he funct ion call are
m andat ory. First y ou m ust specify a funct ion owner; t he sam ple designat es t he
dbo user. Second, aft er t he funct ion nam e, y ou m ust include par ent heses. When
t here is a param et er ( as in t his inst ance) , you m ust specify a par am et er value
unless t he param et er has a default value in it s declar at ion.
--udfXHigherThanMax
--Drop old version of user-defined function if it exists.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
       WHERE ROUTINE_NAME = ’udfXHigherThanMax’)
       DROP FUNCTION udfXHigherThanMax
GO

--Create function to compute x units higher than maximum.
--Demonstrates use of parameters.
CREATE FUNCTION udfXHigherThanMax(@x AS int)
RETURNS int
AS
BEGIN
    Return(SELECT MAX(col1) + @x FROM MyTable)
END
GO

--Must reference function owner’s name (dbo) for syntax to work.
SELECT dbo.udfXHigherThanMax(2)
GO
Usin g Sca la r UD Fs in T- SQL Scr ipt s

The first t wo sam ples highlight ed t he sy nt ax for creat ing scalar UDFs. However,
t hey m er ely echoed t he ret ur n value fr om t he UDF. One significant r eason for
using UDFs is t heir abilit y t o be used direct ly in T- SQL st at em ent s. This sect ion
creat es a new UDF and illust rat es t he sy nt ax for r efer encing t he UDF at several
locat ions w it hin a SELECT st at em ent as well as in a T- SQL script wit h an I F…ELSE
st at em ent and in st r ing expr essions for local var iables.
The udfDaysShippedLat e scalar UDF ret ur ns t he num bers of day s t hat an order
shipped before or aft er it s required dat e. Aft er r em oving any prior v ersion of t he
scalar UDF, t he pr ocedure inv ok es t he CREATE FUNCTI ON st at em ent t o st art t he
creat ion of t he new v ersion of t he udfDaysShippedLat e UDF. This UDF r equires
t hr ee it em s t o com put e it s r et ur n value: t he order I D, t he requir ed dat e, and t he
shipped dat e for t he order . The UDF accept s t he order I D as a param et er nam ed
@Tar get I D. Two SELECT st at em ent s r et ur n t he r equired and shipped dat es fr om
t he Orders t able in t he Nort hw ind dat abase. Alt hough t he dat abase cont ex t for
t he funct ion is t he Chapt er05 dat abase, t he UDF can r efer t o t he Nort hwind
dat abase using t he st andard t hr ee- part nam ing conv ent ion. The built - in
DATEDI FF funct ion com put es t he differ ence in days bet ween t he r equired and
shipped dat es so t hat orders shipping aft er t he required dat e hav e a posit iv e
value. The scr ipt uses t he r et ur n fr om t he built - in funct ion w it h it s argum ent s as
t he expression for t he RETURN clause. This clause passes back a value from t he
scalar UDF.
--udfDaysShippedLate_a
--Drop old version of user-defined function if it exists.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
             WHERE ROUTINE_NAME = ’udfDaysShippedLate’)
       DROP FUNCTION udfDaysShippedLate
GO

--Create function to compute difference in days between
--required date and shipped date for an order.
CREATE FUNCTION udfDaysShippedLate(@TargetID AS int)
RETURNS int
AS
BEGIN
DECLARE @TargetShippedDate datetime
DECLARE @TargetRequiredDate datetime

SET @TargetShippedDate = (SELECT ShippedDate
    FROM Northwind..Orders
    WHERE OrderID = @TargetID)
SET @TargetRequiredDate = (SELECT RequiredDate
    FROM Northwind..Orders
    WHERE OrderID = @TargetID)
RETURN (DATEDIFF(d, @TargetRequiredDate, @TargetShippedDate))
END
GO

The next script is a SELECT st at em ent t hat dem onst rat es t he synt ax for
referencing a scalar UDF in t he list for t he st at em ent and in t he WHERE and
ORDER BY clauses of t he st at em ent . The list for t he st at em ent includes four
colum ns for each order: OrderI D, t he udfDaysShippedLat e v alue, t he shipped
dat e, and t he r equir ed dat e. The input param et er specified for t he scalar UDF is
OrderI D. This causes t he UDF t o ret ur n t he differ ence bet ween t he requir ed and
shipped dat es for t he or der on each row of t he SELECT st at em ent ’s r esult set .
The FROM clause designat es t he Orders t able in t he Nort hw ind dat abase.
Wit hout any addit ional clauses, t he list and t he FROM clause for t he SELECT
st at em ent would ret urn a row for each row in t he Orders t able w it h r ow s
arranged by OrderI D value, t he pr im ar y k ey for t he Orders t able. How ever, t he
t wo addit ional clauses change t his. First , t he WHERE clause causes t he st at em ent
t o r et urn rows j ust for t hose orders t hat shipped one or m or e days aft er t he
requir ed dat e. The udfDaysShippedLat e UDF helps t o specify t he expression for
t he clause. The UDF’s r epresent at ion is t he sam e as in t he SELECT st at em ent ’s
list . Second, t he ORDER BY clause specifies t hat t he rows in t he r esult set be
sort ed fr om t he order t hat shipped t he lat est t o t he order t hat shipped t he least
lat e.
--udfDaysShippedLate_b
--Syntax for user-defined function in list, WHERE, and
--ORDER BY clauses of SELECT statement to return
--orders shipped after required date.
SELECT OrderID, dbo.udfDaysShippedLate(OrderID) ’Days Shipped Late’,
       LEFT(ShippedDate, 11) ’Shipped Date’,
       LEFT(RequiredDate, 11) ’Required Date’
FROM Northwind..Orders
WHERE dbo.udfDaysShippedLate(OrderID) > 0
ORDER BY dbo.udfDaysShippedLate(OrderID) DESC

Figur e 5- 1 shows an ex cerpt from t he result set for t he pr eceding SELECT
st at em ent . The second colum n shows t he r et ur n values fr om t he UDF. You can
confirm it s calculat ion w it h t he help of t he last t wo colum ns. Not ice also t hat rows
appear in order based on t he value in t he second colum n, w hich display s t he UDF
values for each row. Figur e 5- 1 shows t he Result s pane. How ev er, t he Messages
pane cont ains t he num ber of r ows affect ed, or r et urned, by t he SELECT
st at em ent . I t is only 37, which is subst ant ially less t han t he full num ber of 830
rows in t he or iginal Orders t able.

  Figu re 5 - 1 . An e xce r pt fr om a r esu lt se t ba se d on a SELECT st a t e m e n t
   t h at u ses a sca la r UD F in it s list a s w e ll as it s W H ERE a n d ORD ER BY
                                          cla u se s.




The next script shows anot her t ype of applicat ion for t he udfDaysShippedLat e
UDF. This script uses t he UDF in an expression t hat serves as t he condit ion for an
I F…ELSE st at em ent . Because t he value for t he UDF appears elsew her e in t he
script besides t he condit ion for t he I F…ELSE st at em ent , t he script sav es t he UDF’s
value in a local var iable, @DaysBefor eAft er . This assignm ent saves hav ing t o
recom put e t he funct ion each t im e t he script needs t he UDF’s value.
The script com put es and displays one of t wo possible m essages based on t he
udfDaysShippedLat e UDF value. I f t he scalar UDF value is negat iv e, t he order
shipped before t he requir ed dat e. Ot herw ise, t he order shipped on or aft er t he
requir ed dat e. The expr ession for t he I F…ELSE st at em ent capt ur es whet her t he
order shipped befor e or aft er t he required dat e. The I F clause of t he st at em ent
com put es a st at em ent saying how m any days befor e t he requir ed dat e an order
shipped. This can be any value fr om 1 day t hrough t he m ax im um num ber of days
in t he Orders t able t hat an order shipped befor e it s r equir ed dat e. The ELSE
clause com put es a st at em ent det ailing how m any days aft er t he r equir ed dat e an
order shipped. The st ring expressions in t he I F and ELSE clauses bot h refer ence
t he @DaysBeforeAft er local var iable, w hich t he script uses t o st or e t he ret ur n
value from t he udfDaysShippedLat e UDF.
To see t he script in oper at ion, y ou need t o run it wit h OrderI D values for orders
shipping before and aft er t heir r equir ed dat es. The sam ple script includes t wo
such OrderI D values. As t he script appears below, it com put es a m essage for
OrderI D 10777, w hich shipped 23 day s aft er it s r equired dat e. You can com m ent
out t he SET st at em ent assigning 10777 t o t he @Tar get I D local var iable and
rem ov e t he com m ent m ark ers for t he SET st at em ent assigning 10248 t o t he local
variable. This act ion per m it s you t o run t he script in a m ode t hat com put es a
m essage for t he num ber of days t hat an order shipped before it s required dat e.
I n t his inst ance, t he order shipped 16 days before it s requir ed dat e.
--udfDaysShippedLate_c
--Invoke a user-defined function to compute a conditional message
--for the number of days that an order ships before or after its
--required date.
DECLARE @TargetID int
DECLARE @DaysBeforeAfter int
DECLARE @ShipMessage varchar (1000)

--Order 10248 shipped 16 days before its required date.
--Order 10777 shipped 23 days after its required date.
--SET @TargetID = 10248
SET @TargetID = 10777

--Save user-defined function value for reuse in script.
SET @DaysBeforeAfter = dbo.udfDaysShippedLate(@TargetID)

--Branch to compute one of two message formats based on the
--user-defined function value.
IF @DaysBeforeAfter < 0
     BEGIN
         SET @ShipMessage = ’Order ’ + CAST(@TargetID AS varchar) +
             ’ shipped ’ + CAST(-1 * @DaysBeforeAfter AS varchar) +
             ’ days before the required date.’
         Print @ShipMessage
     END
ELSE
     BEGIN
         SET @ShipMessage = ’Order ’ + CAST(@TargetID AS varchar) +
             ’ shipped ’ + CAST(@DaysBeforeAfter AS varchar) +
             ’ days after the required date.’
         Print @ShipMessage
     END
GO




Cr e a t in g a n d I nvok in g Ta ble - Va lu ed UD Fs
Bot h inline UDFs and m ult ist at em ent UDFs can ret ur n t ables inst ead of scalar
values. The inline UDF has t he advant age of an exceedingly sim ple synt ax . I n
addit ion, it support s par am et ers so t hat users can cont r ol it s r esult set at run
t im e. Mult ist at em ent UDFs are subst ant ially m or e flex ible t han inline UDFs. The
ext ra flex ibilit y com es at t he expense of m ore sophist icat ed T- SQL logic. SQL
Ser ver giv es you a choice. You can incorporat e t he t able- valued UDF t hat best fit s
your needs. The sam ples in t his sect ion w ill help you see som e of t he capabilit ies
of bot h appr oaches so t hat y ou can m ake an inform ed choice.

Pr ovidin g Pa r a m e t r ic V ie w s

I nline t able- valued UDFs are alway s based on a single SELECT st at em ent — j ust
lik e a v iew . Howev er, t he inline t able- v alued UDF offers one significant advant age
ov er a v iew. You can pass param et ers t o t he SELECT st at em ent for an inline
t able- v alued UDF, but t he synt ax for t he CREATE VI EW st at em ent offers no
opport unit ies for specify ing param et ers. I nline UDFs height en t he power of t heir
advant age by offer ing it wit h an exceedingly sim ple synt ax . Recall t hat all you
hav e t o do w hen cr eat ing an inline UDF is declar e t he r et ur n dat a t ype as t able in
t he RETURNS clause and t hen specify a SELECT st at em ent as t he argum ent for
t he RETURN clause. You can r eference an inline UDF in T- SQL st at em ent s j ust as
you w ould a v iew except t hat y ou can pass t he inline UDF param et er values.
The follow ing scr ipt illust rat es t he sy nt ax for saving a SELECT st at em ent in a
UDF. The SELECT st at em ent pr ov ides a result set w it h a row for each order by a
cust om er . The synt ax for t he st at em ent j oins t he Cust om ers and Orders t ables in
t he Nort hw ind dat abase. Not ice t hat t he SELECT st at em ent specifies t he input
param et er @Cust I D in it s WHERE clause. The SELECT st at em ent is t he argum ent
for t he RETURN clause in a CREATE FUNCTI ON st at em ent . The par ent heses aft er
t he funct ion nam e t railing t he CREATE FUNCTI ON keyword phrase ar e wher e t he
UDF declar es t he @Cust I D param et er value.
The SELECT st at em ent t hat concludes t he follow ing script illust rat es t he synt ax
for invoking an inline UDF. The sam ple specifies t he ret urn of all t he colum ns
from t he source w it h t he * charact er. You can designat e indiv idual colum ns in t he
list . The FROM clause designat es t he inline UDF as t he source for t he r esult set
from t he SELECT st at em ent . I n t his applicat ion, it isn’t essent ial t hat you specify
t he ow ner for t he UDF. The funct ion’s nam e is sufficient for designat ing an inline
UDF ow ned by t he dbo user . The specificat ion of t he @Cust I D param et er in t he
parent heses aft er t he UDF’s nam e is crit ical because t he funct ion expect s a
param et er value and has no default value. This param et er allows t he funct ion t o
ret ur n t he orders for a part icular cust om er .
--udfOrdersForCustomerID
--Drop old version of user-defined function if it exists.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
             WHERE ROUTINE_NAME = ’udfOrdersForCustomerID’)
       DROP FUNCTION udfOrdersForCustomerID
GO

--Create Inline table-valued function with a parameter.
CREATE FUNCTION udfOrdersForCustomerID(@CustID varchar(5))
RETURNS TABLE
AS
RETURN(
SELECT c.CompanyName, c.ContactName, c.Phone,
        o.OrderID, o.OrderDate
    FROM Northwind..Customers c JOIN Northwind..Orders o
    ON (c.CustomerID = o.CustomerID)
    WHERE c.CustomerID = @CustID
    )
GO

--Specify a parameter for table returned from function.
SELECT *
    FROM udfOrdersForCustomerID(‘BERGS’)
GO
Usin g a Sca la r UD F in t he List f or a n I n lin e UD F

By com bining different t ypes of funct ions, y ou can add consider able flex ibilit y t o
your applicat ions. A scalar UDF r et urns a single value, but t he single value can
change depending on input param et er values. An inline UDF r et ur ns a r esult set
t hat can cont ain m ult iple rows. By condit ioning a scalar UDF on colum n values
from t he r esult set of an inline UDF, y ou can cr eat e new values t hat com bine or
ext end t he values in t he source for t he inline UDF.
The script sam ple in t his sect ion illust rat es how t o use a scalar UDF t o define a
colum n for t he result set fr om an inline UDF. The script also shows how t o use t he
colum n defined by t he scalar UDF in t he WHERE clause for SELECT st at em ent s
inv ok ing t he inline UDF.
The script defines t wo UDFs. The first , udfManagerNam e, is a scalar UDF. This
funct ion ret ur ns t he first and last nam e for an em ployee fr om t he Em ployees
t able in t he Nort hw ind dat abase. An expr ession in t he list for t he SELECT
st at em ent com bines t he First Nam e and Last Nam e fields int o a single scalar value
wit h a space delim it er bet ween t hem . The WHERE clause for t he SELECT
st at em ent includes a param et er for designat ing t he Em ploy eeI D colum n value.
The ret ur n value fr om t he scalar UDF is t he nam e of t he em ploy ee w it h an
Em ploy eeI D colum n value m at ching t he input param et er .
The second UDF in t he follow ing script is an inline UDF, nam ed
udfEm ploy eeExt ensionManager. The SELECT st at em ent for t he inline UDF
specifies t he Em ployees t able in t he Nort hw ind dat abase as it s r ow source. The
list for t he SELECT st at em ent designat es four colum ns. Three com e dir ect ly from
t he r ow source; t hese are an em ploy ee’s first nam e, last nam e, and ex t ension.
The fourt h colum n is t he ret ur n value fr om t he udfManagerNam e UDF. The
param et er value passed t o t he scalar UDF is t he Report sTo colum n v alue from t he
Em ploy ees t able. This colum n value is t he Em ployeeI D for t he m anager t o w hich
an em ploy ee report s. The SELECT st at em ent specifies an alias, Manager ’s Nam e,
for t he udfManager Nam e UDF r et urn value. Not ice t hat y ou can r epresent a single
apost rophe w it hin a st r ing const ant wit h t wo single apost rophes.
--udfEmployeeExtensionManager
--Drop old version of user-defined function if it exists.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
                  WHERE ROUTINE_NAME = ’udfManagerName’)
       DROP FUNCTION udfManagerName
GO

--
Function to return the manager’s name matching a ReportsTo column val
ue.
CREATE FUNCTION udfManagerName (@reportsto int)
RETURNS varchar(40)
AS
BEGIN
    RETURN(SELECT DISTINCT FirstName + ’ ’ + LastName
            FROM Northwind..Employees WHERE
            EmployeeID = @reportsto)
END
GO

--Drop old version of user-defined function if it exists.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
            WHERE ROUTINE_NAME = ’udfEmployeeExtensionManager’)
    DROP FUNCTION udfEmployeeExtensionManager
GO
--Inline table-
valued function to return employee first name, last name,
--extension, and manager’s name.
CREATE FUNCTION udfEmployeeExtensionManager()
RETURNS TABLE
AS
RETURN(SELECT FirstName, LastName, Extension,
        dbo.udfManagerName(ReportsTo) ’Manager’’s Name’
        FROM Northwind..Employees)
GO

--SELECT statement with inline table-
valued function in its FROM clause.
PRINT ’Report for Full udfEmployeeExtensionManager Function’
SELECT *
FROM udfEmployeeExtensionManager()

--Print direct reports to Andrew Fuller.
PRINT ’Report for Andrew Fuller Direct Reports’
SELECT FirstName, LastName, Extension
FROM udfEmployeeExtensionManager()
WHERE [Manager’s Name] = ’Andrew Fuller’

--Print direct reports to Steven Buchanan.
PRINT ’Report for Steven Buchanan Direct Reports’
SELECT FirstName, LastName, Extension
FROM udfEmployeeExtensionManager()
WHERE [Manager’s Name] = ’Steven Buchanan’

--Print direct and indirect reports to Andrew Fuller.
PRINT ’Report for Andrew Fuller Direct and Indirect Reports’
SELECT FirstName, LastName, Extension
FROM udfEmployeeExtensionManager()
WHERE [Manager’s Name] = ’Andrew Fuller’
UNION
SELECT FirstName, LastName, Extension
FROM udfEmployeeExtensionManager()
WHERE [Manager’s Name] = ’Steven Buchanan’

Aft er creat ing t he t wo UDFs, t he script illust rat es wit h four different bat ches how
t o invoke t he inline UDF cont aining a scalar UDF in it s SELECT list . The first bat ch
ret ur ns all t he colum ns for all t he rows in t he r esult set fr om t he inline UDF. This
result set has four colum ns and nine r ows: one colum n for each it em in t he list
for t he SELECT st at em ent of t he inline UDF and one r ow for each row in t he
Em ploy ees t able— t he base t able for t he SELECT st at em ent . The follow ing list ing
shows t he result set s for each of t he four sam ples.
The second and t hird bat ches show how t o refer ence in t he WHERE clause t he
colum n ret ur ned by t he scalar UDF inside t he inline UDF. The sy nt ax for t his
reference uses t he alias nam e for t he funct ion, Manager ’s Nam e, in t he SELECT
list fr om t he inline UDF. The second sam ple r et ur ns all t he direct repor t s t o
Andr ew Fuller. The t hird sam ple r et ur ns t he dir ect report s t o St ev en Buchanan.
Because St ev en Buchanan report s dir ect ly t o Andrew Fuller , t he direct r eport s t o
St even r eport indirect ly t o Andr ew Fuller.
The fourt h bat ch const ruct s a UNI ON query st at em ent t hat r et ur ns all t he
em ploy ees r eport ing direct ly or indirect ly t o Andrew Fuller . The UNI ON operat or
com bines int o one r esult set t he r esult s from t he SELECT st at em ent s in t he
second and t hird sam ples. This final r esult differs fr om t he one for t he first
sam ple in a couple of w ays. First , it cont ains j ust t hree colum ns. Ther e is no need
for a colum n w it h t he m anager’s nam e because all em ploy ees r eport dir ect ly or
indirect ly t o Andr ew Fuller. Second, t his final result set cont ains j ust 8 rows as
opposed t o t he 9 r ows in t he r esult set for t he first sam ple. This is because
Andr ew Fuller doesn’t appear in t he list of em ploy ees r eport ing t o him .
The follow ing list ing present s all t he result set s ret ur ned t o t he Messages pane
when y ou r un t he pr eceding sam ple from Quer y Analyzer w it h a Result s I n Text
set t ing.
Report for Full udfEmployeeExtensionManager Function
FirstName LastName                          Extension Manager’s Name
---------- -------------------- --------- ---------------------------
------
Nancy           Davolio                     5467          Andrew Fuller
Andrew          Fuller                      3457          NULL
Janet           Leverling                   3355          Andrew Fuller
Margaret        Peacock                     5176          Andrew Fuller
Steven          Buchanan                    3453          Andrew Fuller
Michael         Suyama                      428           Steven Buchanan
Robert          King                        465           Steven Buchanan
Laura           Callahan                    2344          Andrew Fuller
Anne            Dodsworth                   452           Steven Buchanan

(9 row(s) affected)

Report for    Andrew Fuller Direct       Reports
FirstName     LastName                   Extension
----------    --------------------       ---------
Nancy         Davolio                    5467
Janet         Leverling                  3355
Margaret      Peacock                    5176
Steven        Buchanan                   3453
Laura         Callahan                   2344

(5 row(s) affected)

Report for    Steven Buchanan Direct Reports
FirstName     LastName             Extension
----------    -------------------- ---------
Michael       Suyama               428
Robert        King                 465
Anne          Dodsworth            452

(3 row(s) affected)

Report for    Andrew Fuller Direct       and Indirect Reports
FirstName     LastName                   Extension
----------    --------------------       ---------
Anne          Dodsworth                  452
Janet         Leverling                  3355
Laura         Callahan                   2344
Margaret      Peacock                    5176
Michael       Suyama                     428
Nancy         Davolio                    5467
Robert        King                       465
Steven        Buchanan                   3453

(8 row(s) affected)



En ca psu la t ing M or e Logic w it h M u lt ist a t e m e nt UD Fs
A m ult ist at em ent t able- valued UDF prov ides subst ant ially m or e flex ibilit y t han is
available from an inline UDF. While an inline UDF rest r ict s you t o a single SELECT
st at em ent , a m ult ist at em ent UDF can cont ain m ult iple SELECT st at em ent s along
wit h ot her k inds of T- SQL st at em ent s. The w ide range of st at em ent s t hat y ou can
place inside a m ult ist at em ent UDF allows you t o creat e m or e flex ible funct ions
t hat can sim plify t he logic of T- SQL st at em ent s t hat r eference t hem or even
recover from invalid input .
The follow ing scr ipt cont ains a m ult ist at em ent UDF t hat can r et ur n t hree different
t ypes of result set s. The UDF accom plishes t his feat w it h t he aid of a couple of
input param et ers and nest ed I F…ELSE st at em ent s t hat t est t he input param et er
values. The @Report sTo param et er designat es t he m anager for w hom t o r et urn a
result set . The par am et er has an int dat a t ype, and it denot es a m anager ’s
em ploy ee I D. The @I ndirect param et er has a bit dat a t y pe. The value 0 is for
dir ect report s, and t he v alue 1 is for t he r et ur n of direct and indirect r eport s. The
logic inside t he CREATE FUNCTI ON st at em ent accom m odat es one invalid pair of
input param et ers t o dem onst rat e w hat y ou can accom plish w it h a m ult ist at em ent
UDF. This logic t raps for a r equest of indir ect report s for t he m anager w hose
Em ploy eeI D value is 5. This r equest is invalid for t he Em ployees t able in t he
Nort hwind dat abase because t his m anager has only dir ect report s. The funct ion
recovers from t he r equest by supply ing only dir ect report s t o t he m anager.
Aft er creat ing t he m ult ist at em ent UDF wit h a CREATE FUNCTI ON st at em ent , t he
script launches four SELECT st at em ent s t hat refer ence t he UDF. The param et ers
for t he SELECT st at em ent s allow y ou t o confirm t he flex ibilit y of t he UDF. The
first SELECT st at em ent ret urns t he direct r eport s t o Andrew Fuller , whose
Em ploy eeI D is 2. The second SELECT st at em ent r et urns t he dir ect report s t o
St even Buchanan, w hose Em ploy eeI D is 5. The t hird SELECT st at em ent includes
t he Em ploy eeI D v alue for Andrew Fuller again, but it set s @I ndir ect t o 1. This
perm it s t he UDF t o ret urn t he result for a union query inst ead of a sim ple
param et er query ( as in t he first t wo SELECT st at em ent s) . The fourt h SELECT
st at em ent r equest s t he dir ect and indirect r epor t s for t he m anager w hose
Em ploy eeI D is 5, nam ely St ev en Buchanan. This request s passes cont rol t o t he
last I F clause in t he UDF and ret urns j ust t he direct r eport s for St ev en Buchanan.
The UDF could hav e pr int ed a cust om m essage wit h t he RAI SERROR st at em ent .
--udfReportsTable
--Drop old version of user-defined function if it exists.
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
                  WHERE ROUTINE_NAME = ’udfReportsTable’)
       DROP FUNCTION udfReportsTable
GO

--Create multistatement table-valued function.
CREATE FUNCTION udfReportsTable(@ReportsTo int, @Indirect bit)
RETURNS @TableOut TABLE(
FirstName varchar(10) NOT NULL,
LastName varchar(20) NOT NULL,
Extension varchar(4) NULL
)
AS
BEGIN
IF @Indirect = 0
     INSERT @TableOut
     SELECT FirstName, LastName, Extension
     FROM Northwind..Employees
     WHERE ReportsTo = @ReportsTo
ELSE
     IF @ReportsTo = 2
         INSERT @TableOut
         SELECT FirstName, LastName, Extension
         FROM Northwind..Employees
            WHERE ReportsTo = @ReportsTo
            UNION
            SELECT FirstName, LastName, Extension
            FROM Northwind..Employees
            WHERE ReportsTo <> @ReportsTo AND
                ReportsTo IS NOT NULL
     ELSE
            IF @ReportsTo = 5
                INSERT @TableOut
                SELECT FirstName, LastName, Extension
                FROM Northwind..Employees
                WHERE ReportsTo = @ReportsTo
RETURN
END
GO

--Print direct reports to Andrew Fuller.
SELECT *
FROM udfReportsTable(2,0)

--Print direct reports to Steven Buchanan.
SELECT *
FROM udfReportsTable(5,0)

--Print direct and indirect reports to Andrew Fuller.
SELECT *
FROM udfReportsTable(2,1)

--Demo recovery from Indirect Reports request for Steven Buchanan.
SELECT *
FROM udfReportsTable(5,1)




I n t r odu ct ion t o Tr igger s
Tr iggers enable developers t o creat e st ored procedur es t hat fir e aut om at ically
when an applicat ion m akes changes t o t ables or v iews t o which t he t riggers
belong. This sect ion int r oduces core concept s about what a t r igger is, t he
different t ypes of t r iggers available t o developers, and st at em ent s for m anaging
t riggers in y our applicat ions.

Tr igge r s Ar e lik e Ev e nt Pr oce du r e s

Visual Basic dev elopers m ay find it conv enient t o t hink of t r iggers as ev ent
procedur es. Tr iggers encapsulat e T- SQL code m uch lik e st ored procedures except
t hat t r iggers fire aut om at ically w hen ev ent s happen for an obj ect t o which t he
t rigger belongs. I t is good pract ice t o back up y our t rigger code independent ly of
t he obj ect s t o w hich t hey belong— especially as you are init ially defining t he
obj ect s for a pr oj ect . This is because dropping an obj ect r em oves any t r iggers
associat ed wit h t he obj ect . Ther e is no war ning m essage about t he ex ist ence of
t rigger code t hat you m ight want t o save before rem ov ing an obj ect .
The ev ent s t hat fir e a t rigger are insert s, updat es, and delet es. Wit h classic
t riggers, t he ev ent s ar e for t ables. These t rigger s act ually fir e aft er t he init iat ion
of a change ev ent but befor e t he com m it m ent of a change t o a dat abase t able.
Wit hin t he code for a classic t rigger, you can per form m any different k inds of
act ions, such as rolling back t he change t o t he t able, perform ing dat a int egrit y
checks, and archiving or iginal and changed dat a. Before t he int r oduct ion of
declarat ive r efer ent ial int egr it y and cascading updat es and delet es, it w as
com m on t o pr ogram t his kind of behav ior w it h t riggers. Ev en now, if an
applicat ion r equires referent ial int egr it y bet w een t w o t ables in different
dat abases, you m ust pr ogram it m anually . Tr iggers r epresent a nat ural place t o
locat e t he code for pr ogram m ing r efer ent ial int egrit y across t wo t ables in
different dat abases.
I t is good pract ice t o k eep y our t r igger code short and uncom plicat ed. This is
because a t rigger fir es whenev er it s ev ent occurs. Ther efor e, an updat e t r igger
fires w henev er a user t r ies t o updat e a value in a t able. The updat e doesn’t
com m it unt il SQL Serv er com plet es t he ex ecut ion of t he code in t he t r igger. I f t he
code pr esent s a m essage t o t he user, y ou especially w ant t o k eep t he code br ief
so t hat t he m essage ret ur ns t o t he user swift ly .
A t r igger does hav e a decided advant age ov er an ev ent pr ocedur e t hat you can
assign t o a form in Visual Basic. This is because t he t r igger always fir es no m at t er
how a user opens t he obj ect wit h t he t r igger. Wit h an ev ent pr ocedur e for a form
t hat uses a SQL Serv er t able for it s r ow source, dat abase users can bypass any
logic in t he ev ent pr ocedur e by opening t he t able dir ect ly or opening t he t able
wit h anot her form or user int erface t hat doesn’t hav e t he event procedur e. When
you code y our change dir ect ly against t he dat abase obj ect w it h a t rigger, t he
code fires no m at t er how users open t he row source.

Ty pe s of Tr igge r s

SQL Ser ver offers t wo basic t ypes of t r iggers. Wit hin each t ype, y ou can hav e
t hr ee event t ypes t hat fire t riggers: insert s, updat es, and delet es. You can cr eat e
a t r igger for any com binat ion of t hese t hr ee event s.
The preceding sect ion briefly descr ibed classic t riggers. This is t he first t ype of
t rigger . SQL Ser ver docum ent at ion r efers t o t his kind of t r igger as an AFTER
t rigger . You can cr eat e an AFTER t rigger only for a t able. The nam e for t he t ype
of t rigger indicat es when t he t rigger fir es— nam ely, aft er t he st art of a change t o
a t able. You can have m ult iple AFTER t riggers for t he sam e change event . Wit h
t he help of t w o syst em st ored procedures, you can designat e t he first and last
t rigger t o fir e for a change event t o an obj ect . By designat ing a first and last
t rigger t o fir e, you can precisely cont r ol t he order in which up t o t hree t riggers
fire. How ev er, rem em ber t hat all t he t r iggers ev ent ually fir e for a change ev ent t o
an obj ect . Ther efore, t he m or e t riggers y ou hav e, t he longer it t akes for SQL
Ser ver t o com m it t he insert , updat e, or delet e act ion. I n addit ion, m ult iple
t riggers can delay cust om m essages sent back t o users.

                                      N ot e
I nv oke t he sp_set t riggerorder syst em st ored pr ocedure t o
cont rol t he or der of execut ion for t riggers. The procedure
t akes t hree argum ent s: one for t he t r igger nam e, anot her for
t he order of firing, and t he t hird for t he t ype of event .
The second t ype of t r igger is an I NSTEAD OF t r igger. You can cr eat e I NSTEAD OF
t riggers for bot h t ables and v iews. This t ype of t rigger fir es before t he change
ev ent for t he obj ect . Ther efor e, you cannot roll back a change t o a t able or v iew
from an I NSTEAD OF t rigger because t he ev ent didn’t occur y et . Howev er , y ou
can com plet e t he act ion, or an alt ernat iv e one, from w it hin t he t r igger code.
Unlike AFTER t riggers, only one I NSTEAD OF t r igger can ex ist for each t ype of
change event . I f you apply a change event t o a view and per m it direct access t o
any base t ables for t he view, users can bypass t he t r igger for t he v iew by opening
t he base t ables.
in se r t e d a nd de le t e d Ta ble s

The insert ed and delet ed t ables ar e t wo logical t ables available w it hin a t rigger.
The t ables hav e t he sam e st r uct ur e as t he t able or v iew t o which a t r igger
belongs. Each of t he t hr ee change ev ent s im pact s t he cont ent s of t he insert ed
and delet ed t ables differ ent ly . These t ables are conv enient for archiving changes
t o a t able. You can select which colum ns y ou ar chiv e and add any dat a t hat y our
requir em ent s dict at e, such as user ident ificat ion, dat e, and t im e.
An I NSERT st at em ent populat es t he insert ed t able. I NSERT st at em ent s don’t
populat e t he delet ed t able. The new colum n values for t he insert ed row ar e in t he
insert ed t able.
A DELETE st at em ent populat es t he delet ed t able, but t he st at em ent leaves t he
insert ed t able em pt y . The delet ed t able w ill have as m any r ows as t he DELETE
st at em ent r em oves from t he t able. The TRUNCATE TABLE st at em ent doesn’t log
changes t o t he delet ed t able or fir e t r iggers. I n addit ion, t he DROP TABLE
st at em ent doesn’t fir e a t rigger. I nst ead, t he st at em ent rem ov es t he t rigger along
wit h t he t able.
An UPDATE st at em ent populat es bot h t he insert ed and delet ed t ables. The r ows
wit h t he new values ar e in t he insert ed t able. The r ows w it h t he old values are in
t he delet ed t able. As w it h t he DELETE st at em ent , t he insert ed and delet ed t ables
can cont ain m ult iple rows for a single UPDATE st at em ent .

St a t e m e nt s for Cr e a t in g a nd D r oppin g Tr igge r s

An array of T- SQL st at em ent s ex ist for creat ing and m anaging t riggers. Many of
t hese st at em ent s parallel t hose for ot her dat abase obj ect s, but som e are special
for t r iggers. ( For exam ple, y ou already r ead about t he sp_set t r iggerorder syst em
st ored procedure.) You can m ak e new t r iggers wit h t he CREATE TRI GGER
st at em ent . This single T- SQL st at em ent facilit at es t he cr eat ion of AFTER and
I NSTEAD OF t riggers by t he inclusion of a k eyw ord phrase specify ing t he t r igger
t ype. The DROP TRI GGER st at em ent works for eit her t ype of t rigger, but t her e is
no I NFORMATI ON_SCHEMA v iew t hat displays t he t r iggers in a dat abase. The
follow ing sam ples dem onst rat e an appr oach t o checking for t he exist ence of a
t rigger based on t he sysobj ect s t able in a dat abase. I t is som et im es conv enient t o
disable a t r igger ( for ex am ple, t o ent er new r ows int o a t able t hat conflict wit h
t he logic in t he t r igger) . Use t he ALTER TABLE st at em ent w it h t he DI SABLE
keyw ord follow ed by t he t r igger nam e t o disable an ex ist ing t r igger . To r est or e
t he t r igger, specify t he ENABLE keyw ord follow ed by t he t rigger ’s nam e w it hin an
ALTER TABLE st at em ent .
The CREATE TRI GGER st at em ent is flex ible because a single t em plat e
accom m odat es bot h AFTER and I NSTEAD OF t r iggers. I n addit ion, y ou can specify
eit her t r igger t ype for any com binat ion of t he t hr ee possible event s t hat can fire
it . The t r igger nam e follow ing t he CREATE TRI GGER k eyw ord phrase is a norm al
SQL Ser ver ident ifier. To m ak e t r igger nam es ident ify t heir obj ect t ype, t his
chapt er begins t r igger nam es w it h t he t rg pr efix . Designat e t he obj ect t o w hich a
t rigger belongs in t he ON clause. Specify t he obj ect by following t he ON keyword
wit h t he nam e of a t able or v iew .
The next line is w her e t he CREATE TRI GGER st at em ent offers m uch of it s
flex ibilit y. You can st art t he line w it h eit her t he AFTER k ey word or t he I NSTEAD
OF k eyw ord phrase t o declare t he t rigger t ype. Because AFTER is t he default
t rigger t ype, y ou don’t need t o specify t he AFTER k eyw ord t o creat e an AFTER
t rigger . The FOR clause specifies t he t ype of event s t hat w ill fir e an AFTER
t rigger . The synt ax for t he I NSTEAD OF k eyw or d doesn’t requir e t he FOR k eyword
( as is t he case for AFTER t r iggers) . The follow ing code t em plat e shows all t hr ee
ev ent s. Howev er, you can designat e any t wo or j ust one ev ent . The ev ent nam es
in t he FOR clause det er m ine what act ions fire a t r igger. The AS keyw or d m arks
t he t ransit ion fr om t he t rigger declarat ions t o t he T- SQL code t hat a t r igger
ex ecut es when it fir es.
CREATE TRIGGER trigger_name

ON tablename or viewname
AFTER OR INSTEAD OF OR FOR INSERT, UPDATE, DELETE
AS
T-SQL statements for trigger

CREATE TRI GGER w ill fail if you t ry t o cr eat e a new t rigger w it h a nam e for a
prev iously exist ing t r igger . Ther e are a couple of workarounds t o t his pr oblem .
First , you can m odify t he design of t he old t rigger w it h t he ALTER TRI GGER
st at em ent . Second, you can condit ionally dr op t he old version of a t r igger. The
synt ax for checking on t he ex ist ence of a previously exist ing t r igger is different
from t hat for t ables, v iews, st ored procedur es, and UDFs. This is because t here is
no I NFORMATI ON_SCHEMA v iew for list ing t r iggers. However, y ou can use t he
nam e and t ype colum ns of t he sysobj ect s t able t o v er ify t he exist ence of a
prev iously exist ing version of a t rigger in a dat abase. The sysobj ect s t able is a
t able m aint ained by SQL Serv er t hat keeps t rack of t he obj ect s in a dat abase. I n
t he follow ing t em plat e, cont r ol passes t o t he DROP TRI GGER st at em ent only if t he
sysobj ect s t able cont ains a row w it h a nam e colum n value equal t o t r igger nam e
and a t ype value equal t o TR.
IF EXISTS (SELECT name FROM sysobjects
           WHERE name = ’triggername’ AND type = ’TR’)
       DROP TRIGGER triggername

You can use t he sam e synt ax for ver ify ing t he exist ence of m any ot her dat abase
obj ect s. Change t ype t o V for views and P for st or ed procedur es. Use FN, I F, and
TF for scalar, inline, and m ult ist at em ent UDFs, r espect iv ely.




Cr e a t in g a n d Ma na gin g Tr igger s
Tr iggers ar e a valuable t ool for m anaging your dat abases. The “I nt r oduct ion t o
Tr iggers” sect ion r ev iew ed t he basic concept s for using t r iggers, som e pot ent ial
applicat ions, and basic synt ax issues. This sect ion pr ov ides four sam ples t hat
illust rat e t he synt ax for using t r iggers in dat abase applicat ions. The sam ples
aren’t as im port ant t hem selv es as t he issues t hat t hey fram e, such as how t o use
t he insert ed and delet ed t ables and how t o enforce business rules. Rev iew t he
sam ples t o rapidly ram p up t o speed on cor e t r igger design and applicat ion
issues. Then adapt and ext end t he sam ples for your ow n applicat ion developm ent
needs.

Pr ot e ct in g a n d Un pr ot e ct in g a Ta ble fr om Ch a n ge s

Because t r iggers can fir e w henev er t here is an at t em pt t o change a t able, it is
possible t o wr it e a t r igger t hat guards t he cont ent s of a t able. For exam ple, y ou
can block all at t em pt s t o m odify t he cont ent s of a t able. You can select iv ely
rest r ict t he abilit y t o delet e r ows, change colum n values in rows, or insert new
rows int o a t able wit h AFTER t riggers. You can prot ect a t able’s cont ent s
uncondit ionally, or you can condit ion t he pr ot ect ion on a user’s m em bership in
secur it y roles, t he t im e of day , day of t he week , or what ever. I f y ou elect t o block
m odificat ions wit h a t rigger t o a t able uncondit ionally , y ou w ill probably encount er
a need t o disable t he t r igger occasionally. Disabling a t r igger allows y ou t o
reinv ok e it easily w it hout hav ing t o r e- creat e or m odify it in any way . To r einv ok e
a disabled t r igger, all y ou hav e t o do is enable it . Recall t hat you can disable and
enable a t r igger w it h an ALTER TABLE st at em ent for t he t able w it h t he t rigger
t hat y ou want t o disable t em porarily.
The follow ing scr ipt dem onst rat es t he synt ax for cr eat ing a t rigger for t he
MyTable t able cr eat ed earlier in t his chapt er. ( See t he “Cr eat ing a Scalar UDF
Wit hout Param et ers” sect ion.) The t r igger pr ot ect s t he t able fr om insert s,
updat es, and delet es by rolling back t he t ransact ion associat ed w it h t he t r igger.
The script st art s by r em ov ing any previous version of t he
t rgKeepMyTableUnt ouched t r igger and t hen begins a CREATE TRI GGER
st at em ent . Lik e m ost ot her CREATE st at em ent s, t he CREATE TRI GGER st at em ent
m ust occur at t he t op of a bat ch. Therefore, t he code t o drop t he old version ends
wit h t he GO k eyw ord. The ON clause of t he CREATE TRI GGER st at em ent
designat es t he MyTable t able as t he one t o w hich t he t r igger w ill belong. The FOR
clause indicat es t hat t he t r igger w ill fir e for insert , updat e, and delet e ev ent s.
The first st at em ent aft er t he AS k eyw ord is a RAI SERROR st at em ent t hat sends a
cust om m essage back t o t he Messages pane of Query Analyzer. An inform at ional
m essage issued from a t rigger is useful for let t ing a user k now t hat a t r igger
fired. The RAI SERROR st at em ent can serv e ot her funct ions as well, but it is a
robust alt er nat iv e t o t he PRI NT st at em ent for sending m essages t o t he Messages
pane. The st r ing for a cust om m essage can be up t o 400 charact ers. The t railing
values 16 and 1 indicat e t he sever it y and st at e for t he err or. For sim ple
inform at ional m essages, y ou can consist ent ly apply t hese v alues. The second T-
SQL st at em ent in t he script r olls back t he t ransact ion t o m odify t he t able. The
ROLLBACK TRAN st at em ent is an abbrev iat ed version of t he ROLLBACK
TRANSACTI ON st at em ent . I n eit her form , t his st at em ent rem ov es any insert ed
rows, r est or es any colum n values t o t heir nonupdat ed st at e, and adds back any
delet ed r ows. You w ill generally want t o use t he ROLLBACK TRAN st at em ent as
t he last st at em ent in a t rigger because any st at em ent s aft er ROLLBACK TRAN can
m odify t he t able for a t r igger.
--trgKeepMyTableUntouched
--Drop prior version of trigger.
IF EXISTS (SELECT name FROM sysobjects
            WHERE name = ’trgKeepMyTableUntouched’ AND type = ’TR’)
       DROP TRIGGER trgKeepMyTableUntouched
GO

--Create new trigger to keep MyTable table untouched.
CREATE TRIGGER trgKeepMyTableUntouched
ON MyTable
FOR INSERT, UPDATE, DELETE
AS
RAISERROR(‘Message from trgKeepMyTableUntouched.’,16,1)
ROLLBACK TRAN
GO

The follow ing scr ipt is a collect ion of T- SQL st at em ent s t hat dem onst rat es t he
behav ior of t he t rigger as well as how t o disable and rest ore t he t r igger. The first
couple of bat ches in t he script at t em pt t o delet e all r ows fr om t he My Table t able
and m odify a colum n value in t he t able. Neit her bat ch succeeds because t he
t rgKeepMyTableUnt ouched t r igger pr ot ect s t he MyTable t able fr om delet e and
updat e ev ent s ( as w ell as insert ev ent s) .
I f it becom es essent ial t o m odify a t able wit h a t rigger t hat blocks changes, y ou
can t em porar ily disable t he t r igger. The script dem onst rat es t he synt ax for t he
t rgKeepMyTableUnt ouched t r igger . You have t o m odify t he My Table t able w it h t he
ALTER TABLE st at em ent t o disable it s t r igger. Aft er disabling t he t r igger, t he
script changes t he m axim um v alue in t he col1 colum n. Then, in anot her bat ch,
t he script r est or es t he init ial m ax im um value. The script s use a scalar UDF
dev eloped ear lier in t his chapt er t o accom plish t hese t asks. Aft er successfully
m odify ing t he t able w it h t he t r igger disabled, t he script enables t he t rigger again
for t he MyTable t able w it h t he ALTER TABLE st at em ent . Just t o confirm t he
t rigger ’s operat ion, t he script again at t em pt s t o delet e all rows fr om t he t able.
The t rigger fir es and pr int s it s inform at ional m essage and rolls back t he
t ransact ion t o rem ov e t he r ows from t he t able.
--Demo_trgKeepMyTableUntouched
--An attempt to delete all records fails with
--trigger error message.
DELETE
FROM MyTable
GO

--An attempt to update the maximum value in
--col1 in the MyTable table fails also.
UPDATE MyTable
SET col1 = dbo.udfOneHigherThanMax()
WHERE col1 = (SELECT MAX(col1) FROM MyTable)
GO

--Disable the trigger for MyTable without dropping it.
ALTER TABLE MyTable
Disable TRIGGER trgKeepMyTableUntouched
GO

--Update attempt for MyTable succeeds.
UPDATE MyTable
SET col1 = dbo.udfOneHigherThanMax()
WHERE col1 = (SELECT MAX(col1) FROM MyTable)

SELECT * FROM MyTable
GO

--Restoring update event also succeeds.
UPDATE MyTable
SET col1 = dbo.udfOneHigherThanMax() - 2
WHERE col1 = (SELECT MAX(col1) FROM MyTable)

SELECT * FROM MyTable
GO

--Re-enable trigger.
ALTER TABLE MyTable
Enable TRIGGER trgKeepMyTableUntouched
GO

--An attempt to delete all records fails again
--with trigger error message.
DELETE
FROM MyTable
GO



Ar ch ivin g Ch a n ge s t o a Ta ble

The logical t ables insert ed and delet ed cont ain t he changes t hat users m ake t o a
t able. Unfort unat ely, t he insert ed and delet ed t ables are available only for t he
t im e t hat a t r igger has cont rol of an applicat ion. When t he t r igger closes, SQL
Ser ver in effect clears t he t ables. I f y ou want t o persist som e subset of t he
changes t o a t able for perm anent ready access, you can use t r iggers t o save t he
cont ent s of t he logical insert ed and delet ed t ables t o a t able in a SQL Ser ver
dat abase. Because changes ( insert s, updat es, and delet es) affect t he insert ed and
delet ed t ables different ly, one approach is t o cr eat e a separat e t r igger for each
t ype of change. This sim plifies t he t rigger logic, and it m ak es each t ype of change
run fast er t han hav ing one t rigger t hat decipher s t he t y pe of change and t hen
archiv es t he insert ed and delet ed t ables properly.
The follow ing scr ipt creat es t hr ee t r iggers t o log insert s, updat es, and delet es t o
t he My Table t able in t he ChangeLogFor MyTable t able. The script st art s by
rem ov ing t he t r gKeepMyTableUnt ouched t r igger creat ed in t he pr ev ious sam ple.
Recall t hat t he pr ev ious t r igger block s all changes t o t he MyTable t able. Next t his
procedur e cr eat es a fr esh blank version of t he ChangeLogForMy Table t able. The
t able has four colum ns— one for t he col1 values from t he insert ed or delet ed
t able, a second for t he t ype of change, a t hird for t he dat e and t im e of t he
change, and a fourt h colum n for t he login of t he user m ak ing t he change.
Aft er creat ing a t able t o archiv e changes, t he script creat es a fresh copy of t he
t rgI nsert ToChangeLog t rigger . This t r igger copies t he col1 value from t he insert ed
t able t o a local var iable. Then it uses t he local v ariable in t he VALUES clause of an
I NSERT I NTO st at em ent t o persist t he new value t o t he ChangeLogFor MyTable
t able. The script uses a st ring const ant — I NSERT—t o designat e t he t ype of
change. The CURRENT_TI MESTAMP and SYSTEM_USER k ey words denot e built - in
funct ions t hat r et ur n t he curr ent dat e and t im e as well as t he login for t he cur rent
user ( t he one who m ak es t he change) .
The CREATE TRI GGER st at em ent s for t he t r gDelet eToChangeLog and
t rgUpdat eToChangeLog t riggers persist t he delet e and updat e col1 values t o t he
ChangeLogForMy Table t able. When logging delet es, you use t he delet ed t able
inst ead of t he insert ed t able. I n t he case of updat es, you log t he cont ent s of t he
delet ed and insert ed t ables t o t he ChangeLogForMyTable t able. Howev er, t he
basic design of delet e and updat e t r iggers cor responds t o t he
t rgI nsert ToChangeLog t rigger .
--trgInsertUpdateDeleteToChangeLog
--Drop prior version of trgKeepMyTableUntouched trigger.
IF EXISTS (SELECT name FROM sysobjects
             WHERE name = ’trgKeepMyTableUntouched’ AND type = ’TR’)
       DROP TRIGGER trgKeepMyTableUntouched
GO

--Remove prior version of ChangeLogForMyTable table.
IF EXISTS(SELECT TABLE_NAME = ’ChangeLogForMyTable’
            FROM INFORMATION_SCHEMA.TABLES)
    DROP TABLE ChangeLogForMyTable

--Create ChangeLogForMyTable table.
CREATE TABLE ChangeLogForMyTable
(
col1 int,
type varchar (10),
changedatetime datetime,
changeuser varchar(128)
)
GO

--Drop prior version of trgInsertToChangeLog trigger.
IF EXISTS (SELECT name FROM sysobjects
        WHERE name = ’trgInsertToChangeLog’ AND type = ’TR’)
    DROP TRIGGER trgInsertToChangeLog
GO

--Create trigger to monitor inserts.
CREATE TRIGGER trgInsertToChangeLog
ON MyTable
FOR INSERT
AS
DECLARE @col1value int
SET @col1value = (SELECT col1 FROM inserted)
INSERT INTO ChangeLogForMyTable VALUES(@col1value, ’INSERT’,
CURRENT_TIMESTAMP, SYSTEM_USER)
GO

--Drop prior version of trgDeleteToChangeLog trigger.
IF EXISTS (SELECT name FROM sysobjects
        WHERE name = ’trgDeleteToChangeLog’ AND type = ’TR’)
    DROP TRIGGER trgDeleteToChangeLog
GO

--Create trigger to monitor deletes.
CREATE TRIGGER trgDeleteToChangeLog
ON MyTable
FOR DELETE
AS
DECLARE @col1value int
SET @col1value = (SELECT col1 FROM deleted)
INSERT INTO ChangeLogForMyTable VALUES(@col1value, ’DELETE’,
CURRENT_TIMESTAMP, SYSTEM_USER)
GO

--Drop prior version of trgUpdateToChangeLog trigger.
IF EXISTS (SELECT name FROM sysobjects
        WHERE name = ’trgUpdateToChangeLog’ AND type = ’TR’)
    DROP TRIGGER trgUpdateToChangeLog
GO

CREATE TRIGGER trgUpdateToChangeLog
ON MyTable
FOR UPDATE
AS
DECLARE @col1value int
SET @col1value = (SELECT col1 FROM deleted)
INSERT INTO ChangeLogForMyTable VALUES(@col1value, ’UPDATE’,
CURRENT_TIMESTAMP, SYSTEM_USER)
SET @col1value = (SELECT col1 FROM inserted)
INSERT INTO ChangeLogForMyTable VALUES(@col1value, ’UPDATE’,
CURRENT_TIMESTAMP, SYSTEM_USER)
GO

The follow ing scr ipt should be r un im m ediat ely aft er y ou creat e t he t r iggers w it h
t he preceding scr ipt . I t also benefit s from a fresh copy of t he MyTable t able, such
as t he one generat ed by t he udfHigher ThanMax script in t he “Cr eat ing a Scalar
UDF Wit hout Param et er s” sect ion. The script m akes a ser ies of changes t o t he
MyTable t able. Aft er each change, it uses SELECT st at em ent s t o ret urn t he
MyTable t able and t he ChangeLogForMy Table t able. The first change is t o add a
new row wit h t he value 25 for col1. Next it updat es t he value 25 t o 26. Finally it
delet es t he r ow in t he MyTable t able w it h a col1 value of 26.
--Demo_trgInsertUpdateDeleteToChangeLog
--Insert a new row into MyTable and display
--MyTable and ChangeLogForMyTable tables
INSERT INTO MyTable (col1)
VALUES (25)

SELECT *
FROM MyTable
SELECT *
FROM ChangeLogForMyTable
GO

--Update inserted row value and display
--MyTable and ChangeLogForMyTable tables.
UPDATE MyTable
SET col1 = 26
WHERE col1 = 25

SELECT *
FROM MyTable
SELECT *
FROM ChangeLogForMyTable
GO

--Delete updated row and display
--MyTable and ChangeLogForMyTable tables.
DELETE
FROM MyTable
WHERE col1 = 26

SELECT *
FROM MyTable
SELECT *
FROM ChangeLogForMyTable
GO

Exam ining t he Result s pane cont ent s will allow you t o follow t he changes t o t he
MyTable t able as well as t he ChangeLogForMy Table t able. The first display of t he
ChangeLogForMy Table t able shows a t able w it h j ust one row and a col1 value of
25. I n t he next display of t he t able, y ou can see t hr ee r ows. This is because an
updat e adds t w o rows t o t he t able. I n it s final appearance in t he result s pane, t he
ChangeLogForMy Table t able cont ains four rows.

En f or cin g a Busin e ss Rule on a Ta ble

One of t he classic uses for t riggers is t he enforcem ent of business rules. Aft er all,
t he t r igger always fir es befor e a change ev ent . The T- SQL in t he t r igger can
assess t he change t o m ake sure it conform s t o business rules before com m it t ing
t he change t o a t able. I f a change value doesn’t sat isfy a business rule, t he
t rigger can t ak e an appropr iat e r em edy, such as r ej ect ing t he change or r ev ising
t he change and inform ing t he user of any r em edial act ion.
The next sam ple enforces a sim ple business r ule. The rule is t hat users can insert
only even num bers int o col1 of t he My Table t able. Your norm al business rules can
be subst ant ially m or e sophist icat ed t han t his sam ple, but t he t r iggers t o enforce
t hose r ules can st ill use t he sam e logic. First you t est t he change value t o m ak e
sure it adheres t o t he r ule. Second, if t he change value doesn’t confor m t o t he
business r ule, y our t r igger can perform an appr opriat e r em edial act ion for t he
invalid change value. Third, if t he change value sat isfies t he business rule, y ou
insert it int o t he t able.

                                     N ot e
Befor e running t he sam ple script in t his sect ion, m ake sure
you drop all ot her t r iggers for t he MyTable t able t hat can
conflict wit h t he sam ple below. The sam ple script on t he
book ’s com panion CD r em oves all prior t rigger s cr eat ed for
t he MyTable t able in t his chapt er. For br ev it y, t he list ing here
doesn’t show t he code for dropping all t hese t riggers.
The sam ple uses an I NSTEAD OF t r igger. Because t his t ype of t r igger fir es before
t he change ev ent , t her e is no need t o r oll back a t ransact ion for an inv alid act ion.
The sam ple uses t he m odulo operat or ( % ) t o check whet her a num ber div ides
ev enly by 2. A rem ainder of 1 indicat es an odd num ber. This out com e calls for a
rem edial act ion. The act ion in t his inst ance is t o add 1 t o t he input value from t he
insert ed t able, const ruct a m essage indicat ing t he alt ernat iv e act ion t ak en, and
finally insert t he new ev en num ber int o t he t able. A rem ainder of 0 indicat es an
ev en num ber . Because ev en num bers sat isfy t he business r ule, t he t r igger can
j ust insert t he value from t he insert ed t able int o col1 of t he My Table t able.
Aft er t he cr eat ion of t he t r igger, t he script includes dat a m anipulat ion and SELECT
st at em ent s t o t est t he t rigger ’s logic. You can run t he sam ple script and see t he
t rigger aut om at ically add 1 when t he script at t em pt s t o input an odd num ber ( 25)
int o col1 in t he My Table t able. On t he ot her hand, t he t r igger m erely accept s t he
insert of an even num ber ( 24) int o col1 in t he MyTable t able.
--trgInsteadOfInsert
--Drop prior version of trgInsteadOfInsert trigger.
IF EXISTS (SELECT name FROM sysobjects
            WHERE name = ’trgInsteadOfInsert’ AND type = ’TR’)
       DROP TRIGGER trgInsteadOfInsert
GO

--Create an INSTEAD OF trigger.
CREATE TRIGGER trgInsteadOfInsert
ON MyTable
INSTEAD OF INSERT
AS
DECLARE @col1value int
DECLARE @newcol1value int
DECLARE @strMsg varchar(400)

SET @col1value = (SELECT col1 FROM inserted)

--If inserted value is odd, make it even
--before inserting it.
IF @col1value%2 = 1
     BEGIN
         SET @newcol1value = @col1value + 1
         SET @strMsg = ’The value you want to insert is: ’
             + CAST(@col1value AS varchar(3))
             + ’, but it violates a business rule.’ + CHAR(10) +
             ’ Therefore, I insert ’
             + CAST(@newcol1value AS varchar(3)) + ’.’
         RAISERROR (@strMsg,16,1)
         INSERT INTO MyTable (col1) VALUES(@newcol1value)
     END
ELSE
     INSERT INTO MyTable (col1) VALUES(@col1value)
GO

--Try to insert an odd value into col1 in MyTable.
INSERT INTO MyTable (col1) VALUES(25)

--Display the col1 values in MyTable.
SELECT *
FROM MyTable

--Delete the next even value after the odd value.
DELETE
FROM MyTable
WHERE col1 = 26

--Display the col1 values in MyTable.
SELECT *
FROM MyTable

--Insert an even value into col1 in MyTable.
INSERT INTO MyTable (col1) VALUES(24)

--Display the col1 values in MyTable.
SELECT *
FROM MyTable

--Delete the new even col1 value in MyTable.
DELETE
FROM MyTable
WHERE col1 = 24

--Display the col1 values in MyTable.
SELECT *
FROM MyTable



En f or cin g a Busin e ss Rule on a Vie w

Two of t he advant ages of views are t hat t hey perm it you t o insulat e your
dat abase schem a from t he user int erface for an applicat ion and t hat you can
select iv ely expose subset s from a t able w it hout exposing all t he dat a in a base
t able. These feat ur es perm it y ou t o secur e t he base t able or t ables for a view
from all or m ost users while y ou grant t hese sam e users access t o a subset of t he
dat a fr om t he base t able or t ables t hrough a view. Unfort unat ely, AFTER t r iggers
never applied t o v iews, so prev iously y ou couldn’t enforce business rules wit h
t riggers for v iews. SQL Ser ver 2000 int r oduced I NSTEAD OF t r iggers, w hich apply
t o v iews. Ther efor e, you can gain t he benefit s of ex posing dat a t hr ough views and
st ill be able t o enforce business r ules v ia t r igger s.
The sam ple in t his sect ion dem onst rat es t he sy nt ax for apply ing a business r ule
for insert s int o a view . The v iew is vewMy Table. This v iew ret urns all t he rows for
t he colum n in t he MyTable t able. The business rule is t hat t he insert ed col1 v alue
can be only 1 gr eat er t han t he cur r ent m ax im um in col1 of t he MyTable t able.

                                    N ot e
As wit h t he sam ple script fr om t he pr eceding sect ion, you
should rem ove all t r igger s t hat can conflict wit h t he new
t r igger. The version of t he follow ing sam ple on t he book ’s
com panion CD rem oves all prior t riggers creat ed for t he
My Table t able in t his chapt er. For br ev it y, t he list ing her e
doesn’t show t he code for dropping all t hese t riggers.
The script below st art s wit h t he cr eat ion of t he vewMyTable v iew. Then t he script
m ov es on t o creat e a fr esh v ersion of t rgI nst eadOfI nsert Forv ewMyTable. No
special act ion is necessary for cr eat ing a t r igger for a v iew. I n t he ON clause for
t he CREATE TRI GGER st at em ent , j ust nam e t he view— vew MyTable, in t his case.
The t rigger ’s logic uses t he udfOneHigherThanMax UDF cr eat ed ear lier in t his
chapt er . You should r un t he code t o cr eat e t his UDF if it isn’t available. The logic
for enforcing t he business rule is t he sam e as for t he pr ev ious t r igger, alt hough
t he act ual business r ule is differ ent . An I F…ELSE st at em ent t est s for t he validit y
of t he new value r elat iv e t o t he business rule. I f t he new value fails t he t est , t he
t rigger perform s a r em edial act ion. This act ion print s a m essage let t ing t he user
know t he new value is invalid. Because t he t r igger is an I NSTEAD OF t r igger,
t here is no need t o r oll back t he insert . I f t he new v alue is valid, t he t r igger
insert s t he new value int o v ewMy Table.
Aft er t he script creat es t he t r igger, t he script goes on t o t est t he t r igger by t ry ing
t o insert t w o new values. The first value v iolat es t he business rule, and t he
t rigger r ej ect s it . The second value sat isfies t he business rule, and t he t rigger
insert s t he new value int o col1 of t he MyTable t able. The final dat a m anipulat ion
st at em ent in t he script rem oves t he value new ly insert ed int o t he v ewMyTable
view t o rest ore t he base t able t o it s init ial st at e.
--trgInsteadOfInsertForvewMyTable
--Drop prior version of vewMyTable view.
IF EXISTS(SELECT TABLE_NAME
                   FROM INFORMATION_SCHEMA.VIEWS
                   WHERE TABLE_NAME = ’vewMyTable’)
       DROP VIEW vewMyTable
GO

--Create vewMyTable view.
CREATE VIEW vewMyTable
AS
SELECT *
FROM MyTable
GO

--Drop prior version of trgInsteadOfInsertForvewMyTable trigger.
IF EXISTS (SELECT name FROM sysobjects
        WHERE name = ’trgInsteadOfInsertForvewMyTable’ AND type = ’TR
’)
    DROP TRIGGER trgInsteadOfInsertForvewMyTable
GO

--Create an INSTEAD OF trigger for a view.
CREATE TRIGGER trgInsteadOfInsertForvewMyTable
ON vewMyTable
INSTEAD OF INSERT
AS
DECLARE @col1value int
SET @col1value = (SELECT col1 FROM inserted)
IF @col1value > dbo.udfOneHigherThanMax()
     RAISERROR(‘Value too high.’,17,1)
ELSE
     INSERT INTO vewMyTable (col1) VALUES(@col1value)
GO

--Attempting to insert a value of 100 fails
--through vewMyTable.
INSERT INTO vewMyTable (col1) VALUES(100)

SELECT * FROM vewMyTable
GO

--Attempting to insert a value one higher
--than the maximum value succeeds.
INSERT INTO vewMyTable (col1) VALUES(dbo.udfOneHigherThanMax())

SELECT * FROM vewMyTable
GO
--Remove inserted value.
DELETE
FROM vewMyTable
WHERE col1 = dbo.udfOneHigherThanMax()-1
GO
Cha pt e r 6 . SQL Se r ve r 2 0 0 0 XM L
Fun ct iona lit y
When Microsoft SQL Ser ver 2000 was launched, Microsoft com m it t ed it self t o
prov iding t he best Ext ensible Mark up Language ( XML) funct ionalit y possible. XML
is im port ant because it prom ises t o r ev olut ionize t he way dat abase and Web
dev elopers im plem ent dat a access and dat a m anipulat ion capabilit ies in t heir
solut ions. Microsoft said it would r ev ise t he init ial release wit h t im ely updat es t hat
included new funct ionalit y r eflect ing t he rapidly ev olv ing XML st andards and
relat ed developm ent issues.
As t his chapt er was being pr epared, Micr osoft delivered on it s com m it m ent w it h
t he r elease of it s lat est updat e— t he Microsoft SQL Ser ver 2000 Web Serv ices
Toolk it . The t oolk it follows t wo ear lier r eleases: XML for SQL Server 2000 Web
Release 1 and XML for SQL Ser ver 2000 Web Release 2.
The Web Ser v ices Toolk it is based on SQLXML 3.0 and includes t he SQLXML 3.0
inst allat ion package. Microsoft says t hat t he feat ur es int roduced in SQLXML 1.0
and SQLXML 2.0 ar e included in t he SQLXML 3.0 package. See Chapt er 12 for
coverage of t he com pat ibilit y of t he t oolk it w it h t he t wo prior Web r eleases. I n
addit ion, see Ch a pt e r 1 3 for com m ent ary and sam ples using t he Web Ser v ices
Toolk it .
You will gain from t his chapt er an ov erall under st anding of XML funct ionalit y in
SQL Ser ver w it h an em phasis on access t o t hat funct ionalit y v ia T- SQL, XML
schem as and t em plat es, and hypert ext t ranspor t prot ocol ( HTTP) . Chapt er 12 w ill
refocus on XML so t hat you can build on t he underst anding pr esent ed her e w hile
you lear n how t o t ap t he XML capabilit ies in SQL Serv er w it h Visual Basic .NET
and relat ed t echnologies, such as ADO.NET. Wit h XML, dev elopers can build
incredibly pow er ful solut ions for r et r iev ing and m aint aining dat a ov er Web
connect ions. As t he w ord get s out about how easy it is t o creat e t hese solut ions,
you w ill becom e an evangelist for using XML wit h SQL Ser ver.
This chapt er relies on t he Nort hw ind sam ple dat abase. The chapt er sam ples add a
couple of new v iews and user- defined funct ions t o t he dat abase for use wit h XML
files. T- SQL script s for creat ing t hese obj ect s ar e included wit h t he sam ple files
for t his chapt er. The m ain r esource for t he chapt er is a collect ion of nearly 20
XML files along w it h an assort m ent of URLs. Som e of t he URLs dem onst rat e direct
access t o a SQL Server dat abase, while ot her URLs inv ok e an XML file and access
a SQL Serv er dat abase indir ect ly t hrough t he XML file.




Ove r view of XM L Su ppor t
I n lear ning about XML funct ionalit y, it is im port ant t o r ecall t hat Micr osoft
int r oduced XML pr ocessing power t o SQL Ser ver 2000 in m ult iple wav es. This
m eans t hat select ed XML feat ures available fr om t he init ial version of SQL Ser ver
2000 hav e been obsolet ed, or at least depr ecat ed, by subsequent ly int r oduced
XML t echniques. This is because Web Release 1 and Web Release 2— and now t he
Web Ser v ices Toolk it — added new XML funct ionalit y not available in t he init ial
release.
The ov erv iew of XML capabilit ies in t his sect ion has t wo part s. First it briefly
sum m ar izes im port ant XML feat ur es for t he init ial release of SQL Serv er 2000 and
each of t he first t wo Web releases. Second it pr ov ides helpful inform at ion for
inst alling t he Web releases. See Chapt er 12 and Ch a pt e r 1 3 for m ore
inform at ion about t he lat est Web release, t he Microsoft SQL Ser ver 2000 Web
Ser vices Toolk it .

Su m m a r y of XM L Fe a t u r e s by SQL Se r ve r Re le a se

The init ial r elease of SQL Serv er 2000 offered XML funct ionalit y in four m ain
areas.

   •   The abilit y t o access SQL Serv er v ia HTTP. This for m of access relies on
       t he creat ion of a Micr osoft I nt ernet I nform at ion Ser v ices ( I I S) v irt ual
       dir ect or y for each dat abase for w hich you prov ide access via HTTP.
   •   Support for XDR ( XML- Dat a Reduced) schem as. You can use t hese
       schem as t o creat e XML- based v iews of SQL Ser ver r ow sources, and y ou
       can use a subset of t he XML Pat h ( XPat h) query language t o query t hese
       views. The full XPat h specificat ion is a Wor ld Wide Web Consort ium ( W3C)
       st andard ( as out lined at ht t p: / / w ww.w3.org/ TR/ xpat h) .
   •   Ret r iev ing and wr it ing XML dat a. Wit h t he FOR XML clause for t he T- SQL
       SELECT st at em ent , SQL Ser ver prov ides a rout e for reading it s dat a
       sources and ret ur ning result set s in XML form at . OPENXML is a new
       funct ion t hat can r et ur n a r owset based on an XML docum ent . Because T-
       SQL enables t he use of t he OPENXML funct ion in a m anner sim ilar t o t hat
       of t he OPENROWSET funct ion, y ou can use I NSERT st at em ent s t o populat e
       dat a sources based on XML docum ent cont ent s.
   •   Enhancem ent s for XML t o Microsoft SQL Server 2000 OLE DB provider
       ( SQLOLEDB) . These XML im pr ov em ent s com e along wit h version 2.6 of
       Micr osoft Dat a Access Com ponent s. Using t he new capabilit ies perm it s you
       t o pass XML- form at t ed dat a t o a Com m and obj ect and ret urn XML-
       for m at t ed dat a fr om a Com m and obj ect . I n eit her case, t he dat a passes as
       a St ream obj ect .

Web Release 1 was last updat ed on Febr uar y 15, 2001. This r elease adds select ed
new XML capabilit ies t o t he XML feat ures int r oduced w hen SQL Serv er 2000
init ially shipped in t he fourt h quart er of 2000. As y ou can see, Microsoft wast ed
no t im e enhancing t he init ial capabilit ies. Web Release 1 creat es t wo m aj or
im pr ov em ent s along w it h a collect ion of m inor ones.

   •   Updat egram s enable t ransact ion- based dat a m anipulat ion using XML.
       Updat egram s offer an XML- based synt ax for insert ing, updat ing, and
       delet ing r ecords in a SQL Serv er r ow source. You can specify t ransact ions
       for set s of operat ions w it hin Updat egram s so t hat all t he dat a m anipulat ion
       t asks wit hin a t ransact ion occur or none occur. By using Updat egram s
       inst ead of t he OPENXML funct ion, dev elopers can im pr ov e t he perform ance
       of t heir insert s, updat es, and delet es w hile sim plify ing t he coding.
   •   XML Bulk Load t arget s m ov ing m assiv e am ount s of XML- based dat a int o
       SQL Ser ver. This feat ure addresses t he needs of dat abase adm inist rat ors
       and ot hers w ho r egular ly use eit her t he BULK I NSERT st at em ent or t he
       bcp ut ilit y. I n a non- t ransact ion- based m ode, y ou can insert XML-
       for m at t ed dat a fast er t han w it h Updat egram s or t he OPENXML funct ion.
   •   Select ed ot her Web Release 1 enhancem ent s. New sy nt ax offers you t he
       abilit y t o specify w it h a param et er t he ret urn of binar y dat a fr om a SQL
       Ser ver dat a source. Virt ual direct or y m anagem ent t ools expand t o offer
       m or e precise cont r ol ov er how users can access a dat abase v ia a v irt ual
       dir ect or y. Synt ax enhancem ent s im pr ov e your abilit y t o m ap XML schem as
       t o SQL Serv er dat a sour ces and generally m anage XML t em plat es.
Web Release 2 cont inued t he pat t ern of int er m ediat e r eleases t hat enhance t he
XML funct ionalit y of SQL Serv er 2000. The last updat e for Web Release 2 was
Oct ober 15, 2001, eight m ont hs aft er Web Release 1. I n I nt er net t im e, t his gap is
long enough for a m aj or upgr ade— and Microsoft t ook advant age of t he int erval t o
offer significant new funct ionalit y . Web Release 2 is especially appropr iat e for
t hose planning t o dev elop solut ions w it h a .NET language, such as Visual Basic
.NET. I highlight four m aj or areas of XML funct ionalit y and operat ion associat ed
wit h Web Release 2:

    •   Com pliance w it h t he W3C schem a specificat ion k now n as XML Schem a
        Definit ion ( XSD) . While t his release doesn’t drop support for t he
        propriet ary XDR schem a specificat ion, Microsoft adds new funct ionalit y
        t hat is com pliant only w it h t he indust ry - st andard XSD. Adopt ing XSD
        schem as in y our own work w ill ensur e t he int eroperabilit y of y our
        applicat ions w it h t hose of ot hers who subscribe t o t he XSD specificat ion.
    •   Client - side form at t ing perm it s t he XML form at t ing of SQL Serv er r owset s
        on t he I I S ser ver rat her t han t he dat abase serv er. This offers pot ent ial
        scalabilit y advant ages because m ult iple v irt ual dir ect or ies from differ ent
        I I S serv ers can point t o t he sam e dat abase on a dat abase serv er. I n
        addit ion, client - side for m at t ing r em oves processing from a dat abase
        serv er t hat m ight hav e ot her pr ocessing requirem ent s besides t hose for
        one or m or e I I S serv ers.
    •   Two new dat a access com ponent s enhance XML processing capabilit ies.
        First , t he SQLXMLOLEDB prov ider facilit at es m ult iple obj ect iv es, including
        client - side form at t ing and Act iv eX Dat a Obj ect s ( ADO) access t o Web
        Release 2 funct ionalit y. SQLXMLOLEDB isn’t a dat a prov ider; y ou use it in
        com binat ion w it h SQLOLEDB, t he SQL Serv er ADO dat a prov ider. Second,
        SQLXML Managed Classes explicit ly expose t he Web Release 2 obj ect
        m odel, SQLXML 2.0, t o t he .NET Fram ework . By using t hese m anaged
        classes, Visual Basic .NET dev elopers can apply DiffGram s as an
        alt er nat ive t o Updat egr am s for dat a m anipulat ion t asks.
    •   Side- by- side inst allat ion allows Web Release 2 t o r un on t he sam e
        m achine w it h Web Release 1. When using Web Release 2 in t his fashion,
        dev elopers need t o explicit ly r efer ence t he version t hey need for t heir
        applicat ions. For ex am ple, client - side pr ocessing is exclusiv ely available
        from v irt ual direct or ies com pliant w it h Web Release 2. Sim ilarly, t he XML
        Bulk Loading capabilit y is dependent on Web release. Each Web r elease
        has it s own dist inct DLL for im plem ent ing t he XML Bulk Loading feat ur e.
        You m ust regist er t he one t hat your applicat ion r equires.

W e b Re le a se I n st a lla t ion

Bot h Web Release 1 and Web Release 2 ar e fully support ed r eleases for SQL
Ser ver 2000. These r eleases shouldn’t be confused wit h serv ice packs t hat fix
problem s. While a Web release can r em edy a problem , it s m ain goal is t o add
new funct ionalit y not pr esent in an ear lier release. I n order t o inst all Web Release
1 or 2, your com put er m ust hav e inst alled SQL Ser ver 2000 RTM ( Version
8.00.194) .
You can obt ain t he Web r eleases from ht t p: / / w ww.m icrosoft .com / sql/ dow nloads/ .
Click t he link labeled XML For SQL Server Web Release 1 ( WR1) for Web Release
1. Click t he link labeled XML For SQL Serv er Web Release 2 ( SQLXML 2.0) for
Web Release 2. You w ill t ypically be downloading t he r eleases t o a com put er
equipped w it h an I I S serv er. Therefor e, you should t ak e t he norm al pr ecaut ions
t o guard against acquir ing a v irus during your I nt er net connect ion t im e.
Aft er y ou com plet e inst alling a Web release, y our Pr ogr am s m enu is updat ed w it h
an it em for t he release. Web Release 1 adds a new m enu it em labeled Micr osoft
SQL Ser ver XML Tools, which includes a single it em — XML For SQL
Docum ent at ion. This it em opens t he Soft war e Dev elopm ent Kit ( SDK) for t he
package, w hich includes docum ent at ion on t he feat ures of t he r elease.
Web Release 2 adds SQLXML 2.0 t o t he Pr ogram s m enu. The SQLXML 2.0 m enu
cont ains t hr ee it em s: Configure I I S, SQL 2.0 Docum ent at ion, and SQLXML 2.0
Readm e. Configure I I S offers a new wizard for configur ing a v irt ual dir ect ory t o
int eract wit h SQL Serv er ( updat ed fr om t he wizard in t he init ial r elease) . The
inst allat ion of Web Release 2 also offers a new SQLI SAPI filt er and SQLXML DLL
files for t he m iddle t ier t hat replace t he v ersions shipping w it h t he init ial r elease
of SQL Serv er 2000. Cr eat ing a v irt ual direct or y w it h t he Configure I I S m enu it em
perm it s y our applicat ions t o t ak e advant age of t he new feat ures enabled by t hese
com ponent s. You can also use t he new w izard t o upgrade v irt ual dir ect ories t o
t ake adv ant age of feat ures int r oduced w it h Web Release 2. I nst alling t he files for
Web Release 2 doesn’t cause t he rem oval or ov erwr it ing of t he files for Web
Release 1. I t is t his feat ur e t hat perm it s y ou t o t ap t he feat ures of eit her r elease
side by side on t he sam e com put er.




XM L For m a t s a n d Sch e m a s
XML is a rich and deep t echnology t hat pr om ises t o adv ance com put ing in t he
first decade of t he t w ent y- first cent ur y as m uch as or m ore t han Visual Basic did
in t he last decade of t he t went iet h cent ury . This sect ion deliv ers an int roduct ion
t o XML- form at t ed dat a t hat part icular ly t arget s curr ent and pot ent ial applicat ions
of XML w it h SQL Serv er. Subsequent sect ions will highlight how t o use XML w it h
SQL Ser ver 2000; t his sect ion focuses on t hree XML t opics t hat w ill equip you t o
underst and t he m at erial in t hose lat er sect ions. First I st art by descr ibing t he
ov erall sy nt ax for XML docum ent s. Second I present t he basics of XML schem as
as a dev ice for validat ing XML docum ent s. Third I rev iew XML annot at ed schem as
as a m eans of creat ing a v iew for a SQL Ser ver dat a source.

XM L D ocum e n t s

XML is especially well suit ed for r epr esent ing st r uct ur ed docum ent s, such as
inv oices and row sources in a dat abase. There is an im m ense body of lit erat ur e
about XML. Aside from t his sect ion, one place t o st art fam iliar izing yourself wit h
XML conv ent ions for represent ing dat a is t he Wor ld Wide Web Consort ium ( W3C)
sit e at ht t p: / / w ww.w3c.org/ XML. This sit e cont ains link s t o m any valuable XML
resources, such as t he W3C Recom m endat ion for XML 1.0. I n addit ion, t her e are
m any XML- based t echnologies, such as XML Schem a, XPat h, XSL, and XSLT.
Links at t he W3C m ain Web sit e can ser ve as a st art ing point for learning about
t hese r elat ed t echnologies.
A t y pical XML docum ent can r epresent dat a w it h a collect ion of t ags and a
st art ing declarat ion. These t ags ar e sim ilar in som e ways t o HTML t ags, but t hey
differ in im port ant ways. XML t ags denot e dat a elem ent s inst ead of how t o form at
dat a. HTML assigns a pr ecise m eaning t o t ags. For exam ple, t he < p> t ag m eans
st art a new paragraph. XML, on t he ot her hand, doesn’t assign a predet erm ined
m eaning t o a t ag. I ndeed, t he sam e t ag can hav e a differ ent m eaning in differ ent
XML docum ent s, and it is even possible for one t ag t o hav e different m eanings in
t he sam e XML docum ent . By using nam espaces, developers can resolv e pot ent ial
conflict s when t he sam e t ag has t w o or m ore different m eanings in t he sam e
docum ent .
XML lit erat ur e t ypically refers t o t he t ags in a docum ent as elem ent s. An elem ent
can cont ain ot her elem ent s, a dat a v alue, or bot h ot her elem ent s and a dat a
value. Elem ent s can have parent , child, and sibling r elat ionships wit h one
anot her. When an elem ent cont ains anot her one, t he cont ainer elem ent is t he
parent elem ent and t he cont ained elem ent is t he child elem ent . For exam ple,
< ShipperI D> , < Com panyNam e> , and < Phone> t ags can be child t ags of a par ent
t ag < Shippers> in an XML docum ent w it h dat a for t he Shippers t able. The t ags
bet ween a part icular inst ance of < Shippers> and < / Shippers> can denot e a row
in t he Shippers t able. XML docum ent s t hat cont ain m ult iple occurr ences of at
least one t ag, such as < Shippers> , m ust hav e one t ag set t hat cont ains all ot her
t ags, such as < root > and < / root > . This out erm ost t ag set can occur j ust once
wit hin an XML docum ent .
An XML t ag ( or elem ent ) can have one or m ore at t ribut es. The use of at t ribut es is
opt ional. At t ribut es appear w it hin t he t ag for an elem ent , such as < Shippers> .
You designat e at t ribut es wit h nam e- value pairs. The nam e denot es t he at t ribut e’s
nam e, and t he value depict s it s dat a value. Dat a values can appear in eit her
single or double quot at ion m ar ks follow ing an equal sign behind t he at t ribut e
nam e. You can r epr esent t he dat a for a t able w it h elem ent values, at t ribut e
values, or bot h.
The follow ing docum ent depict s t he Shippers t able dat a from t he Nort hwind
dat abase repr esent ed w it h elem ent s and no at t r ibut es. Not ice t hat t he first set of
angle bracket s ( < > ) declar es t he docum ent as an XML docum ent in ver sion 1
for m at . The ut f- 8 designat ion for encoding denot es a conv ent ion for conv ert ing
charact ers t o bit sequences inside a com put er. Because t he < Shippers> t ag is
repeat ed t hree t im es in t he docum ent , a par ent t ag set t hat appears j ust once is
necessary ; t he < root > and < / root > t ags m eet t his requir em ent . The nam e root
has no special m eaning; any ot her legit im at e nam e for a t ag, such as
ShippersRoot , can replace r oot . The < Shippers> t ag is t he par ent of t he
< ShipperI D> , < Com panyNam e> , and < Phone> t ags. These lat t er t hr ee t ags are
siblings of one anot her.
<?xml version="1.0” encoding="utf-8”?>
<!--Available in Chapter 06 code samples as shippers_elements.xml-->
<root>
      <Shippers>
            <ShipperID>1</ShipperID>
            <CompanyName>Speedy Express</CompanyName>
            <Phone>(503) 555-9831</Phone>
      </Shippers>
      <Shippers>
            <ShipperID>2</ShipperID>
            <CompanyName>United Package</CompanyName>
            <Phone>(503) 555-3199</Phone>
      </Shippers>
      <Shippers>
            <ShipperID>3</ShipperID>
            <CompanyName>Federal Shipping</CompanyName>
            <Phone>(503) 555-9931</Phone>
      </Shippers>
</root>

The next XML docum ent shows t he sam e dat a fr om t he Shippers t able as t he
preceding one. I n t his inst ance, t he docum ent ’s form at t ing repr esent s dat a values
wit h at t r ibut es inst ead of elem ent s or t ags. The declar at ion for t his XML
docum ent inst ance is t he sam e as in t he pr eceding sam ple. At t r ibut es appear in a
pair ed arr angem ent — fir st t he at t r ibut e nam e followed by an equal sign, and
second t he at t r ibut e v alue in double quot at ion m arks. The colum n values for each
row in t he Shippers t able appear wit hin a separ at e < Shippers> t ag in t he
docum ent . The t railing / charact er wit hin each < Shippers> t ag is an alt er nat iv e t o
designat ing < / Shippers> t o close t he < Shipper s> t ag.
<?xml version="1.0” encoding="utf-8” ?>
<!--shippers_attributes.xml-->
<root>
    <Shippers ShipperID="1” CompanyName="Speedy Express"
    Phone="(503) 555-9831” />
    <Shippers ShipperID="2” CompanyName="United Package"
    Phone="(503) 555-3199” />
    <Shippers ShipperID="3” CompanyName="Federal Shipping"
    Phone="(503) 555-9931” />
</root>

Figur e 6- 1 shows t he Shippers t able in t he XML form at for each of t he preceding
XML docum ent files. The figur e reveals how t he XML appears w it hin a browser.
Not ice t hat y ou can read t he dat a! Many ot her dat a form at s don’t appear so
readable in a browser. XML’s charact er - based form at for represent ing dat a is one
of t he advant ages of XML over ot her form at s for r epr esent ing dat a. I n t he
browser view of shippers_elem ent s.xm l, you can collapse t he dat a for any
indiv idual r ow in t he Shippers t able by click ing t he m inus sign ( - ) next t o t he
opening < Shippers> t ag for a row. You can collapse t he dat a for all t hr ee rows by
click ing t he m inus sign next t o t he opening < root > t ag for eit her docum ent .

    Figu r e 6 - 1 . A p air of scr ee n sh ot s illu st ra t in g t h a t u ser s ca n re a d ily
           e x a m in e t h e con t e n t s of a n X M L docu m e n t in a b row se r.
XM L Sche m a s

An XML schem a pr ov ides a fram ework for describing t he st r uct ur e and v alidat ing
t he cont ent s of an XML docum ent . Wit h an XML schem a, you can k now what
values ar e legit im at e for any t ag or at t ribut e inst ance. You can also use schem as
t o place const raint s on t he range of accept able values for a dat a elem ent . By
specify ing cardinalit y for elem ent s wit h t he m inOccurs and m ax Occurs elem ent
at t ribut es, you can specify how m any elem ent inst ances ar e legit im at e in an XML
docum ent . You can addit ionally designat e w het her an elem ent has any at t ribut es,
and t he relat ionships am ong elem ent s.
The W3C appr ov ed on May 2, 2001, a r ecom m endat ion
( ht t p: / / www .w3.org/ 2001/ XMLSchem a) t hat serv es as t he indust ry st andard for
expressing XML schem as. Dev elopers refer t o t he W3C schem a st andar d as an
XSD schem a. St art ing w it h Web Release 2, SQL Ser ver adopt ed t his st andard.
Befor e Web Release 2, SQL Ser ver work ed w it h XDR schem as— a precursor of t he
XSD schem a. This chapt er uses exclusively XSD schem as.
The follow ing scr ipt r epr esent s t he shell for a schem a. Not ice t hat an XSD schem a
is an XML docum ent because it st art s w it h an XML declarat ion. This m eans t hat
you can describe an XSD schem a w it h t he sam e synt ax t hat y ou use for any XML
docum ent . I n addit ion, not ice t he reference t o t he nam espace at
ht t p: / / www .w3.org/ XMLSchem a. This nam espace defines a set of t ags and
at t ribut es for defining schem as as XML docum ent s. The xsd designat ion for t he
nam espace is arbit rar y. ( For exam ple, you can use xs inst ead.) An XSD schem a
can have m ore t han one nam espace r eference. Each nam espace can refer ence a
different set of t ags and at t ribut es. By using a dist inct nam espace designat or for
each nam espace, y ou can resolv e conflict s for ident ically nam ed t ags and
at t ribut es bet ween t wo different nam espaces. The shell r efers t o t he t ags and
at t ribut es wit h t he xsd nam espace designat ion. The schem a t ag or elem ent ,
which m arks t he beginning and end of a schem a, is fr om t he nam espace
designat ed by xsd.
<?xml version="1.0” encoding="UTF-8”?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
...
</xsd:schema>

A basic underst anding of sev eral form at t ing convent ions can help you get st art ed
wr it ing your own schem a ( or at least equip you t o r ead t hose w rit t en by ot hers) .
Elem ent declarat ions can be for a sim ple or a com plex t ype. A com plex t y pe
elem ent has at least one child elem ent or one at t ribut e. You can ex plicit ly define
a child elem ent w it hin a parent elem ent or refer t o a child elem ent defined
elsewhere wit hin a schem a. A sim ple t ype elem ent has neit her a child elem ent
nor an at t ribut e. I n addit ion, t he declarat ion for a sim ple t ype elem ent classifies
t he dat a t ype for t he elem ent according t o one of t he built - in XSD dat a t y pes. The
XSD dat a t ypes generally cor respond t o SQL Serv er dat a t y pes. See t he “Dat a
Ty pe Coercions and t he sql: dat at ype Annot at ion” t opic in t he online
docum ent at ion for Web Release 2 for a det ailed discussion of t he sim ilar it ies and
differences bet w een SQL Serv er and XSD dat a t ypes. I n addit ion t o elem ent s, a
schem a can also specify at t ribut es. According t o t he W3C convent ion, t he
at t ribut es for a com plex t ype elem ent are designat ed follow ing t he specificat ions
for or refer ences t o any child elem ent s.
The follow ing XML docum ent is t he XSD schem a for t he shippers_elem ent s.xm l
docum ent file present ed in t he preceding sect ion. Follow ing t he schem a t ag wit h
t he nam espace declarat ion, t he schem a declar es a com plex elem ent t y pe for t he
root t ag. The root elem ent is com plex because it has child elem ent s, nam ely, one
or m ore Shippers elem ent s. The exact upper lim it for t he num ber of Shippers
elem ent s wit hin t he root elem ent is unbounded. ( See t he assignm ent for
m axOccurs.) The m inOccurs at t ribut e for t he choice specificat ion doesn’t appear
in t he schem a, but it s default value is 1. Ther efor e, t o allow an XML docum ent
wit h no Shippers elem ent s, designat e t he value 0 for m inOccurs. Not ice t hat t he
Shippers elem ent doesn’t appear nest ed w it hin t he r oot elem ent declar at ion.
I nst ead, t he r oot elem ent declarat ion uses t he ref at t r ibut e t o refer t o t he
Shippers elem ent .
The Shippers elem ent declarat ion follows t he r oot elem ent declarat ion. The
Shippers elem ent has t hree child elem ent s— ShipperI D, Com pany Nam e, and
Phone. I n t he following schem a, t he declarat ions for t he child elem ent s appear
nest ed w it hin t he Shippers elem ent . Each child elem ent has a dat a t y pe derived
from an XSD built - in dat a t ype, such as t he int eger or st ring dat a t ype. The
rest r ict ion elem ent in t he child declarat ions denot es t he dat a t ype for t he child
elem ent s fr om t he built - in dat a t ype. I n t he case of t he ShipperI D elem ent , t he
declarat ion lim it s t he elem ent ’s values t o int egers. I n t he case of t he
Com panyNam e and Phone elem ent s, t he declar at ions lim it t he elem ent values t o
st rings. I n addit ion, t he m axim um lengt h is 40 and 24 for t he Com pany Nam e and
Phone elem ent s, r espect iv ely. By assigning m inOccurs t o 0, t he schem a per m it s
t he Phone elem ent t o be opt ional for each Shippers elem ent . The ShipperI D and
Com panyNam e elem ent s are required child elem ent s for each Shipper s elem ent .
<?xml version="1.0” encoding="UTF-8”?>
<!--shippers_elements.xsd-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <xsd:element name="root">
              <xsd:complexType>
                  <xsd:choice maxOccurs="unbounded">
                        <xsd:element ref="Shippers"/>
                  </xsd:choice>
              </xsd:complexType>
       </xsd:element>
       <xsd:element name="Shippers">
       <xsd:complexType>
       <xsd:sequence>
              <xsd:element name="ShipperID">
                  <xsd:simpleType>
                        <xsd:restriction base="xsd:integer"/>
                  </xsd:simpleType>
              </xsd:element>
              <xsd:element name="CompanyName">
                  <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="40"/>
                        </xsd:restriction>
                  </xsd:simpleType>
              </xsd:element>
              <xsd:element name="Phone” minOccurs="0">
                  <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="24"/>
                        </xsd:restriction>
                  </xsd:simpleType>
              </xsd:element>
       </xsd:sequence>
       </xsd:complexType>
       </xsd:element>
</xsd:schema>

The schem a for t he shippers_at t r ibut es.xm l docum ent file appears next . The
Shippers elem ent in t his schem a has no child elem ent s because of t he layout of
t he shippers_at t ribut es.xm l docum ent . Nev ert heless, t he Shippers elem ent st ill
requir es a com plex t ype elem ent declarat ion because t he Shippers elem ent has
t hr ee at t ribut es. Not ice t hat y ou can use t he sam e sim pleType elem ent s for
declaring at t ribut es t hat you use for declaring elem ent s in an XML docum ent . I n
spit e of using t he sam e sim pleType elem ent s as t he pr eceding schem a, t his
schem a differs from t he preceding one by declaring ShipperI D, Com pany Nam e,
and Phone as at t r ibut es inst ead of elem ent s.
<?xml version="1.0” encoding="UTF-8”?>
<!--shippers_attributes.xsd-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <xsd:element name="root">
              <xsd:complexType>
                    <xsd:choice maxOccurs="unbounded">
                        <xsd:element ref="Shippers"/>
                    </xsd:choice>
              </xsd:complexType>
       </xsd:element>
       <xsd:element name="Shippers">
       <xsd:complexType>
              <xsd:attribute name="ShipperID">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:integer"/>
                    </xsd:simpleType>
              </xsd:attribute>
              <xsd:attribute name="CompanyName">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                               <xsd:maxLength value="40"/>
                        </xsd:restriction>
                    </xsd:simpleType>
              </xsd:attribute>
              <xsd:attribute name="Phone” type="string">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                               <xsd:maxLength value="24"/>
                        </xsd:restriction>
                    </xsd:simpleType>
              </xsd:attribute>
       </xsd:complexType>
       </xsd:element>
</xsd:schema>


An not a t e d Sche m a s

Up unt il t his point , I used schem as t o specify t he cont ent s of XML docum ent s.
Howev er, m ost of you r eading t his book probably care m ore about t he dat a in
your SQL Serv er dat abase t han in an XML docum ent . XML docum ent s are a
conv enient way of show ing and sharing dat a ov er t he Web. I nst ead of schem as
m er ely defining XML docum ent s, y ou would probably pr efer t hat XML docum ent s
point t o SQL Ser ver dat abases and expose dat abase cont ent s. This r ole allows
schem as t o pr ov ide Web- based v iews for SQL Ser ver dat abase cont ent s.
Annot at ed schem as w hen used w it h a v irt ual dir ect ory on an I I S ser ver allow y ou
t o der iv e a v iew of t he dat a in a SQL Serv er dat abase. An annot at ed schem a
cont ains special elem ent s and at t r ibut es t hat specify how t o link it t o a SQL
Ser ver dat abase. The XML docum ent t hat exposes t he view can appear in a Web
browser. The cont ent s of t he XML docum ent will confor m t o t he schem a design
and any param et ers passed direct ly from t he br owser ( or an int erm ediat e XML
docum ent ) . A browser can bot h init iat e t he request for t he XML v iew and display
t he v iew as an XML docum ent . I n addit ion, a br owser can launch t he pr ocess by
point ing t o an XML docum ent in a v irt ual direct ory on an I I S serv er t hat inv ok es a
schem a link ing t o a row source. SQL Serv er has a special t ool for cr eat ing v irt ual
dir ect or ies on I I S server s t hat point t o specific SQL Ser ver dat abases. These
virt ual dir ect ories perm it annot at ed schem as t o connect t o a SQL Ser ver dat abase
and der iv e a r owset .

                                      N ot e
One of t he innovat ions of Web Release 2 is t hat t he
form at t ing of t he ret urned rowset can t ake place on t he I I S
server inst ead of SQL Serv er. By t ransfer ring t he for m at t ing
of t he ret urned rowset fr om t he dat abase server t o t he I I S
server , Micr osoft can event ually pr ov ide v iews based on
annot at ed schem as for ot her t han SQL Server dat abases.
This sect ion int roduces t he basics of annot at ed schem a design and use. A lat er
sect ion, “ Virt ual Direct ory Managem ent ,” drills down on v irt ual direct or ies. An
annot at ed schem a is an XML docum ent j ust like a norm al XSD schem a. Howev er,
you norm ally wr it e it wit hout t he XML v ersion declarat ion. I n addit ion, you m ust
add a new nam espace r efer ence ( schem as- m icr osoft - com : m apping- schem a) t o
t he schem a shell t o accom m odat e special annot at ion elem ent s and at t r ibut es.
This Microsoft m apping nam espace support s t he special feat ures t hat perm it
annot at ion of XSD schem a so t hey link t o one or m ore row sources in a SQL
Ser ver dat abase. The sql designat or for t he nam espace is arbit rar y ; y ou can use
any ot her legit im at e XML nam e.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
...
</xsd:schema>

Two at t ribut es for link ing a schem a t o a row source in a dat abase include t he
relat ion at t r ibut e and t he field at t r ibut e. Precede t hese at t r ibut e nam es and any
ot her t hat you use for annot at ing y our schem a wit h t he designat or for t he
Micr osoft m apping nam espace. The relat ion at t ribut e cr eat es a link bet ween a
com plex elem ent and a SQL Ser ver row source. Using t he r elat ion at t ribut e let s
you cr eat e an alias in y our annot at ed schem a for t he row source nam e in a SQL
Ser ver dat abase. The schem a w ill at t em pt t o m at ch t he child elem ent s and
at t ribut es for t he com plex elem ent t o t he colum ns fr om t he row source. I f t he
at t ribut es and child elem ent s hav e nam es t hat m at ch colum n nam es in t he r ow
source, y ou don’t need t o specify a field at t r ibut e for t he at t ribut e or elem ent . I f
t he at t r ibut e or child elem ent nam e doesn’t m at ch t he nam e for a colum n in t he
row source, y ou can specify t he field at t ribut e. Wit h t he field at t r ibut e, you can
explicit ly link an elem ent or at t r ibut e t o a colum n in t he r ow source specified by a
relat ion at t r ibut e.

                                      N ot e
I f a com plex elem ent nam e in a schem a m at ches a row
source nam e in a dat abase, you don’t need t o designat e t he
corr espondence bet ween t he t wo wit h t he relat ion at t r ibut e.
The follow ing annot at ed schem a dem onst rat es t he use of t he r elat ion and field
at t ribut es. The schem a for m at s an XML docum ent w it h a com plex elem ent t ype
nam ed xm lShippers t hat has t wo child elem ent s, xm lCom panyNam e and
xm lPhone, and an at t ribut e, Shipper I D. Not ice t hat t he r elat ion and field
at t ribut es appear w it h a sql pr efix t o specify t he nam espace for defining t he
at t ribut es. The sql: r elat ion at t ribut e point s t he x m lShippers elem ent t o t he
Shippers r ow source. The sql: field at t r ibut es for t he x m lCom panyNam e and
xm lPhone elem ent s link t hese elem ent s t o t he Com panyNam e and Phone colum ns
in t he Shippers r ow source. Because t he ShipperI D at t r ibut e nam e m at ches a
colum n in t he Shippers row source, it doesn’t requir e a sql: field at t ribut e set t ing
t o link it t o a colum n wit hin t he row source.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<!--xmlShippersSchema.xml-->
    <xsd:element name="xmlShippers” sql:relation="Shippers” >
      <xsd:complexType>
        <xsd:sequence>
             <xsd:element name="xmlCompanyName”
                               sql:field="CompanyName”
                               type="xsd:string” />
             <xsd:element name="xmlPhone”
                               sql:field="Phone”
                               type="xsd:string” />
        </xsd:sequence>
        <xsd:attribute name="ShipperID” type="xsd:integer” />
       </xsd:complexType>
    </xsd:element>
</xsd:schema>

Wit h t hr ee m or e st eps, you can r et ur n an XML docum ent based on t he Shippers
row source.

    1. Sav e t he annot at ed schem a in a v irt ual dir ect or y configured t o connect t o
       t he Nort hw ind dat abase. Because t he Nort hw ind t able cont ains a t able
       nam ed Shippers, t his defines t he r ow source in t he annot at ed schem a.
    2. Creat e a new XML docum ent , called a t em plat e, t hat inv ok es t he
       annot at ed schem a. By inv ok ing t he quer y wit h XPat h sy nt ax, t he t em plat e
       file can cause t he annot at ed schem a t o ret urn a view of t he Shippers t able
       as an XML docum ent .
    3. Nav igat e t o t he t em plat e from a browser t o ret ur n t he v iew specified by
       t he t em plat e t o t he br owser’s docum ent window.

The follow ing XML docum ent illust rat es t he synt ax for referring t o t he preceding
annot at ed schem a in x m lShippersSchem a.xm l. The specificat ion r equir es t he
schem a t o r eside in a special t em plat e folder w it hin t he v irt ual direct or y, but y ou
can explicit ly designat e anot her source for t he annot at ed schem a file. The act ual
query sy nt ax sim ply refer ences t he elem ent w it h t he sql: r elat ion at t ribut e set t ing,
nam ely x m lShippers. This form of an XPat h query request s t he ret urn of all t he
rows fr om t he Shippers t able. The XPat h query is equivalent t o SELECT * FROM
Shippers in T- SQL.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--xmlShippersSchemaT.xml-->
  <sql:xpath-query mapping-schema="xmlShippersSchema.xml">
     /xmlShippers
  </sql:xpath-query>
</ROOT>

The t op screen shot in Figur e 6- 2 shows t he Shippers t able in XML form at based
on t he annot at ed schem a in xm lShippersSchem a.xm l and t he t em plat e file
( xm lShippersSchem aT.x m l) t hat quer ies t he schem a. The browser ’s Address box
shows t he pat h t o t he t em plat e file t hat cont ains t he XPat h query . The t em plat e
resides on an I I S serv er nam ed ccs1. The t em plat e is in t he t em plat e folder of t he
MyNw ind v irt ual direct ory. The use of t he nam e t em plat e for t he t em plat e folder
is arbit rary . Any ot her nam e w ill serv e equally well. The XML docum ent in t he
browser w indow follows t he form at of t he annot at ed schem a. Not ice t hat
ShipperI D appears as an at t ribut e, but xm lCom panyNam e and xm lPhone appear
as elem ent s. Whereas t he dat a values are from t he Shippers t able in t he
Nort hwind dat abase, t he elem ent and at t r ibut e nam es are from t he annot at ed
schem a.

   Figu r e 6 - 2 . A pa ir of scre e n sh ot s illu st ra t in g d iffer e n t re su lt se t s from
t h e sa m e an n ot a t e d sch e m a b ase d on t w o t em plat e s w it h differ en t X Pa t h
                                            qu e rie s.




The lower screen shot in Figure 6- 2 shows t he result of an XPat h query t hat asks
for t he ret urn of j ust t he row w it h ShipperI D equal t o 3. The sy nt ax for t he
t em plat e wit h t he query appears below . The par am et er for ShipperI D has a
leading @. Not ice t hat t he Addr ess box point s t o t he file wit h t he following
t em plat e. By cont rast ing t he follow ing t em plat e wit h t he pr eceding one, you can
see how t o r euse an annot at ed schem a t o der iv e different result set s. I n a sense,
t he annot at ed schem a ser ves as a param et er ized view!
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--xmlShippersSchemaT2.xml-->
   <sql:xpath-query mapping-schema="xmlShippersSchema.xml">
    /xmlShippers[@ShipperID=3]
  </sql:xpath-query>
</ROOT>

Recall t hat annot at ed schem as sim ulat e v iews in SQL Ser ver dat abases. Because
views oft en j oin t ables, t he nex t annot at ed schem a m erges t he Orders t able w it h
t he Shippers t able t o m ake available t he orders by Shipper I D. The schem a has t o
specify t he j oin bet ween t he t ables in t he original SQL Serv er dat a sour ce. The
schem a specifies t he j oin wit h a r elat ionship elem ent ( not t o be confused wit h a
relat ion elem ent ) . The relat ionship elem ent has five at t r ibut es.

    •   The nam e at t r ibut e assigns a nam e t o t he r elat ionship for subsequent
        reference in t he schem a.
    •   The parent at t ribut e denot es t he parent row source, or one side, of t he
        one- t o- m any r elat ionship bet ween Shippers and Orders. ( Each shipper can
        hav e m any orders.)
    •   The parent - key at t r ibut e denot es t he field in t he par ent row source for
        link ing t he parent and child r ow sources.
    •   The child and child- key at t ribut es point t o t he m any side of t he one- t o-
        m any r elat ionship. The Shipv ia field in t he Orders t able is a for eign k ey
        point ing t o t he ShipperI D field in t he Shippers t able.

The relat ionship elem ent is nest ed w it hin t he appinfo elem ent , w hich in t urn is
nest ed in t he annot at ion elem ent .
Aft er specifying t he r elat ionship in t he SQL Serv er dat a source, t he annot at ed
schem a focuses on specify ing t he lay out of t he XML docum ent and link ing t hat
lay out t o t he t w o source t ables and t he r elat ionship bet w een t hem . The schem a
defines a cust om com plex elem ent nam ed ShipperType. This cust om t y pe st art s
wit h a declarat ion for t he Order com plex t ype elem ent . The Order com plex
elem ent is based on t he Orders t able and t he ShipperOrders r elat ionship defined
at t he t op of t he schem a. The Order elem ent has t wo at t r ibut es, Order I D and
ShipVia, t hat r elat e t o Orders t able colum ns w it h t he sam e nam es. I n addit ion t o
t hese at t r ibut es based on t he Orders t able, t he ShipperType elem ent has a parent
wit h t w o addit ional at t r ibut es, ShipperI D and Com panyNam e. As wit h t he Order
at t ribut es, t here is no need for t he sql: field at t r ibut e t o link t hese t o colum ns in
t he Shippers t able because t he at t r ibut e nam es m at ch t he colum n nam es.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                    xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<!--xmlShipperOrdersSchema.xml-->
<xsd:annotation>
        <xsd:appinfo>
        <sql:relationship name="ShipperOrders"
             parent="Shippers"
             parent-key="ShipperID"
             child="Orders"
             child-key="ShipVia” />
        </xsd:appinfo>
</xsd:annotation>

<xsd:element name="Shipper” sql:relation="Shippers”
type="ShipperType” />
    <xsd:complexType name="ShipperType” >
       <xsd:sequence>
        <xsd:element name="Order”
                   sql:relation="Orders"
                   sql:relationship="ShipperOrders” >
           <xsd:complexType>
              <xsd:attribute name="OrderID” type="xsd:integer” />
               <xsd:attribute name="ShipVia” type="xsd:integer” />
            </xsd:complexType>
         </xsd:element>
      </xsd:sequence>
         <xsd:attribute name="ShipperID”   type="xsd:string” />
         <xsd:attribute name="CompanyName” type="xsd:string” />
     </xsd:complexType>

</xsd:schema>

The next XML docum ent shows t he t em plat e for r efer encing t he preceding
annot at ed schem a in an XPat h query . The quer y calls for t he ret ur n of all rows
from t he j oining of t he Shippers t able w it h t he Orders t able. An excerpt fr om t he
result set appears in Figur e 6- 3. The browser docum ent w indow shows t he
t ransit ion from t he last few r ows for ShipperI D 1 t o t he first few rows for
ShipperI D 2.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--xmlShipperOrdersSchemaT.xml-->
    <sql:xpath-query mapping-schema="xmlShipperOrdersSchema.xml">
      /Shipper
    </sql:xpath-query>
</ROOT>


    Figu re 6 - 3 . An e x cer pt fr om a r e su lt se t ba se d on t h e j oin in g of t h e
                       Sh ipp er s t a ble w it h t h e Or de rs t a b le .




URL Acce ss t o SQL Se r ve r
The preceding discussion of annot at ed schem as dem onst rat ed URL access t o a
SQL Ser ver dat abase. You learned t hat by r efer encing an XPat h query for an
annot at ed schem a in an XML file, a br owser can r et urn dat a based on it s URL, t he
XPat h query , and t he annot at ed schem a. I n t his sect ion, I lay t he foundat ion for a
m or e com prehensiv e underst anding of URL access for SQL Ser ver dat abases. This
sect ion begins w it h a br ief rev iew of v irt ual direct ory m anagem ent issues. The
prim ary focus is how t o set up a new v irt ual dir ect ory w it h t he I I S Virt ual
Direct ory Managem ent For SQLXML 2.0 ut ilit y in Web Release 2. You will also
lear n about w hy and w hen t o upgrade a v irt ual dir ect or y creat ed wit h t he init ial
version of t he ut ilit y for configur ing I I S v irt ual direct ories t o work w it h SQL
Ser ver. Next I dem onst r at e how t o use t he FOR XML clause for SQL Server
SELECT st at em ent s in a browser ’s Address box . Aft er an int r oduct ion t o t he FOR
XML clause, I dr ill dow n on how t o apply it w it h a collect ion of sam ples t hat
highlight issues pert aining t o it s use and reveal wor kar ounds for URL access
problem s wit h respect t o SQL Ser ver dat a sour ces. This closing m at erial
com plem ent s and ext ends t he previous discussion of annot at ed schem as. Many
dat abase dev elopers and adm inist rat ors ar e lik ely t o find t he T- SQL approach
illust rat ed in t his sect ion m or e fam iliar t han t he XPat h quer ies of t he preceding
sect ion.

Vir t u a l D ir e ct or y M a na ge m e n t

Befor e users can gain URL access t o a SQL Serv er dat abase, an adm inist rat or
m ust configur e an I I S virt ual direct ory t hat point s t o t he dat abase. This dir ect or y
m ust r eside on a com put er r unning I I S serv er. This can be t he sam e or a
different com put er fr om t he one running SQL Ser ver. You can hav e v irt ual
dir ect or ies on m ult iple I I S serv ers connect ing t o a single SQL Serv er dat abase.
Users gain URL access t o t he dat abase t hrough t he v irt ual dir ect or y on a serv er
t hat point s t o a SQL Ser ver dat abase.
The I I S Virt ual Dir ect or y Managem ent For SQLXML 2.0 ut ilit y let s you creat e and
m anage a v irt ual dir ect ory . This t ool changed wit h t he int roduct ion of Web
Release 2. This is because Web Release 2 is t he first r elease t o support client - side
for m at t ing of XML docum ent s. Recall fr om earlier discussions of t his t opic t hat
client - side XML form at t ing enhances scalabilit y and reduces t he load on a
dat abase serv er . As a r esult of t he enhancem ent t o t he ut ilit y for Web Release 2,
you cannot gain t he benefit s of client - side form at t ing w it hout upgrading an old
virt ual dir ect ory or cr eat ing a new one w it h Web Release 2.
Launch t he I I S Virt ual Dir ect ory Managem ent For SQLXML 2.0 ut ilit y by opening
t he Windows St art m enu and choosing Program s, t hen SQLXML 2.0, and t hen
Configur e I I S Support . Select Default Web Sit e under t he local I I S serv er . This
exposes any prev iously creat ed v irt ual dir ect or ies in t he r ight - hand pane of t he
m anagem ent console for t he ut ilit y. Double- click any ex ist ing dir ect or y t o open a
m ult it abbed Propert ies dialog box for t hat direct ory . From t his dialog box, you can
updat e t he set t ings for t he dir ect ory — j ust select t he Version 2 t ab and click
Upgrade To Version 2. Right - click Default Web Sit e, choose New, and t hen choose
Virt ual Dir ect ory t o st ar t creat ing a new v irt ual dir ect ory . This opens t he New
Virt ual Dir ect ory Propert ies dialog box, w hich has generally t he sam e t abs as
t hose for an ex ist ing vir t ual dir ect or y. You specify t he new v irt ual dir ect ory by
m aking select ions on t he dialog box ’s t abs and click ing OK.
Befor e st art ing t o cr eat e a new virt ual dir ect ory, pick an ex ist ing physical
dir ect or y ( a folder ) or cr eat e a new one w it h Windows Explor er . The physical
dir ect or y will be associat ed wit h t he virt ual dir ect ory y ou’re creat ing. I t is
com m on t o locat e folder s for a v irt ual direct ory in t he www root dir ect or y of t he
I net pub folder. For inst ance, you can cr eat e a folder t her e nam ed nw ind. You w ill
t ypically want t o creat e t wo addit ional folders below t he m ain folder for a v irt ual
dir ect or y— one subfolder for st or ing t em plat es and anot her for st oring annot at ed
schem as. The t em plat e folder is part icular ly flex ible. Recall from t he discussion of
annot at ed schem as t hat you can st or e and use annot at ed schem as in t he
t em plat e folder.

                                      N ot e
For m or e inform at ion about creat ing a virt ual dir ect ory , see
t he “Creat ing t he nwind Virt ual Dir ect or y” t opic in t he
SQLXML 2.0 docum ent at ion.
Aft er creat ing folders for y our v irt ual dir ect or y, open a New Virt ual Direct ory
Propert ies dialog box as j ust described. Next com plet e t he inform at ion on t he
dialog box ’s t abs.

    •   On t he General t ab, ent er a nam e for your v irt ual direct ory, such as
        MyNw ind. Then use t he Browse but t on t o nav igat e t o t he root folder for
        your v irt ual dir ect ory.
    •   Next navigat e t o t he Secur it y t ab. I n t he Cr edent ials group, designat e a
        login t hrough w hich t hose browsing t he v irt ual dir ect or y will log on t o t he
        dat abase. For exam ple, you can specify I USR_CCS1 t o designat e
        anonym ous Web users on a dat abase serv er nam ed CCS1. Mak e sur e t hat
        you hav e a Windows account nam ed I USR_CCS1 as well as SQL Serv er
        login w it h user account s in dat abases t o which y ou want t he I USR_CCS1
        user t o have access. Give t he user account s in a dat abase w hat ev er
        perm issions y our applicat ion r equires. See Chapt er 7 for a m or e
        com prehensiv e discussion of SQL Server secur it y.
    •   On t he Dat a Source t ab, ent er or select a SQL Ser ver nam e and a
        dat abase nam e on t he ser ver. These set t ings det erm ine t he dat abase t o
        which t he v irt ual direct ory point s.
    •   The Set t ings t ab offers cont rols for det erm ining how browsers can specify
        quer ies t hr ough t he URL t hey show in t he Addr ess box. For exam ple, y ou
        can enable and disable SQL quer ies, such as t hose dem onst rat ed lat er in
        t his sect ion, direct ly from t he Addr ess box. You can also use t his t ab t o
        specify XML form at t ing of a r owset ret ur ned by a quer y on t he I I S client
        inst ead of t he dat abase serv er.
    •   Wit h t he Virt ual Nam es t ab, you can designat e nam es and pat hs for t he
        schem a and t em plat e t y pe folders. You can also creat e a v irt ual nam e as a
        dbobj ect t ype t hat facilit at es users m aking direct references in a URL t o
        dat abase obj ect s, such as a t able or view.
    •   Use t he Advanced t ab t o fine- t une perform ance and m em or y usage. When
        you com plet e all t he specificat ions for a new virt ual direct ory, click OK t o
        creat e it .

Ov e r vie w of FOR X M L in SELECT St a t e m e n t s

SQL Ser ver 2000 int roduced a new clause for it s SELECT st at em ent t hat ret urns a
rowset form at t ed as XML dat a. The clause causes t he SELECT st at em ent t o r et ur n
a t ext st ream obj ect for m at t ed as XML inst ead of as a rowset . The row set and t he
t ext st ream cont ain t he sam e inform at ion, but t he FOR XML clause form at s t he
inform at ion as an XML docum ent . Using t he FOR XML clause in com binat ion w it h
a v irt ual direct or y point ing t o a SQL Ser ver dat abase perm it s y our applicat ions t o
ret ur n dat a fr om a SQL Ser ver dat abase via HTTP.
The FOR XML clause goes at t he end of a SELECT st at em ent for ret riev ing dat a.
The clause r equires one of four argum ent s. These argum ent s det erm ine how t o
for m at t he ret r ieved dat a as XML. I n addit ion, t hr ee opt ional FOR XML argum ent s
can furt her fine- t une t he form at for XML dat a from a SELECT st at em ent . The
operat ion of t his clause depends in part on a v ir t ual dir ect or y’s set t ing for client -
side form at t ing. As m ent ioned, t he FOR XML clause appears at t he end of a
SELECT st at em ent . I t s general design is:
SELECT … FOR XML
mode [, optional arguments]

The sy nt ax requir es a m ode argum ent . This argum ent can t ak e any of four
values. ( See Table 6- 1.) The RAW m ode argum ent pr ov ides t he m ost basic XML
represent at ion of a r ow source. For exam ple, t his argum ent r et ur ns XML dat a
wit h t he sam e row ident ifier for all r ow sources, and a par ent - child row source
appears in a single collect ion of rows inst ead of in a nest ed form at w it h t he child
dat a nest ed below t he parent dat a t o w hich it belongs. The AUTO m ode argum ent
prov ides m ore flex ibilit y in t he r et ur n and easier form at t ing for ret ur ning binary
dat a. The EXPLI CI T m ode is a special m ode for det ailing t he pr ecise layout of an
XML docum ent fr om a SELECT st at em ent . I n r et ur n for t he cont rol ov er t he
lay out , y ou m ust specially form at t he design of your SELECT st at em ent . See t he
“Using EXPLI CI T Mode” t opic in Books Online for SQL Server 2000 for num er ous
sam ples illust rat ing t his nonst andard approach t o form at t ing XML docum ent s.
The NESTED m ode is a special m ode t hat t aps t he feat ures of client - side
for m at t ing. This is t he only m ode t hat support s t he GROUP BY clause in a SELECT
st at em ent . For t his m ode t o work , a virt ual direct ory m ust enable client - side
for m at t ing. The check box for t his feat ur e is Run On The Client on t he Set t ings
t ab of t he Propert ies dialog box for a v irt ual direct ory. You can get t o t his dialog
box fr om t he I I S Virt ual Dir ect ory Managem ent For SQLXML 2.0 ut ilit y as
described in t he “Virt ual Dir ect ory Managem ent ” sect ion. The m ode is available
only for v irt ual dir ect ories creat ed ( or upgraded t o becom e com pat ible) wit h Web
Release 2.
                      7DEOH  0RGH $UJXPHQWV LQ WKH )25 ;0/ &ODXVH

  1DPH                                            'HVFULSWLRQ
RAW         Form at s rowset t o XML wit h a gener ic r ow ident ifier . Non- null colum ns
            in a SELECT st at em ent ’s rowset m ap t o at t r ibut es wit hin a row.
            Repr esent s j oined par ent - child r ow sources in a flat form at .
AUTO        Form at s rowset t o XML wit h a specific r ow sour ce ident ifier based on t he
            SELECT st at em ent ’s FROM clause. Repr esent s j oined parent - child r ow
            sources in a hierarchical form at .
NESTED Form at s sim ilar ly t o AUTO, but it explicit ly invokes client - side
       processing. Requires virt ual dir ect or y t o enable client - side form at t ing
       feat ur e for v alid operat ion. Enables GROUP BY clause and aggregat e
       funct ions.
EXPLI CI T Allows explicit form at t ing of XML dat a, but it r equir es special SELECT
           st at em ent sy nt ax t o accom m odat e t he layout form at t ing flex ibilit y.
The FOR XML clause opt ional argum ent s include ELEMENTS, XMLDATA, and
BI NARY BASE64. You can concurr ent ly use m or e t han one opt ional argum ent wit h
t he FOR XML clause for a SELECT st at em ent . Delim it t hese argum ent s wit h
com m as from t he m ode argum ent and one anot her. The FOR XML clause ret urns
colum n values fr om a SELECT st at em ent as at t r ibut es by default . Specifying t he
ELEMENTS argum ent r et urns colum n values as elem ent s inst ead of at t r ibut es.
Refer encing t he XMLDATA argum ent in a SELECT st at em ent insert s a schem a for
t he XML form at t ed dat a at t he beginning of t he argum ent . This schem a is in XDR
( as opposed t o XSD) for m at no m at t er what r elease y ou use. The BI NARY
BASE64 argum ent facilit at es t he r et ur n of binar y dat a w hen you’r e using eit her
t he RAW or EXPLI CI T m ode argum ent . Failing t o use t he BI NARY BASE64
argum ent for eit her of t hese m odes w hen a r esult set has binary dat a generat es
an er ror.

RAW vs. AUTO M ode Sa m ple s

When using t he FOR XML clause in t he Addr ess box of a browser, y ou w ill
t ypically need t o designat e sev eral it em s. St art wit h ht t p: / / . Then follow t his w it h
t he pat h t o t he ser ver and v irt ual dir ect ory you are using. Next ent er a quest ion
m ark. This allows you t o specify a param et er nam e and it s value. Use sql as t he
param et er nam e follow ed by an equal sign ( = ) . Then t ype a SELECT st at em ent
t hat t erm inat es w it h a FOR XML clause, such as SELECT * FROM Shippers FOR
XML RAW . Ther e is no need t o replace blank spaces wit h special charact ers, such
as % 20, because t he I nt ernet Explorer browser aut om at ically insert s replacem ent
charact ers for blank spaces. When t he XML docum ent for a SELECT st at em ent
ret ur ns m or e t han a single r ow, y ou m ust specify a root elem ent for t he XML
docum ent t o display t he r esult set . You can do t his by t yping & and r oot = root .
You can set t he t erm r oot equal t o any legit im at e XML nam e, such as a or a1, but
not 1a, w hich is an illegit im at e nam e because it st art s wit h a num ber .
Figur e 6- 4 shows in it s t op screen shot a sam ple SELECT st at em ent t o r et ur n all
rows fr om t he Shippers t able in RAW m ode:
http://ccs1/MyNwind?sql=SELECT * FROM Shippers FOR XML RAW&root=root

The browser subm it s t he SELECT st at em ent t o t he MyNwind v irt ual dir ect ory on
t he I I S serv er nam ed ccs1. For t his quer y st at em ent t o work, t he MyNwind v irt ual
dir ect or y m ust point t o a SQL Serv er dat abase wit h a Shippers row source, such
as t he Shippers t able in t he Nort hw ind dat abase. You can also use a v iew as t he
row source. Not ice t hat t he t op screen shot includes an XML docum ent in t he
browser w indow based on t he SELECT st at em ent in t he Address box . All rows in
t he docum ent hav e t he sam e elem ent — row. Colum n values appear as at t ribut es
aft er t he row elem ent . The at t r ibut e nam e m at ches t he colum n nam e.
The bot t om screen shot shows exact ly t he sam e SELECT st at em ent except t hat
t he FOR XML m ode argum ent is AUTO inst ead of RAW. The sole difference in t he
out com e for swit ching t o AUTO is t hat t he r ow elem ent nam e changed from r ow
t o Shippers. When ret ur ning r esult s, t he AUTO argum ent always uses t he t able
nam e, or it s alias, as r ow ident ifiers.

    Figu r e 6 - 4 . A p air of SELECT st at e m en t s in br ow se r s con t ra st in g t h e
   im pa ct of t h e RAW an d AUTO m ode a rg u m e n t s for a r esu lt se t from a
                                      sin gle t a ble.




Using a SELECT st at em ent t hat j oins par ent and child t ables dem onst r at es
anot her dist inct ion bet w een t he RAW and AUTO m ode argum ent s. Consider t he
follow ing SELECT st at em ent . I t j oins t he Order s t able t o t he Shippers t able by
ShipperI D num ber , which has t he nam e ShipVia in t he Orders t able. The ORDER
BY clause arranges t he rowset so t hat r ows are sort ed by OrderI D wit hin
ShipperI D inst ead of by OrderI D w it hout r egard t o ShipperI D. OrderI D is t he
default order for t he r esult set . The Orders t able rows relat e hierarchically t o t he
rows in t he Shippers t able because each shipper is r esponsible for t ransport ing a
m ut ually exclusiv e set of orders. Tradit ional relat ional dat abase result set s appear
as flat t ables. How ev er, XML can pr oper ly represent t he hierarchical nat ur e of t he
result set from t he following SELECT st at em ent . To display t he ret urn set
hierarchically, use AUTO inst ead of RAW as t he m ode argum ent .
SELECT ShipperID, CompanyName, ShipVia, OrderID, OrderDate
FROM Shippers JOIN Orders ON (Shippers.ShipperID=Orders.ShipVia)
ORDER BY ShipperID

Figur e 6- 5 shows an ex cerpt from t he XML for m at t ed r esult set for t he pr eceding
SELECT st at em ent w it h bot h t he RAW and AUTO m ode argum ent s. The RAW
m ode argum ent out com e appears in t he t op pane. The docum ent w indow for t he
browser in t he t op pane shows t he last t w o r ow s for ShipperI D 1 and t he first t wo
rows for Shipper I D 2. The bot t om pane shows t he sam e result s form at t ed based
on AUTO m ode. Not ice t hat t he first t wo Order r ows for ShipperI D 2 appear
nest ed w it hin a Shipper s row. All t he Order r ow s appear nest ed w it hin whichev er
shipper t ransport ed t hem . This hierarchical display of t he dat a is m or e m eaningful
t han t he flat t able form at in t he t op screen shot . However, in eit her case, y ou
enj oy t he benefit of capt uring dat a direct ly from a SQL Serv er dat abase ov er t he
Web.

 Figu r e 6 - 5 . Th e t op pa n e sh ow s t h e for m at for a pa re n t - ch ild re su lt set
 w it h RAW m od e. Th e bot t om pa n e sh ow s t h e sa m e r e su lt se t form a t t e d
                  b ase d on AUTO m od e—n ot ice it is h ie ra rch ica l!




The default form at for r et ur ning XML dat a is at t ribut e- cent r ic. That is, dat a values
appear as at t ribut e values. How ev er , an elem ent - cent r ic form at is popular w it h
m any dev elopers. Using t he ELEMENTS opt ional argum ent perm it s y ou t o r et ur n
values fr om a SELECT st at em ent in an elem ent - cent r ic form at . To specify t he
ELEMENTS opt ion, y ou m ust use eit her AUTO or NESTED as t he m ode argum ent
in t he FOR XML clause. Not ice t hat a com m a delim it s t he ELEMENTS opt ion from
t he AUTO m ode designat ion:
http://ccs1/MyNwind?sql=SELECT * from Shippers Œ
for XML AUTO, ELEMENTS&root=root

Figur e 6- 6 dem onst rat es t he use of t his synt ax for invoking t he ELEMENTS opt ion.
To appreciat e t he im pact of t he ELEMENTS opt ion, you can cont rast t he XML
docum ent in Figur e 6- 6 wit h t he one in t he bot t om pane of Figure 6- 4. The
SELECT st at em ent is ident ical in bot h cases except for t he ELEMENTS clause.

 Figu re 6 - 6 . For m at X M L docu m e n t s so t h ey a re e le m en t - ce n t r ic, in st ea d
     of t h e d efa u lt at t ribu t e - cen t r ic la you t , by sp ecifyin g t h e op t ion a l
                                    ELEM EN TS ar gu m en t .




The sam ples in t his chapt er up t o t his point deal w it h result set s populat ed w it h
charact ers. However, you som et im es hav e t o deal wit h binary dat a. For exam ple,
t he Nort hwind dat a populat es t wo t ables wit h binar y dat a represent ing im ages.
One of t hese is t he Cat egories t able t hat cont ains binary dat a for it s Pict ur e
colum n values. The binary dat a in t he Pict ur e colum n r epr esent s im ages of t he
product s in a cat egory . When using RAW m ode t o r et ur n t he colum ns of t he
Cat egor ies t able, y ou m ust specify t he BI NARY BASE64 opt ional argum ent in t he
FOR XML clause. The follow ing URL shows t he synt ax for t he Address box in t he
browser. The t op screen shot in Figur e 6- 7 show s an excerpt fr om t he XML
docum ent t hat t he br ow ser displays. Not ice t hat t he XML docum ent shows an
encoded represent at ion of t he im age. Failing t o specify t he opt ional BI NARY
BASE64 argum ent generat es an er ror m essage in t he br owser w indow inst ead of
an XML docum ent .
http://ccs1/MyNwind?sql=SELECT * FROM Categories Œ
FOR XML RAW, BINARY BASE64&root=root

Specify ing t he AUTO m ode passes back a pat h t o t he Pict ur e colum n values in t he
XML docum ent . ( See t he follow ing URL and t he m iddle screen shot in Figur e 6- 7.)
You can open t he Pict ur e colum n value for any row in t he browser as an im age by
appending t he pat h t o t he Web serv er wit h t he virt ual dir ect ory point ing t o t he
t arget dat abase. The bot t om screen shot in Figure 6- 7 shows t he XPat h query
st at em ent com pr ising t he Web serv er, t he virt ual dir ect or y nam e, and t he first
colum n value for Pict ure in t he m iddle row. Not ice t hat t he bot t om screen shot
displays t he pict ure for t he binary obj ect in t he browser! To run t he query in t he
bot t om browser, y our v irt ual direct ory m ust be able t o r un XPat h quer ies, and
you m ust hav e defined a dbobj ect v irt ual nam e. You can cont r ol t hese feat ures
wit h t he I I S Virt ual Direct ory Managem ent For SQL Ser ver ut ilit y .
http://ccs1/MyNwind?sql=SELECT * FROM Categories Œ
FOR XML auto &root=root


Figu r e 6 - 7 . W or k in g w it h b in ar y im ag e file s ca n be st r aigh t forw a rd w h en
 you u se AUTO m od e for t h e FOR X M L clau se an d t h e X Pa t h q u e r ie s, b u t
e ven RAW m ode can r et u r n an e n code d re pr e sen t a t ion of a n im ag e t o a n
                                         X M L docu m e n t .
AUTO vs. N ESTED M ode Sa m ple s

All t he URL access sam ples t o t his point in t he chapt er w ork ed w it h t ables, but
views can serv e as t he row source for a SELECT st at em ent w it h a FOR XML clause
as well. How ev er, t he r esult ing XML docum ent v aries slight ly depending on
whet her y ou use AUTO or NESTED as t he m ode argum ent . Wit h AUTO as t he
m ode argum ent , t he row ident ifier in t he XML docum ent is t he nam e of t he v iew.
When y ou use NESTED as t he m ode for a SELECT st at em ent based on a v iew , t he
row ident ifier in t he XML docum ent is t he base t able’s nam e rat her t han t he
view’s nam e.
Use Query Analyzer t o creat e t he Shipper View dat abase obj ect in t he Nort hw ind
dat abase. This view can serv e as a row source for a SELECT st at em ent . Not ice
t hat t he view m er ely cr eat es a set of aliases for t he colum ns in t he Shippers
t able.
--CreateShipperView.sql
USE Northwind
GO
CREATE VIEW ShipperView AS
SELECT ShipperID as SID, CompanyName as CName, Phone as PNo
FROM Shippers
GO

Ex ecut ing a SELECT st at em ent from t he browser’s Address box t hat select s all t he
colum ns fr om t he Shipper View obj ect form at s an XML docum ent show ing t he
colum n aliases as at t ribut e nam es. This out com e is t r ue w het her y ou use AUTO or
NESTED as t he m ode ar gum ent for t he FOR XML clause in t he SELECT st at em ent .
Howev er, w it h AUTO as t he m ode argum ent , t he ident ifier elem ent for each row
in t he docum ent is t he v iew’s nam e, ShipperView. ( See t he t op screen shot in
Figur e 6- 8.) This out com e holds w het her you enable client - side form at t ing for
XML docum ent s in t he v irt ual direct ory or not . I f your SELECT st at em ent uses
NESTED for it s m ode ar gum ent and you enabled client - side form at t ing for XML
docum ent s in t he v irt ual direct ory, t he row ident ifier r efers t o t he base t able for
t he v iew— nam ely, Shippers in t he case of t he v iew nam ed Shipper View . ( See t he
bot t om screen shot in Figur e 6- 8.) I f y ou run a SELECT st at em ent w it h NESTED
for t he m ode and t he v irt ual direct ory doesn’t enable client - side form at t ing, an
error result s.

  Figu re 6 - 8 . Usin g N ESTED a s t h e m od e a rgu m en t sh ow s t h e b a se t a ble
                      for a vie w r a t h e r t h a n t h e vie w ’s n a m e .
Som e dev elopers m ight consider not show ing a v iew’s nam e a m inor weakness
for client - side processing. How ev er, a m aj or st rengt h of client - side pr ocessing is
it s abilit y t o use t he GROUP BY clause and aggr egat e funct ions in SELECT
st at em ent s t hat use NESTED as t he m ode in t he FOR XML clause. Ot her m ode
argum ent s don’t suppor t t he use of t he GROUP BY clause. Because t his clause is
so com m on in SELECT st at em ent s, being able t o specify t he GROUP BY clause is a
m aj or advant age of client - side form at t ing for XML docum ent s. Ev en if your v irt ual
dir ect or y enables client - side form at t ing, you don’t gain t he abilit y t o use t he
GROUP BY clause unless your SELECT st at em ent explicit ly designat es NESTED as
t he m ode argum ent in t he FOR XML clause.
The SELECT st at em ent in t he follow ing URL inv okes t he GROUP BY clause for
OrderI D in t he I nv oices view t o com put e t ot al Ext endedPr ice for each order. A
CAST funct ion form at s t ot al Ext endedPr ice per order w it h t wo places aft er t he
decim al point . Figure 6- 9 shows an excerpt from t he XML docum ent t hat t he
SELECT st at em ent generat es.
http://ccs1/MyNwind?sql=SELECT OrderID, Œ
CAST(SUM(ExtendedPrice) AS DEC(8,2)) AS [OrderTotal] Œ
FROM Invoices GROUP BY OrderID FOR XML NESTED&root=root


  Figu r e 6 - 9 . Th is e x cer pt fr om a n X M L d ocu m en t re su lt s from a SELECT
st a t e m e n t t h a t spe cifies t h e N ESTED m od e in t h e FOR X M L cla u se so t h at
    t h e st a t e m e n t ca n spe cify a GROUP BY cla u se t o su m Ex t e n de dPrice
                                    colu m n va lu e s b y or de r .
                                      N ot e
I n t he URL at t he bot t om of t he pr evious page, not ice t hat
t he alias for t he t ot al of Ex t endedPrice per order is
OrderTot al. Alt hough t his alias appears in bracket s, t hey
aren’t st r ict ly necessar y. I could have used a SELECT
st at em ent w it h an alias of [ Or der Tot al] for t ot al
Ext endedPrice. However, because spaces ar e illegal in XML
nam es, t he par ser would aut om at ically conv ert t he nam e
when assigning it t o an at t ribut e for t he aggregat e colum n
value. I t is t o avoid t his renam ing pr ocess t hat I r evert ed t o
a nam e wit hout spaces. A slogan t hat I use in m y sem inars is
“Real program m ers do not use spaces.”
Som e applicat ions group m ult iple SELECT st at em ent s in a single connect ion t o a
dat abase serv er . This st rat egy r et ur ns m ult iple result s w it hout incur r ing t he cost
of a new connect ion for each result set . I f y our applicat ions can benefit from t his
capabilit y, av oid using NESTED as t he m ode set t ing for t he FOR XML clause in
your SELECT st at em ent s. The follow ing code sam ple shows a URL w it h t wo
SELECT st at em ent s. Not ice t hat a sem icolon delim it s t he t w o SELECT st at em ent s.
Each SELECT st at em ent designat es AUTO as t he m ode argum ent for it s FOR XML
clause. This st at em ent succeeds ev en if t he v irt ual dir ect or y enables client - side
for m at t ing. ( See Figure 6- 10.) However, updat ing eit her of t he AUTO k eyw ords
wit h NESTED generat es an er ror.
http://ccs1/MyNwind?sql=SELECT * FROM Shippers Œ
WHERE ShipperID=1 FOR XML AUTO;SELECT OrderID, OrderDate Œ
FROM Orders WHERE ShipVia=1 FOR XML AUTO&root=root


Figu re 6 - 1 0 . An X M L docu m e n t b a sed on t w o d ist in ct SELECT st a t e m en t s.
Tem pla t e Access t o SQL Se r ver
Tem plat es are XML files t hat reside in t he t em plat e folder of a v irt ual direct ory
point ing t o a SQL Ser ver dat abase. Developers can creat e solut ions t hat ret rieve
and m anipulat e t he dat a in a dat abase w it h t he XML files in a t em plat e folder. By
wrapping up t he code t o per form dat a r et r ieval and m anipulat ion operat ions in an
XML file, you can pr ot ect and secur e y our applicat ion’s code and t he dat abase it
references. Tem plat e- based solut ions ar e as easy t o r un as ent er ing a URL in a
browser or nav igat ing t o a URL from a cont rol on a form . The URL point s t o t he
XML file in t he t em plat e folder . You can m ake y our solut ions dy nam ic at run t im e
by passing param et ers in t he URL. To invoke t em plat e- based solut ions for a
dat abase, t he v irt ual dir ect ory point ing t o t he dat abase m ust have a t em plat e
folder. You can cr eat e a t em plat e folder r efer ence when y ou init ially creat e a
virt ual dir ect ory , or you can add a t em plat e folder or updat e t he nam e and
locat ion of a t em plat e folder for an ex ist ing v irt ual dir ect or y.
XML files in a t em plat e folder can cont ain sev er al t ypes of cont ent s t o r et r iev e
and m anipulat e t he dat a in a dat abase. I n t he “Annot at ed Schem as” sect ion
earlier in t his chapt er, y ou learned how t o use XML files in a t em plat e folder
cont aining annot at ed XSD schem as t hat ar e queried w it h t he XPat h language t o
ret riev e t he cont ent s of a SQL Serv er dat a sour ce. This sect ion shows how t o use
XML files wit h T- SQL st at em ent s; SQL Serv er dat abase obj ect s, such as user -
defined funct ions; and Updat egram s. Updat egr am s are a special t ype of XML file
for insert ing, updat ing, and delet ing dat a from SQL Ser ver t ables. St r ict ly
speaking, Updat egram s aren’t t em plat e files, but you st or e t hem in t he t em plat e
folder. XML files in a t em plat e folder can cont ain ot her t ypes of files, such as
DiffGram s. Microsoft int roduced DiffGram s for t ight int egrat ions w it h t he .NET
Fram ew ork , part icular ly t he ADO.NET Dat aSet com ponent . DiffGram s, like
Updat egram s, facilit at e t he m anipulat ion of dat a source cont ent s. I will r ev isit
DiffGram s in Chapt er 12.

Te m p la t e s w it h T- SQL St a t e m e n t s

Using an XML file in a t em plat e folder is a t wo- st ep pr ocess. First you cr eat e t he
XML file. Second y ou invok e t he file. I f y our t em plat e needs edit ing, y ou can pass
t hr ough t hese st eps as m any t im es as necessary t o fine- t une t he design of your
XML t em plat e file. The XML file m ust hav e a t op- level t ag, such as ROOT, w it h a
reference t o ur n: schem as- m icrosoft - com : xm l- sql. This nam espace cont ains t he
elem ent s and at t r ibut es for designing t em plat e files. Aft er you’ve declar ed t he
nam espace for t he elem ent s and at t r ibut es, t he ex act cont ent s of a t em plat e file
vary according t o y our obj ect iv es and how you go about im plem ent ing your
t em plat e- based solut ion. For exam ple, y ou can query a dat a source w it h eit her an
XPat h st at em ent or a T- SQL st at em ent . The elem ent s t hat y ou use in y our
t em plat e file v ary accor ding t o t he language for expressing t he query .
The follow ing docum ent illust rat es t he XML for m at t ing for a sim ple T- SQL
st at em ent . The ROOT elem ent designat es sql as r efer encing t he ur n: schem as-
m icr osoft - com : xm l- sql nam espace. Not ice t hat you em bed a T- SQL st at em ent in
a sql: quer y elem ent . The T- SQL st at em ent r et r iev es all rows and colum ns from
t he Shippers dat a source. The definit ion for t his dat a source depends on t he
virt ual dir ect ory holding t he XML file in it s t em plat e folder. I n t his chapt er, I use
t he My Nwind v irt ual dir ect ory point ing t o t he Nort hw ind dat abase. I f y ou r un t he
sam e XML file fr om t he t em plat e folder of a v irt ual dir ect or y point ing t o a
different dat abase, y ou can obt ain differ ent result s fr om t he sam e XML t em plat e
file.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--tmpSelectAllShippers.xml-->
       <sql:query>
            SELECT * FROM Shippers FOR XML RAW
       </sql:query>
</ROOT>

Figur e 6- 11 illust rat es a URL point ing t o t he t em plat e file and t he corr esponding
result set in t he browser. The FOR XML clause det erm ines t he XML for m at for t he
result set . The br owser’s Addr ess box in Figur e 6- 11 point s t o t he ccs1 I I S serv er
and t he My Nw ind v irt ual direct ory wit hin t he ser ver. The t em plat e folder has t he
nam e t em plat e, but any ot her legit im at e folder nam e w ill w or k as well so long as
you adj ust y our set t ings for t he v irt ual dir ect ory t o point t o it . The last it em in t he
Addr ess box specifically nam es t he XML file w it h t he SELECT st at em ent .

      Figu re 6 - 1 1 . Th e Addr ess box sh ow s t h e form a t for re fe rr in g t o a
       t e m pla t e file t h a t r et u r n s all t h e r ow s from t h e Sh ippe rs t a b le .




The sim ple form at for t he Addr ess box in Figur e 6- 11 enables y ou t o r eadily
creat e applicat ions t hat allow users t o t ap t he cont ent s of your dat abases from
anyw her e in t he wor ld. Because t he dat a ret ur ned is in XML form at , t he cont ent s
are r eadily usable by all applicat ions com pat ible wit h XML dat a. Also, you can
disable running quer ies direct ly from t he URL and bet t er secure your applicat ions.
Tem plat e files facilit at e sanct ioned r et rievals fr om your dat abase— nam ely, t hose
t hat y ou pr epr ogram for users.
I t is frequent ly desirable t o r et ur n a subset of records in a row source. This
capabilit y is ev en m or e powerful w hen y ou m ak e it dy nam ic at r un t im e so t hat
an applicat ion can det er m ine w hich subset t o r et urn according t o user input .
Enabling t em plat e files t o r et ur n result s based on param et ers sat isfies t his
requir em ent . Users can specify one or m or e par am et ers when t hey inv oke t he
t em plat e file. The param et ers can det erm ine t he r esult set fr om t he t em plat e file.
Creat ing dy nam ic t em plat e files t hat accept r un- t im e input requir es an updat ed
t em plat e design. I n part icular, y ou w ill need t o add a m inim um of t w o new
elem ent s t o an XML t em plat e file. First , y ou need a sql: header elem ent . You can
define one or m or e param et ers w it hin t his elem ent . Second, y ou need t he
sql: param elem ent . Use st art ing and ending sql: param t ags for each param et er .
Designat e t he param et er’s nam e as t he nam e at t ribut e for t he sql: param
elem ent . You can opt ionally specify a default value for t he par am et er . I f t he user
fails t o specify t he param et er at r un t im e, y our applicat ion can ex ecut e it s T- SQL
st at em ent wit h it s default param et er value. Wit hin a T- SQL st at em ent , designat e
t he param et er w it h a leading @ sym bol. I f y our param et er nam e is MyI D in t he
sql: param elem ent , y our T- SQL st at em ent should refer t o it as @My I D.

                                      N ot e
One sql: header elem ent can cont ain m ult iple par am et er
specificat ions. Reference m or e t han one param et er in a
t em plat e file by adding a sql: par am elem ent wit h a unique
nam e at t r ibut e for each addit ional param et er .
The follow ing XML docum ent illust rat es an ex t ension of t he preceding sam ple. A
WHERE clause in t he T- SQL uses a param et er t o specify which row t o r et riev e
from t he Shippers t able. Your applicat ion can specify t his value at run t im e by
including t he par am et er ’s nam e and value in t he URL invok ing t he t em plat e file.
Not ice t hat t he sql: param elem ent nam es t he param et er MyI D, and t he WHERE
clause designat es t he param et er as @MyI D. The par am et er’s default v alue is 1.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--tmpSelectShipperIDEquals.xml-->
      <sql:header>
           <sql:param name=‘MyID’>1</sql:param>
      </sql:header>
      <sql:query>
           SELECT * FROM Shippers WHERE ShipperID=@MyID FOR XML AUTO
      </sql:query>
</ROOT>

Figur e 6- 12 shows a browser inv ok ing t he t em plat e file w it h it s result set . The
URL t rails t he nam e for t he t em plat e file w it h a quest ion m ark ( ?) . Then t he URL
list s t he param et er nam e, an equal sign ( = ) , and t he param et er value, 3. I f you
had addit ional param et ers t o specify , you could delim it t hem from one anot her
wit h an am persand ( &) . Each param et er designat ion follows t he sam e form at :
param et er nam e, equal sign, param et er value. Failing t o specify a param et er at
run t im e ret ur ns t he row wit h a Shipper I D v alue of 1. I f your t em plat e file didn’t
specify a default value, t he result set w ould be em pt y. ( No error m essage is
ret ur ned.)

 Figu r e 6 - 1 2 . A sam p le de m on st r a t in g t h e sp ecificat ion of a p a ra m et e r in
  a URL in vok in g a t e m p la t e file t o r e t u rn a r ow fr om t h e Sh ipp er s t a ble .
XML t em plat e files wit h T- SQL don’t rest r ict y ou t o ret r iev ing dat a. You can
perform dat a m anipulat ion and even ot her t asks. The t r ick is t o use t he proper T-
SQL code and associat e a login wit h t he v irt ual dir ect or y t hat has per m ission t o
perform t he t asks y ou program in t he t em plat e file. ( Chapt er 7 exam ines SQL
Ser ver secur it y. ) For ex am ple, associat ing a login in t he sysadm in fix ed serv er
role enables t he ex ecut ion of t he next sam ple ( as well as t he updat egram
sam ples in t he chapt er ’s closing sect ion) . Using T- SQL in a t em plat e file is a very
rich appr oach because y ou can accom plish anyt hing t hat T- SQL perform s
( pr ov ided y our login account has pr oper perm ission) .
The next t em plat e file shows how t o use t he I NSERT and DELETE st at em ent s t o
first add and t hen r em ove a r ecord fr om t he Shippers t able. The t em plat e file
m onit ors t he st art ing, int erm ediat e, and ending st at es of t he Shippers t able wit h
a ser ies of SELECT st at em ent s. I n addit ion, t he T- SQL scr ipt in t he t em plat e file
reseeds t he I DENTI TY propert y for t he Shippers t able so t hat t he added r ecord
always appears w it h a ShipperI D value of 4 inst ead of a pr ogression of values,
such as 4, 5, 6, on successive execut ions of t he t em plat e file. This sam ple is
inst ruct ive because it shows t he use of t he DBCC CHECKI DENT st at em ent , w hich
is neit her a dat a r et riev al nor a m anipulat ion st at em ent .
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--tmpInsertAndDelete.xml-->
<sql:query>
       SELECT ’Shippers before an insert’
       SELECT *, ’Before Insert’ as At FROM Shippers FOR XML AUTO

    INSERT INTO Shippers (CompanyName, Phone) VALUES (‘foo’,’(123) 45
6-7890’)
    SELECT ’Shippers after an insert’
    SELECT *, ’After Insert’ as At FROM Shippers FOR XML AUTO

     DELETE FROM Shippers WHERE ShipperID > 3
     SELECT ’Shippers after deleting records with ShipperID > 3’
     SELECT *, ’After Delete’ as At FROM Shippers FOR XML AUTO

    <!--Reseed Identity for Shippers table so it starts from 3-->
    DBCC CHECKIDENT (Shippers, RESEED, 3)
</sql:query>
</ROOT>

Figur e 6- 13 shows t he r esult set s fr om t he SELECT st at em ent s in t he preceding
XML t em plat e file— one befor e t he insert , anot her aft er t he insert , and a final one
aft er t he delet e. Not ice t hat t he new record appears in t he m iddle result set . No
m at t er how m any t im es you rerun t he t em plat e file, t he ShipperI D value for t he
new record w ill always be 4. I f y ou st art ed w it h an init ial I DENTI TY value gr eat er
t han 3, t he first run of t he t em plat e file w ill reflect t he higher value, but all
subsequent successiv e r uns w ill act as if t he last I DENTI TY value wer e 3. This
behav ior reflect s t he im pact of t he DBCC CHECKI DENT st at em ent at t he close of
t he T- SQL script in t he t em plat e file.
 Figu r e 6 - 1 3 . Th is br ow se r sh ow s t h e im pa ct of a T- SQL scr ipt in a n X M L
t e m pla t e file t h a t a dds a n d t h e n r e m oves a row fr om t h e Sh ip per s t ab le .




Te m p la t e s En h a n ce d w it h D a t a ba se Obj e ct s

The “AUTO vs. NESTED Mode Sam ples” sect ion describes a T- SQL st at em ent for a
URL t hat com put es a sum wit h a GROUP BY clause. Unfort unat ely, t he sam e
st at em ent fails w hen ex ecut ed fr om wit hin an XML t em plat e file rat her t han a
URL. How ev er, y ou can st ill perform aggregat es wit h SELECT st at em ent s t hat
include GROUP BY clauses. The t r ick is t o cr eat e a v iew wit h t he GROUP BY clause
and aggr egat e funct ion. Then use t he v iew as t he source for a SELECT st at em ent
inside a t em plat e file. The t em plat e file r et ur ns rows wit h aggr egat ed v alues
based on t he com put at ions perform ed in t he v iew t hat serv es as it s source.
The follow ing scr ipt creat es a v iew based on t he T- SQL st at em ent used t o
populat e Figure 6- 9. Recall t hat t he figur e excerpt s t he out com e from a T- SQL
st at em ent in a URL t hat groups and aggr egat es colum n values fr om a r ow source.
The SELECT st at em ent for t he Order Tot alView v iew and t he quer y generat ing t he
result set excerpt ed in Figur e 6- 9 are ident ical except for t he FOR XML clause,
which is m issing fr om t he v iew. This v ar iance is because y ou want t he view t o
ret ur n a t radit ional rowset . A second quer y in a t em plat e file can r eference t he
Order Tot alView v iew as it s source argum ent in t he FROM clause. I t is in t he
t em plat e file t hat y our applicat ion can apply XML form at t ing t o t he rowset
ret ur ned by t he v iew.
--CreateOrderTotalView.sql
USE Northwind
GO
CREATE VIEW OrderTotalView AS
SELECT OrderID, CAST(SUM(ExtendedPrice) AS DEC(8,2)) OrderTotal
FROM Invoices
GROUP BY OrderID
GO

The XML t em plat e file can cont ain t he following XML scr ipt . By using t he
Order Tot alView v iew as it s source, t he query in t he t em plat e file draws on a
rowset w it h aggr egat ed ext ended pr ice across t he line it em s for each order in t he
I nv oices view . An alias ( I nv oices) for t he OrderTot alView v iew enables t he
SELECT st at em ent t o show I nv oices as t he ult im at e source for t he r esult s. The
XML form at t ed result set fr om running t his t em plat e file looks ident ical t o t he one
in Figur e 6- 9. However, t he cont ent s of t he Addr ess box are m uch m or e basic.
The URL m er ely references t he t em plat e file:
http://ccs1/MyNwind/template/tmpSelectFromAggregatingView.xml .
<!--tmpSelectFromAggregatingView.xml-->
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
      <sql:query >
        SELECT *
        FROM OrderTotalView AS Invoices
        FOR XML AUTO
    </sql:query>
</ROOT>

The solut ion is desirable if y ou want a report w it h t he t ot als for all t he orders, but
fr equent ly applicat ions r equire a result for j ust one it em or som e subset of it em s.
To m eet t his r equirem ent , you can aggr egat e by gr oup and t hen filt er based on
t he group values y our applicat ion needs t o r et urn. By r efer encing a t able- valued
user - defined funct ion fr om a query in a t em plat e file, you can enable a t em plat e
file t o dy nam ically filt er a rowset w it h r ows cont aining aggr egat ed values at run
t im e.
You can apply t he logic in t he pr eceding paragraph t o ext ending t he previous
sam ple. The pr ocess requir es t wo st eps. First creat e a user- defined funct ion
nam ed OrderTot alFunct ion t hat r et urns a t able based on t he I nv oices v iew. The
funct ion’s SELECT st at em ent aggr egat es t he Ex t endedPrice colum n fr om t he
I nv oices view by Order I D. The @My OrderI D par am et er in t he funct ion perm it s a
calling rout ine t o det er m ine for which order t he funct ion r et ur ns a t able. I n t his
case, t he t able consist s of a single row. Second creat e an XML t em plat e file
( t m pSelect From Aggregat ingTableUDF.xm l) t hat references t he user - defined
funct ion. The t em plat e file can use t he funct ion as t he source for a SELECT
st at em ent . I n addit ion, t he t em plat e file can pass a param et er t o t he funct ion t o
designat e which r ow t he user- defined funct ion should ret urn. At run t im e for t he
t em plat e, users can dy nam ically specify t he OrderI D of t he order for which t hey
want a t ot al.
Here’s t he script for cr eat ing t he user- defined funct ion. I t s SELECT st at em ent is
ident ical t o t he SELECT st at em ent in t he v iew for t he pr eceding sam ple except for
t he HAVI NG clause t hat filt ers t he r esult set and t he param et er, @MyOr derI D,
t hat facilit at es t he r un- t im e designat ion of w hich order t o r et urn t he sum for. See
t he “Creat ing and I nv ok ing Table- Valued UDFs” sect ion in Chapt er 5 for a r ev iew
of t he synt ax for user - defined funct ions.
--CreateOrderTotalFunction.sql
USE Northwind
GO
CREATE FUNCTION OrderTotalFunction(@MyOrderID int)
RETURNS TABLE
AS
RETURN(
       SELECT OrderID, CAST(SUM(ExtendedPrice) AS DEC(8,2)) OrderTotal
       FROM Invoices
       GROUP BY OrderID
       HAVING OrderID = @MyOrderID
)
GO

The follow ing XML docum ent invok es t he Order Tot alFunct ion udf. This docum ent
fulfills t he second st ep in t he applicat ion dev elopm ent pr ocess. I t defines a
param et er nam ed MyOrderI D wit h a default value. Ther efor e, users can get a
result set from r unning t he t em plat e file whet her or not t hey specify a param et er
value. Figur e 6- 14 show s t he XML form at t ed result set in t he browser from a URL
t hat specifies 10252 as t he param et er v alue.
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<!--tmpSelectFromAggregatingTableUDF.xml-->
       <sql:header>
             <sql:param name=‘MyOrderID’>10250</sql:param>
    </sql:header>
      <sql:query >
        Select * FROM OrderTotalFunction(@MyOrderID)
        FOR XML AUTO
    </sql:query>
</ROOT>


Figu r e 6 - 1 4 . Th is br ow se r sh ow s t h e re su lt se t fr om an X M L t em pla t e file
 t h a t in voke s a u ser - d e fin e d fun ct ion t o r e t u rn a n a ggr eg at e d va lu e for
                         t h e r ow s m at ch in g a spe cific Ord er I D .




Upda t e gr a m s Ar e lik e Te m p la t e s

Updat egram s ar en’t t em plat es, but you can invok e t hem in ways t hat are sim ilar
t o how you r un XML t em plat e files. Updat egram s offer an XML- based way t o
insert , delet e, and updat e rows in a SQL Serv er row source. Because
Updat egram s accept param et ers, your applicat ions can allow users t o specify
dynam ically w hat r ows t o insert , delet e, or updat e. A single Updat egram can
support m ult iple insert s, delet es, and updat es. I n addit ion, you can gr oup y our
dat a m anipulat ion t asks int o t ransact ions so t hat none w ill occur unless all t asks
wit hin t he t r ansact ion com plet e. You can even com pose an Updat egram wit h
m ult iple t ransact ions so t hat t he dat a m anipulat ion t asks in one t ransact ion occur
ev en if t hose in anot her t ransact ion r oll back. Per haps t he best feat ur e of
Updat egram s is t hat t heir synt ax is easy t o underst and.
The follow ing layout shows t he ov erall design for m ost Updat egram s. Not ice t hat
Updat egram s have t heir ow n nam espace. How ever, t hey follow st andar d XML
synt ax conv ent ions. You can opt ionally designat e an annot at ed schem a for t hem
t o w ork against . I f y ou don’t specify an annot at ed schem a, Updat egram s operat e
against what ev er row source you specify in t he updg: before and updg: aft er
elem ent s. The updg: sync elem ent allows y ou t o group dat a m anipulat ion t asks
int o t ransact ions. You can hav e m ult iple updg: sync elem ent s w it hin a single
Updat egram , but ev ery Updat egram m ust have at least one updg: sync elem ent .
Befor e t he first updg: sy nc elem ent , you can opt ionally insert an updg: header
elem ent , and w it hin t his elem ent y ou can insert one or m ore updg: param
elem ent s. You can use t hese updg: param elem ent s in Updat egram s in t he sam e
way t hat y ou do wit hin XML t em plat e files t o specify param et ers. Wit hin t he body
of t he Updat egram , you designat e param et ers wit h a leading $ ( dollar sign)
inst ead of t he @ ( at sy m bol) com m on in T- SQL code.
I t is wit hin t he updg: before and updg: aft er elem ent s t hat y ou specify m uch of t he
det ail work t hat an Updat egram perform s. For exam ple, y ou can insert a new r ow
of colum n values int o a row source by including a specificat ion for t he r ow w it hin
t he updg: before elem ent wit hout refer encing t he row wit hin t he updg: aft er
elem ent . I n cont rast , you can delet e a r ow by including a reference t o it wit hin
t he updg: aft er elem ent wit hout denot ing t he row in t he updg: befor e elem ent . To
specify an updat e, refer ence t he sam e r ow wit hin t he updg: before and updg: aft er
elem ent s. The colum n v alues in t he updg: befor e elem ent should ident ify t he row
( or rows) before t he updat e, and t he colum n v alues w it hin t he updg: aft er
elem ent should denot e t he new colum n values for t he rows t hat requir e
m odificat ion.
<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
<updg:sync [mapping-schema="SampleSchema.xml"] >
      <updg:before>
      </updg:before>
      <updg:after>
      </updg:after>
</updg:sync>
</ROOT>

The next script denot es t he cont ent s of an Updat egram t o add a new r ow t o t he
Shippers t able. The ent r y inside t he updg: aft er elem ent denot es t he colum n
values for t he new r ow. The new colum n values appear as at t ribut es for t he
Shippers elem ent . Don’t specify values for colum ns w it h an I DENTI TY propert y
set t ing because SQL Serv er aut om at ically adds values t o colum ns w it h an
I DENTI TY propert y. I t is for t his reason t hat t he Updat egram assigns no value t o
ShipperI D. The updg: befor e elem ent is em pt y . I t is t he com binat ion of an em pt y
updg: befor e elem ent and a populat ed updg: aft er elem ent t hat causes t he
Updat egram t o add a new r ow t o t he Shippers t able. You can save t his
Updat egram w it h a nam e, such as updgI nsert CABDeliv ers.xm l, in t he t em plat e
folder of a v irt ual direct ory point ing t o a dat abase wit h a Shippers t able. This
conv ent ion let s y ou invoke Updat egram s j ust as you do st andard XML t em plat e
files.
<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
<!--updgInsertCABDelivers.xml-->
<updg:sync >
       <updg:before>
       </updg:before>
       <updg:after>
             <Shippers CompanyName="CAB Delivers” Phone="(123) 456-7890”
/>
        </updg:after>
</updg:sync>
</ROOT>

I nst ead of specify ing t he new colum n values in a row as at t r ibut es of a single
elem ent in t he Updat egr am , y ou can designat e new values in an elem ent - cent r ic
hierarchical form at . The follow ing ex cerpt fr om
updgI nsert CABDeliv ersElem ent sI n.xm l illust rat es how t o lay out t he pr eceding
input dat a in a hierarchical form at . All ot her design feat ur es of t he
updgI nsert CABDeliv ersElem ent s- I n.xm l Updat egram m at ch t hose in
updgI nsert CABDeliv ers.xm l. The at t r ibut e- cent r ic and elem ent - cent r ic layout s
generat e XML docum ent s wit h ident ical cont ent , but t he form at of t he generat ed
docum ent changes bet w een t he t wo files— nam ely , updgI nsert CABDelivers.xm l
vs. updgI nsert CABDeliv ersElem ent sI n.xm l.
       <updg:after>
           <Shippers>
                <CompanyName>CAB Delivers</CompanyName>
                <Phone>(123) 456-7890</Phone>
           </Shippers>

You can r un t he elem ent - cent ric version of t he Updat egram by ent ering
ht t p: / / ccs1/ m ynw ind/ t em plat e/ updgI nsert CABDeliversElem ent sI n. xm l in t he
Addr ess box of a browser . As w it h XML t em plat e files, y ou designat e an I I S serv er
nam e, a v irt ual dir ect or y nam e, a t em plat e folder nam e, and finally t he
Updat egram filenam e. I f t he Updat egram succeeds, y our browser show s an XML
file w it h a single root elem ent cont aining t he Updat egram nam espace designat or.
( See Figure 6- 15.)

 Figu r e 6 - 1 5 . You in vok e an Upd a t e gr a m sim ila rly t o t h e w ay you r un a n
                                   X M L t e m plat e file .




Running t he t m pSelect AllShippers.xm l t em plat e file can confirm t he new r ow in
t he Shippers t able w it h a Com pany Nam e colum n value of CAB Delivers and a
Phone colum n v alue of ( 123) 456- 7890. The follow ing Updat egr am m odifies t he
Phone colum n value for t he newly added r ow. I t cont ains a single set of colum n
values in bot h t he updg: befor e and updg: aft er elem ent s. The values in t he
updg: befor e elem ent m ust refer ence a specific row in t he Shippers t able. I f t he
values denot e eit her m ore t han one row or no r ow, t he updat e fails w it h a
m essage in t he br owser alert ing t he user t o t he problem . The values in t he
updg: aft er elem ent include bot h t he Com pany Nam e t o ident ify t he row and a new
Phone value t o r eplace t he ex ist ing one. You can inv ok e
updgCABDeliversNewPhone.xm l in t he sam e way t hat you ran t he first
Updat egram . Because t he Updat egram m er ely ret urns a single- lined docum ent
wit h t he nam e of t he Updat egram nam espace, y ou m ight want t o rerun
t m pSelect AllShippers.x m l t o confirm t he updat e.
<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
<!--updgCABDeliversNewPhone.xml-->
<updg:sync >
      <updg:before>
             <Shippers CompanyName="CAB Delivers” Phone="(123) 456-7890”
/>
      </updg:before>
      <updg:after>
             <Shippers CompanyName="CAB Delivers” Phone="(234) 567-8901”
/>
      </updg:after>
</updg:sync>
</ROOT>

You can r em ove a row from a t able by uniquely ident ify ing it in t he updg: before
elem ent and leav ing t he updg: aft er elem ent em pt y. The ident ify ing colum n
values t hat y ou specify in t he updg: before elem ent m ust point t o a unique r ow in
a t able. I f t he colum n v alues y ou use t o denot e a t arget row aren’t unique, t he
Updat egram r et urns an er ror m essage. For t his reason, y ou should consider using
prim ary k ey values w hen specify ing r ows for delet ion. The sam ple below uses t he
Com panyNam e colum n value t o ident ify t he row t o delet e because t he ShipperI D
value is set by SQL Ser ver. You can r ev ise t he Updat egram t o delet e a row based
on ShipperI D by running t m pSelect AllShippers. xm l t o discover t he t arget
ShipperI D value and t hen using t hat value in t he updg: befor e elem ent . Finally,
you can r un t he Updat egram lik e eit her of t he preceding t w o sam ples. The URL I
ent er ed was ht t p: / / ccs1/ My Nw ind/ t em plat e/ updgDelet eCABDeliv ers.xm l. You w ill
need t o revise t he nam es for t he I I S serv er , v ir t ual dir ect ory, and t em plat e folder
for y our applicat ion’s environm ent .
<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
<!--updgDeleteCABDelivers.xml-->
<updg:sync >
      <updg:before>
           <Shippers CompanyName="CAB Delivers"/>
      </updg:before>
       <updg:after>
       </updg:after>
</updg:sync>
</ROOT>

The next sam ple dem onst rat es t he synt ax for using param et ers as you add a new
row t o a t able. The Updat egram declar es t he param et ers w it h updg: par am
elem ent s. The sam ple designat es t wo param et ers nam ed Com panyNam e and
Phone. The code doesn’t assign default param et er v alues, so your applicat ion
m ust specify values for t he param et ers at r un t im e. The updg: aft er elem ent
dem onst rat es t he synt ax for r eferr ing back t o t he param et ers as you specify a
new row for a t able. As you can see, t he r ule is t o use t he param et er nam e w it h a
leading $.
<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
<!--updgInsertShippersParams.xml-->
<updg:header>
     <updg:param name="CompanyName” />
     <updg:param name="Phone” />
</updg:header>
<updg:sync >
     <updg:before>
     </updg:before>
     <updg:after>
           <Shippers CompanyName="$CompanyName” Phone="$Phone” />
     </updg:after>
</updg:sync>
</ROOT>

You can r un a param et r ically specified Updat egr am j ust as you would any XML
t em plat e file w it h param et ers. Ent er a URL int o a browser t hat st art s wit h t he
pat h t o t he Updat egram on t he I I S ser ver. Follow t his w it h a quest ion m ark ( ?)
and nam e- value pairs for each param et er t hat t he Updat egram requir es. Figure
6- 16 shows t he sy nt ax for adding a shipper w it h a Com pany Nam e field of CAB
Deliv ers and a Phone field of ( 123) 456- 7890. The br owser aut om at ically r eplaces
each blank space w it h % 20.

 Figu r e 6 - 1 6 . D e sign at e p ar am e t er va lu e s a t ru n t im e for a n Upda t e gr a m
                         j u st a s you d o for a n X M L t em pla t e file.




The approach dem onst rat ed for adding a r ow based on run- t im e param et ers
applies t o delet ing and updat ing a r ow. The follow ing Updat egr am shows t he
synt ax for r em ov ing a r ow from t he Shippers t able based on ShipperI D value.
Users can r un t m pSelect AllShippers.xm l t o det erm ine t he ShipperI D value for t he
row t hey want t o delet e. For exam ple, if t he t arget row t o delet e had a ShipperI D
value of 5, y ou could r em ov e it by ent er ing
ht t p: / / ccs1/ MyNw ind/ t em plat e/ updgDelet eShippersParam s.xm l?ShipperI D= 5 in
t he browser .
<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
<!--updgDeleteShippersParams.xml-->
<updg:header>
        <updg:param name="ShipperID"/>
</updg:header>
<updg:sync >
        <updg:before>
               <Shippers ShipperID="$ShipperID"/>
        </updg:before>
        <updg:after>
        </updg:after>
</updg:sync>
</ROOT>
Cha pt e r 7 . SQL Se r ve r 2 0 0 0 Se cur it y
I n t hese t im es, all infor m at ion t echnology professionals, including dat abase
dev elopers, hav e a pr essing need t o prot ect t heir syst em s. There is no m agic pill
you can t ake t o inoculat e y our syst em s against any k ind of securit y at t ack t hat
ev er did, or w ill, ex ist . Secur ing syst em s is a m at t er of learning your applicat ions
and j udiciously apply ing t he securit y m easur es appropriat e for y our com put ing
env ir onm ent . This chapt er exposes y ou t o t he securit y feat ures available w it h
Micr osoft SQL Serv er 2000. Use t he foundat ion you get from t his chapt er as a
basis for dr illing down deeper int o select ed t opics t hat you feel a need t o lear n in
great er dept h.
Aside from general securit y concer ns, SQL Serv er 2000 developers hav e specific
reasons for needing t o k now about secur it y. For exam ple, t he only way users can
connect t o a SQL Ser ver inst ance is by specify ing a login account . Aft er gaining
access t o t he dat abase serv er w it h a login account , users cannot t ypically gain
access t o a dat abase ex cept by hav ing a user account associat ed w it h t he login
account . Furt herm ore, login account and user account m em bership in v arious
fix ed and user - defined r oles enable users t o per for m server and dat abase
funct ions, including m anaging secur it y for a ser ver and it s dat abases or ev en for
t he dat abases on ot her serv ers.
The t wo resources for t his chapt er ar e sim ilar t o t hose for Chapt er 2 t hrough
Chapt er 5. The first resource is a set of T- SQL script s wit h t he sam ples in t his
chapt er . These T- SQL script s oft en r efer ence t he second resource, t he Chapt er07
dat abase. I n fact , t here is a script am ong t he sam ples files for t his book t o cr eat e
t he dat abase, but t he sam ples also include a copy of t he dat abase files
t hem selves ( Chapt er07_dat .m df and Chapt er07_log.ldf) for y our easy reference.
The script s in t his chapt er differ fr om t hose of preceding chapt ers in t hat t he login
for dat abase connect ions var ies bet ween script s. By using differ ent logins, t he
sam ples enable y ou t o evaluat e t he effect s of different t ypes of logins as well as
underst and how t o cr eat e t hose logins.




Ove r view of SQL Ser v er Secu r it y
SQL Ser ver secur it y cent ers on t he dat abase serv er, but t he m anagem ent of
secur it y ext ends upwar d t o t he operat ing syst em on w hich SQL Serv er runs and
downward t o client w or kst at ions t hat connect t o a com put er r unning SQL Ser ver.

Se cu r it y Accou nt s

SQL Ser ver has t wo m ain k inds of securit y account s. The first k ind of secur it y
account grant s access t o a dat abase serv er. SQL Serv er calls t his first k ind of
secur it y account a login secur it y account or a login. The second kind of secur it y
account grant s access t o a dat abase w it hin a serv er. SQL Serv er applies t he
nam e user secur it y account or user t o t his k ind of secur it y account . User account s
allow y our applicat ion’s users t o gain access t o t he r esources t hat y ou creat e for
t heir use on a SQL Ser v er inst ance. Any one login account can have m ult iple user
secur it y account s associat ed w it h it — one for each dat abase t o which t he login
needs access.
Ev er y SQL Ser ver inst ance m aint ains a collect ion of logins. A login is like a k ey
t hat let s a user open t he door int o a SQL Serv er inst ance. There ar e t hree t ypes
of logins. These t ypes of logins r elat e t o how SQL Server validat es a user. The
Windows User and Windows Group are t wo t y pes of logins t hat r elat e t o t he
Windows operat ing syst em . These ar e account s validat ed by Windows. When y ou
creat e a Windows User login t ype wit hin a SQL Server inst ance for a Windows
user , t hat user can gain access t o t he SQL Serv er inst ance w it hout t he need t o
revalidat e her cr edent ials. SQL Ser ver accept s t he Windows user account as valid
for access t o SQL Serv er. The sam e general not ion applies t o a Window s Group
t ype login except t hat SQL Ser ver accept s t he Windows login as valid for any
m em ber of t he Window s group.
SQL Ser ver can also m anage it s ow n login account s. These ar e st andar d logins.
SQL Ser ver m ust m anage t he login nam e and password in t his case. While SQL
Ser ver secur it y m anagem ent feat ures aren’t as rich as t hose for Windows, t her e
are t im es w hen st andar d secur it y login account s are especially useful. First , if
SQL Ser ver is running on an operat ing syst em ot her t han Windows NT, Windows
2000, or Windows XP, such as Windows 98, y ou m ust use st andard logins.
Second, if your applicat ion has users w ho aren’t regist ered wit h a Windows
dom ain serv er, t hese users r equir e SQL Serv er logins. Third, SQL Serv er logins
are also necessary for com pat ibilit y wit h applicat ions cont aining dat a im port ed
from dat abase v endors ot her t han Micr osoft .
No m at t er what t ype of securit y login a user pr esent s, users also generally m ust
hav e user securit y account s for dat abase access. The ex cept ions r elat e t o login
account s w it h br oad aut hor it y and dat abases w it h guest account s for logins
wit hout a user account . User secur it y account s r eside w it h each dat abase.
Howev er, all user account s except t he guest account m ust relat e t o a specific
login. The login t ype can be Windows User, Windows Group, or st andar d.

Au t h e nt ica t ion

As t he prev ious sect ion indicat es, login secur it y account s ar e w hat client s present
t o a dat abase serv er t o gain access t o t he ser ver. Aut hent icat ion is t he process by
which a dat abase server accept s t he login secur it y account and det erm ines
whet her it is v alid. SQL Ser ver 2000 support s t wo aut hent icat ion m odes. These
are Windows Aut hent icat ion Mode, which is t he default m ode, and Mix ed Mode.
For serv ers running wit h Windows Aut hent icat ion Mode, dat abase user s don’t
need t o validat e t hem selv es when t hey at t em pt t o gain access t o a dat abase
serv er. For serv ers running Mix ed Mode, only dat abase users wit h a SQL Ser ver
login m ust subm it t heir login nam e and passwor d when at t em pt ing t o gain access
t o a serv er . Dat abase users wit h a Windows User or Windows Group login t ype on
t he SQL Serv er inst ance ar en’t pr om pt ed a second t im e t o validat e t heir
credent ials.
The default m ode allows login t o a SQL Serv er inst ance only v ia a Windows
account . All dat abase users m ust m eet t wo cr it eria wit h Windows Aut hent icat ion
Mode. First , dat abase users m ust have a valid Windows account w it h a dom ain
serv er for eit her Windows NT or Windows 2000. Second, t he SQL Ser v er inst ance
m anaging a dat abase m ust aut hor ize t he indiv idual user ’s Windows account or a
Windows gr oup t o w hich t he indiv idual user belongs. Windows users w it hout an
account t hat SQL Ser ver r ecognizes cannot ent er t he dat abase.
When y ou inst all w it h t he default m ode, t he Windows Adm inist rat or account on
t he com put er r unning t he SQL Serv er inst ance is t he serv ice account for SQL
Ser ver. The inst allat ion process aut om at ically cr eat es a login for t he
Adm inist rat or account t hat is a m em ber of t he sysadm in fixed serv er r ole. ( You
can ov err ide t his select ion of a serv ice account .) As a result , t he login for t he
Adm inist rat or account enj oy s near ly all t he pr iv ileges of t he t radit ional sa secur it y
account . One cr it ical differ ence is t hat you can delet e t he login for t he
Adm inist rat or account , but y ou cannot delet e t he sa login.
Wit h Mixed Mode aut hent icat ion, users can log in if t hey hav e an account w it h a
Windows dom ain serv er or a SQL Serv er login m aint ained by a SQL Serv er
inst ance. When y ou inst all t he dat abase server on a com put er running Windows
98 or Windows Millennium Edit ion, SQL Serv er aut om at ically r uns w it h Mix ed
Mode aut hent icat ion. I f your SQL Serv er inst ance is an applicat ion serv er on a
wor kgr oup inst ead of a dom ain, and one or m or e of y our client workst at ions r un
Windows 98, y our serv er m ust support Mix ed Mode aut hent icat ion. This
requir em ent exist s whet her or not SQL Serv er 2000 r uns on a com put er wit h
eit her t he Windows 2000 or t he Windows NT operat ing syst em .

                                    N ot e
When y ou choose Mixed Mode aut hent icat ion during SQL
Server 2000 inst allat ion, a r em inder appears t o assign a
password t o t he sa login. Failing t o proper ly respond t o t his
rem inder opens y our com put er t o unwarrant ed ent ry.

Role s a n d Pe r m ission s

Get t ing int o a SQL Serv er inst ance doesn’t necessarily ensur e t hat y ou can do
anyt hing once you get t her e. The role m em bership of login and user secur it y
account s conveys perm issions t o perform v arious t asks— bot h for t he serv er and
for t he dat abases m aint ained on a serv er. Som e roles ar e fix ed— t hat is, specified
by SQL Serv er. Two collect ions of fix ed r oles ar e t he fix ed ser ver roles and fixed
dat abase roles. SQL Ser ver also perm it s t he cr eat ion of user - defined roles. Wit h
user - defined r oles, you can assign t he pr ecise perm issions t hat an applicat ion
requir es. Perm issions ar e of t wo general t ypes. First , you can assign perm issions
for dat abase obj ect s, such as t he abilit y t o select rows fr om a t able or v iew.
These perm issions are called obj ect perm issions. Second, you can gr ant t he
aut horit y t o exercise a subset of t he T- SQL st at em ent s, such as CREATE TABLE.
These perm issions are called st at em ent perm issions.
The fixed serv er r oles convey perm issions for ser ver t asks, such as cr eat ing,
alt er ing, and dropping dat abases or m anaging logins for ot her users and changing
t heir passwords. SQL Ser ver 2000 offers eight fix ed serv er r oles. ( See Table 7- 1.)
The Bulk I nsert role is new w it h SQL Serv er 2000. An indiv idual login can belong
t o none, one, or m or e t han one of t hese r oles. Run t he sp_addsrvr olem em ber
syst em st ored procedur e t o add a login t o a fix ed server role. Dat abase users
inherit t he perm issions for any fix ed serv er r oles t o which t heir logins belong. You
cannot dir ect ly assign a user account t o a fix ed serv er r ole. Use t he
sp_helpsrvr ole syst em st or ed procedure t o obt ain a list of t he fix ed ser v er r ole
nam es along w it h br ief descript ions. I nv ok e t he sp_srvroleperm ission syst em
st ored procedure for a det ailed list of T- SQL st at em ent s and ser ver funct ions for
which each fix ed ser ver role gr ant s perm ission.
Fix ed dat abase roles conv ey right s w it hin a dat abase, such as t he abilit y t o select
or change dat a as w ell as t he abilit y t o add new dat abase obj ect s. There ar e nine
fix ed dat abase r oles. ( See Table 7- 2.) Use t he sp_addrolem em ber syst em st ored
procedur e t o assign a user secur it y account t o a fixed dat abase r ole in t he current
dat abase. The secur it y account used t o designat e m em bership in a fixed dat abase
role can be a user account in t he curr ent dat abase based on a SQL Ser ver login, a
Windows User login, or a Windows Gr oup login. Just as wit h t he fix ed ser ver
roles, t her e ar e t w o syst em st or ed procedur es t o help you discover m ore about
t he fix ed dat abase roles. I nvoke sp_helpdbfix edrole for a list ing of t he r oles w it h
brief descript ions. Run sp_dbfix edr oleperm ission t o v iew t he com plet e list of
perm issions associat ed wit h each fixed dat abase role.
                               7DEOH  )L[HG 6HUYHU 5ROHV

  5ROH 1DPH                                    6HOHFWHG 7DVNV
Sysadm in         Can per form any t ask and gain unr est rict ed access t o all dat abases
Ser veradm in     Can per form sp_configure and SHUTDOWN oper at ions
Set upadm in      Can designat e a st or ed procedur e t o run at st art up and m anage
                  linked serv er specificat ions
Secur it yadm in Can per form sp_grant login, sp_addlogin, and sp_deny login
                 procedur es; can also m anage dat abase cr eat ion perm issions and
                 password changes
Processadm in Can per form KI LL operat ions
Dbcreat or        Can per form CREATE DATABASE, ALTER DATABASE, and DROP
                  DATABASE operat ions
Diskadm in        Can per form sp_addum pdev ice and sp_dropdev ice procedures
Bulkadm in        Can per form BULK I NSERT operat ions
Besides t he nine fixed dat abase roles in Table 7- 2, anot her r ole ex ist s wit hin each
dat abase: t he public r ole. All dat abase users belong t o t he public r ole and can
ex ercise w hat ever perm issions t he role allows. Each dat abase has it s own set of
fix ed dat abase r oles, including t he public r ole. Mem bership in a r ole wit hin one
dat abase doesn’t conv ey m em bership in t he sam e role for any ot her dat abase. I n
addit ion, t he public role in one dat abase can possess different per m issions t han
t he public r ole in anot her dat abase.

                                     N ot e
I t ’s oft en good pract ice t o st r ip all perm issions from t he
public role so t hat users in a dat abase derive no per m issions
j ust from t heir abilit y t o access a dat abase. This pract ice is
especially im por t ant when y ou have a guest user account in
a dat abase because t he guest account , which allows
dat abase access by any login, is a m em ber of t he public role.
                              7DEOH  )L[HG 'DWDEDVH 5ROHV

     5ROH 1DPH                                     6HOHFWHG 7DVNV
db_owner               Can per form any t ask in a dat abase
db_accessadm in        Can per form sp_grant dbaccess and sp_rev ok edbaccess
                       procedur es
db_securit yadm in     Can per form sp_addrolem em ber and sp_dr opr olem em ber
                       procedur es
db_ddladm in           Can ex ecut e CREATE, ALTER, and DROP st at em ent s for
                       obj ect s in a dat abase
db_backupoperat or Can per form BACKUP DATABASE and BACKUP LOG operat ions
db_dat areader         Can per form SELECT operat ions for any obj ect in a dat abase
db_dat awrit er        Can per form I NSERT, UPDATE, and DELETE operat ions for
                       any obj ect in a dat abase
db_denydat ar eader Cannot perform SELECT operat ions for any obj ect s in a
                    dat abase
db_denydat awr it er Cannot perform I NSERT, UPDATE, or DELETE operat ions for
                          any obj ect in a dat abase
I n addit ion t o t he fix ed roles list ed in Tables 7- 1 and 7- 2, SQL Serv er perm it s t he
creat ion of user- defined roles. Creat e user- defined r oles when y our securit y
needs ar e m or e granular t han t hose accom m odat ed by t he fix ed roles. I nvok e t he
sp_addrole syst em st or ed pr ocedure t o cr eat e a new user- defined r ole. Aft er
creat ing a r ole, y ou can add m em bers t o it w it h t he sp_addrolem em ber syst em
st ored procedure. You can assign m em bers t o user- defined roles fr om t he sam e
set of secur it y account s as for fix ed dat abase roles. Of course, y ou can m anage
perm issions for a user - defined r ole so t hat m em bership has it s pr iv ileges! Just as
wit h fix ed roles, user - defined r oles ex ist wit hin a dat abase. Two user - defined
roles in differ ent dat abases wit h t he sam e nam e can hav e differ ent m em bers and
conv ey differ ent perm issions wit hin each dat abase. You can m anage user- defined
roles wit h any login t hat belongs t o t he sysadm in fixed serv er r ole or any user
secur it y account t hat is a m em ber of t he db_ow ner or db_secur it y adm in fixed
dat abase role.
You can assign t w o t ypes of perm issions t o user - defined roles. The first k ind of
perm issions grant s aut hor it y for dat abase obj ect s. These perm issions include
SELECT, I NSERT, UPDATE, DELETE, REFERENCES, and EXECUTE. You can apply
SELECT, I NSERT, UPDATE, and DELETE perm issions t o any ent ir e t able, v iew, or
t able- v alued user - defined funct ion. I n addit ion, y ou can apply SELECT and
UPDATE perm issions t o any subset of t he colum ns in a t able or v iew. EXECUTE
perm ission pert ains t o bot h st or ed pr ocedur es and user- defined funct ions.
REFERENCES allows t wo different t ypes of perm issions. First , you can use
REFERENCES t o designat e perm ission t o r eference t he prim ary k ey in one t able
as a m at ch for t he for eign k ey in anot her t able. Second, you can also invok e t he
REFERENCES perm ission t o enable a view or a user - defined funct ion t o specify it s
sources for SCHEMABI NDI NG. The REFERENCES perm ission becom es necessary
for t hese cases w hen t he owner of t he t able wit h t he pr im ary k ey is differ ent from
t he ow ner of t he t able wit h t he for eign key or t he ow ner of a view or user- defined
funct ion is different fr om it s base t ables or v iews.
The second k ind of per m issions t hat you can add t o user - defined r oles is T- SQL
st at em ent perm issions. Wit h t hese perm issions, t he m em bers of y our user-
defined roles can per for m t ask s such as creat ing dat abases and creat ing t ables,
views, st or ed procedures, and user - defined funct ions w it hin a dat abase. The
“Managing Perm issions” t opic in Books Online includes t he full list of st at em ent s
t o w hich y ou can grant perm issions.
T- SQL offers t hree st at em ent s for m anaging t he perm issions t hat a role can
conv ey t o it s m em bers. The GRANT st at em ent giv es a perm ission t o a r ole. The
REVOKE and DENY st at em ent s can bot h disable a perm ission in a role. When t he
sam e user belongs t o m ult iple roles, conflict s wit h perm issions can ex ist . A
perm ission conv ey ed t hrough a GRANT st at em ent for one r ole over rides a
REVOKE st at em ent for t he sam e perm ission in any ot her role. However , a DENY
st at em ent ov er r ides any GRANT st at em ent . Ther efor e, a user belonging t o t w o
different roles w it h a GRANT st at em ent and a DENY st at em ent for t he sam e
perm ission in bot h r oles won’t hav e t he perm ission.




I n t r odu ct ion t o Specia l Se cu r it y I ssu es
A var iet y of special SQL Serv er secur it y t opics fall out side t he scope of t he
preceding sum m ary of secur it y account s, aut hent icat ion, r oles, and per m issions.
This sect ion addr esses t hr ee of t hese t opics. First , you lear n about applicat ion
roles, w hich are a cust om t ype of user - defined roles t hat can pr ov ide unique
access t o a dat abase. Second, I explor e t echniques for w or king wit h linked
serv ers, which let y our users fr om one SQL Ser ver inst ance r eadily connect w it h
dat abase resources on anot her SQL Serv er inst ance. Third, t his sect ion includes
an exam inat ion of secur it y issues relat ing t o v irt ual dir ect or ies, such as t hose
review ed in Chapt er 6 for Web dat a access and m anipulat ion v ia XML.

Applica t ion Role s
Applicat ion r oles pr ov ide a dat abase access rout e t hat com plem ent s t hose
afforded by SQL Serv er secur it y account s. I nst ead of accessing a dat abase wit h
logins and user account s, an applicat ion r ole prov ides access t o a dat abase v ia
t he applicat ion role’s nam e and password. Any dat abase user w it h perm ission t o
creat e a user- defined r ole can creat e an applicat ion role wit h t he sp_addapprole
syst em st ored procedur e. Aft er cr eat ing an applicat ion r ole, assign perm issions t o
it in t he sam e way t hat you do for user - defined dat abase roles. Users log in t o an
applicat ion r ole wit h t he sp_set approle syst em st or ed pr ocedur e. There are no
role m em bership requirem ent s t o inv ok e sp_set approle.
When a user invokes an applicat ion role, she loses all ot her securit y set t ings
associat ed wit h a dat abase connect ion. A user m ust disconnect and reconnect t o
regain st andard secur it y for her login and user secur it y account s. How ever, a user
of an applicat ion r ole does enj oy any right s for t he guest user in t he cur rent
dat abase or any ot her dat abase. Therefore, you m ust be careful t o adm inist er
perm issions for t he guest user t o m anage t he perm issions available t hr ough an
applicat ion r ole.
One dist inct advant age of an applicat ion r ole is t hat it can prov ide a single point
of access for a dat abase. All users m ust reference t he sam e applicat ion role nam e
and password wit h sp_set appr ole t o open an applicat ion r ole. Furt herm or e, wit h
t he st andard SQL Serv er secur it y feat ur es, y ou can r est rict access t o a dat abase
so t hat t he only way for users t o gain access t o it is t hrough t he applicat ion role.
I n t hat case, y ou can uniform ly define t he per m issions for all users of a dat abase
( except for sysadm in m em bers, w ho hav e unrest rict ed access t o all r esources on
a dat abase ser ver) .

Link e d Se r ve r s

Link ed serv ers are an alt er nat iv e t echnique t o t he OPENROWSET funct ion for
im plem ent ing r em ot e serv er access and het erogeneous quer ies. See t he “ Views
for Rem ot e and Het er ogeneous Sources” sect ion in Chapt er 4 for sam ples
illust rat ing t he use of t he OPENROWSET funct ion. As t hat sect ion dem onst rat es,
t his capabilit y facilit at es per form ing queries for a dat a source on anot her
com put er, such as a SQL Serv er inst ance r unning on anot her com put er , or
quer ies against a differ ent dat abase, such as Or acle or Access. Link ed ser vers
readily support quer ies t o any dat a source for which t her e is an OLE DB dat a
prov ider w it h t he proper feat ure set . Micr osoft explicit ly t est ed link ed serv ers w it h
fiv e OLE DB prov iders: Micr osoft OLE DB pr ov ider for SQL Serv er , Micr osoft OLE
DB pr ov ider for Jet , Microsoft OLE DB provider for Oracle, Micr osoft OLE DB
prov ider for ODBC, and Micr osoft OLE DB pr ov ider for I ndex ing Serv ice.
One advant age of t he OPENROWSET funct ion over a link ed ser ver is t hat t he
OPENROWSET funct ion requir es only your ex ist ing user credent ials for t he r em ot e
or het erogeneous dat a source. While t he sy nt ax for specify ing dist r ibut ed quer ies
wit h linked ser vers is sim pler t han t hat for t he OPENROWSET funct ion, a m em ber
from eit her t he sysadm in or set upadm in fix ed ser ver role m ust add t he link ed
serv er befor e you can use it . Wit h t he OPENROWSET funct ion, any user w it h t he
credent ials t o connect t o a rem ot e or het erogeneous dat a source can im m ediat ely
m ake t he query.
Your init ial query fr om a link ed serv er r equires t hr ee st eps. First y ou m ust creat e
a link ed serv er refer ence on t he curr ent com put er r unning SQL Serv er 2000.
Second y ou m ust m ap a login on t he cur r ent com put er t o a login for t he rem ot e
or het erogeneous dat a source. Third y ou m ust specify t he query for t he rem ot e or
het er ogeneous dat a source w it h a four - part nam ing conv ent ion. The first part
denot es t he link ed serv er r efer ence. The second, t hird, and fourt h part s com plet e
t he unique ident ificat ion of t he source; how you specify t hese part s can var y
depending on t he source. The fourt h part t ypically specifies t he t able or v iew in
t he t arget dat a source. Aft er t he init ial quer y, using a link ed serv er is easier t han
using t he OPENROWSET funct ion because t he link ed serv er sy nt ax is m or e
st raight forward, and y ou no longer hav e t o perform t he first t wo st eps.
Creat e a link ed serv er for a r em ot e or het er ogeneous dat a source w it h t he
sp_addlinkedserv er syst em st ored procedure. This procedure can t ak e as m any
as seven argum ent s, but you can use as few as t wo argum ent s for cr eat ing a
reference t o a rem ot e SQL Server source and as few as four argum ent s for a
linked ser ver point ing t o an Access dat a source. Aft er cor rect ly init ializing t he
linked ser ver reference wit h t he sp_addlink edserver syst em st ored pr ocedur e,
inv oke sp_addlink edsrv login for m apping logins on t he curr ent SQL Ser v er 2000
inst ance t o logins for t he rem ot e or het er ogeneous dat a source. When a user runs
a query on t he local ser ver against t he link ed ser ver, t he local serv er logs in t o
t he link ed serv er w it h t he credent ials specified when t he sp_addlink edsrv login
syst em st ored procedur e was last r un for t he link ed serv er. You can invok e t he
sp_linkedserv ers syst em st ored pr ocedur e t o it em ize in a r esult set t he link ed
serv ers defined on a local serv er .

Se cu r it y for Vir t ua l D ir e ct or ie s

Virt ual direct ories ar e necessary for Web dat a access t o SQL Serv er dat a sources
via XML. Each dat abase t hat r equires Web access via XML m ust have a virt ual
dir ect or y point ing t o it . As described in t he “ Virt ual Direct ory Managem ent ”
sect ion of Chapt er 6, y ou m ust designat e a login for t he virt ual dir ect or y. All
access t o t he dat abase is m apped t hrough t he login t hat y ou specify on t he
Secur it y t ab of t he Pr opert ies dialog for a dir ect ory .
Figur e 7- 1 shows t he Propert ies dialog box used for t he MyNwind v irt ual direct ory
t hat ser ved as t he source for m ost of t he sam ples in Chapt er 6. Not ice t hat t he
Secur it y t ab specifies I USR_CCS1 in t he User Nam e t ext box. The User Nam e t ext
box cont ains t he login nam e for t he v irt ual dir ect ory . Select ing Windows as t he
Account Type aut om at ically inst alls I USR_ser ver nam e as t he login. Windows 2000
Ser ver aut om at ically inst alls t he I USR_ser ver nam e user account . I I S
aut om at ically uses t his Windows user account for anonym ous login. Since t he
sam ples for Chapt er 6 r an fr om a serv er nam ed ccs1, t he dialog replaced
serv er nam e w it h CCS1.

Figu r e 7 - 1 . Use t h e Se cu r it y t a b for a vir t u a l dire ct or y t o spe cify t h e login
 by w h ich u se r s of t h e virt u a l dire ct or y w ill ga in a cce ss t o a SQL Se rve r.
I f you decide t o allow access t o your dat abase t hr ough t he I USR_serv ernam e
Windows account , y ou m ust m anually cr eat e a login for t he Windows user on
your SQL Serv er inst ance. Then y ou m ust creat e a user secur it y account in t he
dat abase t o w hich t he v irt ual direct ory point s. Finally y ou m ust assign
perm issions t o t he I USR_serv er nam e securit y account appropriat e t o t he needs of
your applicat ion. For ex am ple, if y ou want t o enable br owsers t o r ead from any
row source in t he dat abase, y ou can assign t he I USR_serv er nam e user account t o
t he db_dat areader fix ed dat abase role. I f you have m ore r est rict ive requir em ent s,
use t he T- SQL GRANT st at em ent t o specify m or e granular perm issions, such as
t he abilit y t o view j ust one t able or v iew. Mak e sure t he dat abase has perm issions
for t he public role t hat don’t allow t he I USR_ser vernam e account t o access t he
dat abase wit h a differ ent set of perm issions t han t he one y ou specify explicit ly for
t he v irt ual dir ect or y user account .
When y ou decide t o per m it updat es, insert s, and delet es t o a dat abase t hr ough a
virt ual ser ver, t he user securit y account for t he virt ual dir ect ory ’s login m ust
enable t hese act ions. My adv ice is t o carefully r est rict t he row sources t hat y ou
m ake available for updat ing over t he Web. Av oid assigning t he I USR_ser vernam e
account t o t he db_dat awr it er fix ed dat abase r ole. I nst ead, assign I NSERT,
UPDATE, or DELETE per m issions w it h t he T- SQL GRANT st at em ent for whichever
dat abase obj ect s requir e m odificat ion ov er t he Web.
Sa m ple s for Login s a n d Use r s
Login and user secur it y account s com plem ent one anot her. Recall t hat a login
aut horizes access t o a ser ver, but a user account grant s access t o a dat abase on
a serv er. The users of y our applicat ions t ypically need bot h t ypes of secur it y
account s t o access a dat abase on a SQL Serv er inst ance. I n addit ion, t her e are
t wo dist inct t ypes of logins. The sam ples in t his sect ion explore t he different k inds
of logins for SQL Serv er and how t hey relat e t o user secur it y account s. All t he
script s in t his sect ion ar e in t he LoginAndDr opUsers.sql sam ple file.

Add a SQL Se r ve r Login a n d Use r

Recall t hat a login get s a user int o a ser ver but not necessarily int o any dat abases
on t he serv er . This is because a login t ypically r equires a m at ching securit y
account for each dat abase t o w hich a user is t o hav e access. Howev er, t her e are
t wo ways in w hich a user can access a dat abase wit hout a user account for t he
dat abase. First , t he dat abase can hav e a guest account . The user w ill t hen enj oy
any perm issions assigned explicit ly t o t he guest account or indirect ly t o t he guest
account t hr ough perm issions for a dat abase’s public role. Second, if a login is a
m em ber of t he sysadm in fixed serv er role, it can access any dat abase on a serv er
wit hout any r est rict ions on it s funct ionalit y . For t his reason, y ou want t o lim it t he
num ber of logins w it h m em bership in t he sysadm in role. I f y ou need t o carefully
specify how t he user of a login can int eract wit h a dat abase, y ou m ust creat e a
user securit y account for t he login in t he dat abase.
I nvok e t he sp_addlogin syst em st ored procedur e t o creat e a new SQL Ser ver
login. Wit h t he sp_addlogin syst em st ored pr ocedur e, you can cr eat e a login t hat
SQL Ser ver m anages. When users at t em pt t o gain access t o a SQL Serv er
inst ance w it h t his login, t hey m ust explicit ly designat e bot h t he login nam e and
it s associat ed password. To creat e a SQL Serv er login, y ou m ust be a m em ber of
eit her t he sysadm in or securit yadm in fixed ser v er r ole. Any user can change her
own password w it h t he sp_password syst em st or ed procedur e. Only m em bers of
t he sysadm in and secur it yadm in fixed serv er r oles can invoke sp_password t o
change t he password for a login differ ent fr om t heir ow n.

                                      N ot e
While a SQL Ser ver login enables a user t o connect t o a SQL
Server inst ance by specifying a login nam e and password, it
is t he SI D ( secur it y ident ifier) t hat SQL Ser ver uses t o
ident ify and t r ack t he user. SQL Ser ver int ernally generat es a
GUI D t o r epr esent t he SI D for SQL Server logins.
I nvok e t he sp_grant dbaccess syst em st ored procedure t o cr eat e a user secur it y
account in a dat abase for a login. Only m em bers of t he sysadm in fixed serv er r ole
as well as t he db_owner and db_accessadm in fix ed dat abase r oles can run
sp_grant dbaccess. Before r unning sp_grant dbaccess, m ake sur e t he dat abase
cont ext is set t o t he dat abase in which you want t o creat e a user securit y
account . For exam ple, inv ok e t he USE st at em ent for a dat abase nam e befor e
running sp_grant dbaccess.
The follow ing T- SQL script uses sp_addlogin t o creat e a new SQL Serv er login. I t
is m andat or y t o specify t he @loginam e and @passwd argum ent s for t he
sp_addlogin syst em st ored pr ocedure. You can opt ionally specify sever al ot her
argum ent s t o change t he default set t ings deriv ed from y our SQL Serv er
configurat ion. For exam ple, t he script dem onst r at es t he synt ax for designat ing a
default dat abase of Chapt er07, t he sam ple dat abase for t his chapt er . I f t he script
didn’t m ak e t his assignm ent for t he @defdb ar gum ent , t he default dat abase
would have been t he m ast er dat abase. The m ast er dat abase is one of t he built - in
dat abases t hat SQL Ser ver uses t o adm inist er it self. While all users r equir e access
t o t his dat abase, you probably don’t want t o m ake it t he default dat abase for
t ypical users.
Not ice t hat t he scr ipt ex plicit ly refer ences t he m ast er dat abase befor e invok ing
sp_addlogin. This r efer ence isn’t st rict ly necessary since you can cr eat e a login
secur it y account fr om any dat abase on a serv er . How ev er , t he sam ple script
inv okes t he USE st at em ent t wo m ore t im es, and t hese t wo r efer ences are
necessary . You m ust invok e t he USE st at em ent befor e r unning t he
sp_grant dbaccess syst em st ored pr ocedur e. Recall t hat t his syst em st ored
procedur e cr eat es a user secur it y account . Set t ing t he dat abase cont ext befor e
inv ok ing sp_grant dbaccess det erm ines t he dat abase for w hich t he syst em st ored
procedur e cr eat es a user secur it y account .
--LoginAndDropUsers
--Create a SQL Server login with access
--to the Chapter07 and Northwind databases.
USE master
EXEC sp_addlogin
       @loginame = ’vbdotnet1’,
       @passwd= ’passvbdotnet1’,
       @defdb = ’Chapter07’
USE Chapter07
EXEC sp_grantdbaccess ’vbdotnet1’
USE Northwind
EXEC sp_grantdbaccess ’vbdotnet1’

The vbdot net 1 login doesn’t st rict ly requir e a user secur it y account for t he
Nort hwind dat abase because t his sam ple dat abase has a guest account , and t he
public role for t he dat abase grant s perm issions t o all dat abase obj ect s in t he
init ial version of t he dat abase. Howev er, cr eat ing a user account for t he
vbdot net 1 login allows y ou t o rem ove t he guest account for t he dat abase and st ill
m aint ain dat a access privileges. I n addit ion, a user account for t he vbdot net 1
login enables a dat abase designer t o fine- t une t he perm issions available t o t he
login relat iv e t o ot her dat abase users.

Re m ove a SQL Se r ve r Login a n d Use r

I n t he norm al course of dat abase m anagem ent , it becom es necessary t o rem ov e
as well as add dat abase users. Since a SQL Ser ver dat abase user has t wo
different secur it y account t ypes, y ou m ust rem ov e bot h t o flush a user com plet ely
from a dat abase serv er. To pr ev ent orphaned user account s, SQL Ser v er doesn’t
allow y ou t o delet e t he login for a user w it hout delet ing t he user account s
associat ed wit h t hat login. Rem ov ing t he user account s wit hout elim inat ing t heir
login st ill allows a user t o access a dat abase ser ver, and t he login can access any
dat abases wit h a guest account .

                                    N ot e
I n addit ion t o being unable t o rem ove a login wit h one or
m ore associat ed user account s, y ou cannot rem ove a login
t hat is current ly in use, owns a dat abase, or owns a j ob in
t he m sdb dat abase. A j ob is a sequence of st eps for
aut om at ing a t ask t hat is defined in t he m sdb dat abase, one
of t he built - in dat abases t hat SQL Server uses t o m anage
it self. As m ent ioned prev iously, you can nev er r em ove t he sa
login from a SQL Server inst ance.
Befor e y ou at t em pt t o r em ove a login, it ’s useful t o sur vey any associat ed user
secur it y account s associat ed w it h t he login. This perm it s y ou t o m ak e sur e t hat
you can r em ove all of t he user securit y account s associat ed w it h a login before
at t em pt ing t o rem ov e t he login. I nv ok e t he sp_helplogins syst em st or ed
procedur e wit h t he nam e of t he login for which you’re seek ing infor m at ion, as
show n in t he follow ing code. The syst em st or ed procedur e r et urns a r esult set
com prising t wo recordset s. The first r ecordset cont ains a single row for t he login
t hat y ou specify. The second recordset cont ains a r ow for each user account
associat ed wit h t he login nam ed as t he argum ent for t he sp_helplogins syst em
st ored procedure. I f you don’t specify a login nam e as an argum ent w hen y ou
inv oke sp_helplogins, t he syst em st or ed procedur e st ill r et urns t wo recordset s.
Howev er, t hese recordset s ret urn inform at ion for all t he logins on t he cur rent SQL
Ser ver inst ance.
--Return info about a login, including
--its database user accounts.
EXEC sp_helplogins @LoginNamePattern=‘vbdotnet1’

Figur e 7- 2 shows t he t w o r ecordset s t hat result from running sp_helplogins
vbdot net 1 aft er first inv ok ing t he scr ipt in t he preceding sect ion. The fir st
recordset st art s wit h t he login nam e follow ed by a part ial display of t he login’s
SI D. The nex t t wo colum ns indicat e t he default dat abase and language for t he
login. The next - t o- last colum n, AUser, is yes w hen t he login has at least one
corr esponding user account . The last colum n, ARem ot e, indicat es whet her t he
login specifies a r em ot e login for a link ed serv er. The second recordset prov ides
inform at ion about each user account for t he login. The first and t hird colum ns
denot e, respect ively , t he login nam e and t he user nam e. By default , t hese are t he
sam e, but you can ov er ride t his convent ion. The second colum n designat es t he
dat abase t o w hich t he user account belongs. The last colum n specifies whet her
t he user account is for an indiv idual user or a role.

Figu r e 7 - 2 . Use t h e sp_ h e lplogin s syst e m st ore d pr oce d u r e t o le a rn a bou t
                             a log in on a da t ab a se ser ve r .




Arm ed w it h t he inform at ion in Figure 7- 2, y ou can const ruct a T- SQL script like
t he follow ing t o r em ove t he vbdot net 1 secur it y account s fr om t he serv er. St art by
inv ok ing t he sp_r ev okedbaccess syst em st ored procedure in each dat abase wit h a
user account for t he vbdot net 1 login. Specify t he user account nam e as t he
argum ent for t he sp_r evokedbaccess syst em st or ed procedur e. Not ice t hat t he
script inv ok es sp_rev ok edbaccess t wice— once in each dat abase for w hich t he
vbdot net 1 login has a user account . The scr ipt closes by r unning t he sp_droplogin
syst em st ored procedur e. This syst em st or ed pr ocedur e r equir es j ust one
argum ent specify ing t he nam e of t he login t o r em ov e. The perm issions for
rem ov ing user account s and logins m at ch t hose for adding t hem : a login
at t em pt ing t o rem ov e a login m ust be a m em ber of t he sy sadm in or
secur it yadm in fix ed ser ver r ole t o r un sp_droplogin.
--Drop a SQL Server login,
--first revoking its user accounts.
USE Northwind
EXEC sp_revokedbaccess ’vbdotnet1’
USE Chapter07
EXEC sp_revokedbaccess ’vbdotnet1’
EXEC sp_droplogin @loginame = ’vbdotnet1’



Addin g a n d Re m ovin g Logins for a W in dow s Use r

Managing a login based on a Windows user account for Windows NT, Windows
2000, or Windows XP is sim ilar t o m anaging a SQL Ser ver login. By a Windows
user account , I m ean t he account by w hich Windows validat es a user . From a
user perspect iv e, t he m ain difference is t hat a login based on a Windows user
account doesn’t hav e t o specify a login and password w hen connect ing t o a SQL
Ser ver inst ance. For a dat abase user w it h a login based on a Windows user
account , all a user has t o do is select t he Windows Aut hent icat ion opt ion in t he
Connect To SQL Serv er dialog box of Quer y Analyzer. I f t he t arget SQL Ser ver
inst ance has a login for t he Windows user account , t he connect ion at t em pt
succeeds. Howev er, a m em ber of t he sysadm in group m ust first creat e a login for
t he Windows account in order for t he at t em pt t o succeed.
The process for cr eat ing login and user secur it y account s based on a Windows
user account is sim ilar t o t hat for m anaging SQL Serv er logins. When creat ing a
login for a Windows user account , inv ok e t he sp_grant login syst em st or ed
procedur e t o cr eat e a login for t he Windows user. When y ou designat e a login
nam e for a Windows user account , t he nam e m ust hav e t w o part s delim it ed by a
backslash ( \ ) . The part befor e t he backslash is t he nam e of t he Windows serv er.
The part aft er t he backslash is t he nam e of t he Windows user.
The sp_grant login syst em st ored pr ocedur e is analogous t o t he sp_addlogin
syst em st ored procedur e. Bot h of t hese syst em st ored procedures creat e a new
login. SQL Serv er saves bot h of t he logins in t he syslogins t able. SQL Ser ver also
report s bot h t ypes of logins in t he sam e colum n of t he r esult set from t he
sp_helplogins syst em st or ed procedur e. How ev er, t he login creat ed w it h
sp_grant login is aut hent icat ed by a Windows 2000 or Windows NT serv er. When a
Windows user at t em pt s t o connect , SQL Serv er st ores t he Windows secur it y
ident ifier for t he Windows user . The Windows secur it y ident ifier is analogous t o
t he SQL Serv er SI D. Howev er , t he Windows securit y ident ifier is m anaged by t he
Windows serv er, and t he Windows secur it y ident ifier is longer t han t he SQL
Ser ver SI D ( 85 byt es for Windows and 16 byt es for SQL Ser ver ) .
Aft er y ou creat e a login for a Windows user account , t he login cannot connect t o
any dat abase w it hout a user secur it y account unless t he dat abase has a guest
account . You can creat e a user secur it y account for a login based on a Windows
user account wit h t he ident ical procedure for a SQL Ser ver login. First set t he
dat abase cont ext for t he user secur it y account . For exam ple, inv ok e t he USE
st at em ent t o specify t he nam e of t he dat abase for which y ou want t o creat e a
user account . Second r un sp_grant dbaccess wit h t he nam e of t he login as it s
argum ent .
The follow ing short script dem onst rat es t he synt ax for cr eat ing a login based on a
Windows user account . The Windows user account resides on a Windows 2000
Ser ver nam ed CCS1. The nam e of t he account on t he Windows serv er is
winvbdot net 1. The last t wo lines of t he script cr eat e a user secur it y account in t he
Chapt er07 dat abase based on t he login cr eat ed wit h sp_grant login.
--Create a Windows login with
--access to Chapter07 database.
EXEC sp_grantlogin ’CCS1\winvbdotnet1’
USE Chapter07
EXEC sp_grantdbaccess ’CCS1\winvbdotnet1’
                                  N ot e
I f t he Windows user account is for a Window s serv er t hat
isn’t a dom ain ser ver but m er ely an applicat ion serv er , you
m ust cr eat e a local account on a Windows NT Wor kst at ion or
Windows 2000 Professional client com put er wit h t he sam e
nam e and password as on t he Windows server .
Rem oving t he login is a t wo- st ep pr ocess because t he login has a single user
secur it y account associat ed w it h it . First r em ov e t he user account for t he
Chapt er07 dat abase. The syst em st or ed procedur e for elim inat ing a user secur it y
account based on a login for a Windows user account is t he sam e as for delet ing a
user account based on a SQL Serv er login. Second r ev ok e t he login. When
dropping a login, y ou use a differ ent sy st em st ored procedure for one based on a
Windows user account t han for one creat ed by SQL Ser ver. Here is t he T- SQL
code for im plem ent ing t he st eps.
--Drop a Windows login with sp_revokelogin,
--but first revoke its user accounts.
USE Chapter07
EXEC sp_revokedbaccess ’CCS1\winvbdotnet1’
EXEC sp_revokelogin ’CCS1\winvbdotnet1’


       W ho’s Using Your Applica t ion?
By now, y ou should feel com fort able wit h t he idea t hat t her e
are act ually t wo r easonable answer s t o t his quest ion. The fir st
answer is t he login nam e. This nam e ident ifies a user as she
ent er s a SQL Serv er inst ance. The second answer is t he nam e
of t he user securit y account . This ident ifies a user w it hin a
dat abase. I f a login doesn’t hav e a user securit y account
assigned explicit ly t o it for a dat abase and t he dat abase has a
guest account , t he login can ent er t he dat abase wit h t he guest
user account .
SQL Server 2000 offer s t wo built - in funct ions for t elling you
t he login nam e and user account nam e of t he user perform ing
a t ask in your dat abase. The SYSTEM_USER funct ion ret urns
t he login nam e. The CURRENT_USER funct ion r et urns t he user
account nam e. Befor e discussing a list ing t o clarify t he
operat ion of t hese funct ions, I want t o m ent ion t he DB_NAME
funct ion. When you ent er DB_NAME( ) in a SELECT st at em ent ,
it r et ur ns t he nam e of t he cur rent dat abase.
The following short script invokes t he SYSTEM_USER and
CURRENT_USER funct ions in t hree different dat abases—
m ast er, Nor t hwind, and Chapt er 07. I f y ou r un t his script aft er
connect ing t o a SQL Serv er inst ance wit h t he
CCS1\ winvbdot net 1 login, you obt ain an ident ical result set
fr om each SELECT st at em ent . However , t wo differ ent values
are display ed for t he CURRENT_USER funct ion. I n t he m ast er
and Nor t hw ind dat abases, t he CURRENT_USER funct ion
ret ur ns guest . I n t he Chapt er07 dat abase, t he
CURRENT_USER funct ion ret urns CCS1\ winvbdot net 1. This is
because t he login has a user account nam ed aft er it in t he
Chapt er 07 dat abase.
--
Demonstrate functions telling who’s using a database.
USE master
SELECT DB_NAME(), SYSTEM_USER, CURRENT_USER
USE Northwind
SELECT DB_NAME(), SYSTEM_USER, CURRENT_USER
USE Chapter07
SELECT DB_NAME(), SYSTEM_USER, CURRENT_USER


Pr oce ssin g Logins Ba se d on W in dow s Gr ou ps

I n addit ion t o basing a login on an indiv idual Windows user account , you can also
creat e a login for a Windows group account . The lat t er t y pe of Window s account
prov ides a single nam e for r efer encing m or e t han one indiv idual Windows
account . When you cr eat e a login based on a Windows group, all t he indiv idual
m em bers of t he group inher it t he login assigned t o t he gr oup. I n addit ion, y ou
can creat e separat e logins for a subset of t he indiv idual m em bers of a Windows
group. These logins for indiv idual Windows account s com plem ent t he login based
on t he Windows group account by pr ov iding an alt er nat ive r out e int o a SQL
Ser ver inst ance and t he dat abases on it .
The sam ple for t his sect ion works w it h a Windows group nam ed w invbdot net . The
group cont ains t wo individual Windows user account s nam ed w invbdot net 1 and
winvbdot net 2. All t he account s reside on a CCS1 Windows 2000 serv er. The
follow ing T- SQL script shows t he code for cr eat ing dist inct logins for t he Windows
group and t he indiv idual Windows account s t hat belong t o t he Windows group.
Aft er t he ex ecut ion of t he script , bot h t he w inv bdot net 1 and w inv bdot net 2 users
connect t o t he SQL Ser v er inst ance w it h t heir own logins as w ell as t he login for
t he Windows group. I n addit ion, bot h individual Windows user account s hav e
t heir own user account s in t he Chapt er07 dat abase, and t he Windows user
account s m ap t o t he Chapt er07 user account for t he Windows group.
--Create login for winvbdotnet Windows group.
EXEC sp_grantlogin ’CCS1\winvbdotnet’
USE Chapter07
EXEC sp_grantdbaccess ’CCS1\winvbdotnet’

--Also create logins for group members individually.
EXEC sp_grantlogin ’CCS1\winvbdotnet1’
EXEC sp_grantdbaccess ’CCS1\winvbdotnet1’
EXEC sp_grantlogin ’CCS1\winvbdotnet2’
EXEC sp_grantdbaccess ’CCS1\winvbdotnet2’
GO

Ther e ar e act ually t w o ways t o m ak e a login unavailable for use. First , you can
run t he sp_revok elogin syst em st ored procedur e as dem onst rat ed in t he
preceding sect ion. This approach r em oves t he login for t he Windows user fr om
t he dat abase server. Wit h t his approach in t he curr ent cont ext , r ev ok ing t he
CCS1\ w invbdot net 1 Windows user login st ill per m it s t he w invbdot net 1 Windows
m em ber of t he w invbdot net group t o connect t o t he dat abase serv er. This
capabilit y is possible because t he Windows user can access t he dat abase serv er
t hr ough t he login for t he w invbdot net Windows group.
The follow ing scr ipt shows t he sy nt ax for a second appr oach. I t denies login
perm ission t o an ex ist ing login— in t his case, t he one for t he w invbdot net 1
Windows user. This approach st ill perm it s t he w invbdot net 2 Windows user t o
access t he dat abase ser ver. However, by denying t he login perm ission for t he
CCS1\ w invbdot net 1 login, t he script ov er rides t he abilit y of t he w invbdot net 1
Windows user t o access t he dat abase serv er t hr ough t he CCS1\ w invbdot net login.
--This does not affect winvbdotnet2,
--which is a member in winvbdotnet group.
EXEC sp_denylogin ’CCS1\winvbdotnet1’
GO

The follow ing one- line script blocks t he winvbdot net 2 Windows user fr om
accessing t he dat abase serv er. The logins for t he w invbdot net 1 and w invbdot net 2
Windows users ar e st ill on t he dat abase serv er. I n addit ion, t he
CCS1\ w invbdot net login st ill aut hor izes it s m em bers t o log in t o t he ser ver. A
deny set t ing ( inst it ut ed by t he sp_deny login syst em st or ed procedur e) for t he
indiv idual Windows account s ov er r ides t he access grant ed by t he sp_gr ant login
syst em st ored procedur e for t he CCS1\ winvbdot net Windows gr oup account . This
general r ule is t r ue for all perm issions. A deny set t ing ov er r ides a grant set t ing.
--This does affect winvbdotnet2,
--which is a member in winvbdotnet group.
EXEC sp_denylogin ’CCS1\winvbdotnet2’
GO

To rem ov e t he logins for t he indiv idual Window s users and t he Window s group t o
which t he users belong, you should r ev ok e t he dat abase access t o t he user
secur it y account s cor responding t o logins. Then you can r ev ok e t he specific logins
for t he Windows users and Windows group. The follow ing scr ipt shows t he synt ax
for accom plishing t hese t asks. While t he sp_denylogin syst em st ored pr ocedure
disables a login fr om accessing a serv er , t his sy st em st ored pr ocedur e doesn’t
rem ov e t he login from a SQL Serv er inst ance— inst ead, you need t he
sp_revok elogin syst em st ored procedure t o accom plish t he t ask.
--Cleanup account settings.
USE Chapter07
EXEC sp_revokedbaccess ’CCS1\winvbdotnet’
EXEC sp_revokedbaccess ’CCS1\winvbdotnet1’
EXEC sp_revokedbaccess ’CCS1\winvbdotnet2’
EXEC sp_revokelogin ’CCS1\winvbdotnet’
EXEC sp_revokelogin ’CCS1\winvbdotnet1’
EXEC sp_revokelogin ’CCS1\winvbdotnet2’
GO




Sa m ple s for Assign in g Per m ission s
This sect ion dem onst rat es t he essent ial T- SQL st at em ent s for organizing
perm issions w it hin a dat abase. Specific t echniques ex ist for obj ect and st at em ent
perm issions. I n addit ion, t he final t opic in t he sect ion rev eals how t o m anage
perm issions w hen a user account can possess a perm ission dir ect ly as well as
indirect ly t hrough it s m em bership in one or m ore Windows account s or SQL
Ser ver roles.
The sam ples in t his sect ion rely on a v ersion of t he Em ailCont act s t able. The
“Scr ipt ing Tables” sect ion of Chapt er 2 init ially present ed t he T- SQL code for t his
t able. For t he purposes of t his chapt er, y ou can r e- cr eat e t his t able in t he
Chapt er07 dat abase sim ply by changing t he references t o t he Chapt er02
dat abase in Chapt er 2 t o t he Chapt er07 dat abase. A copy of t he m odified code
ex ist s in t he sam ple file Creat eEm ailCont act sTable.sql for y our easy r eference.
This sect ion also r elies on t he ex ist ence of t he four logins w it h t heir m at ching
user securit y account s creat ed so far in t his chapt er. Recall t hat one login is a
SQL Ser ver login ( vbdot net 1) , anot her t w o are Windows user logins
( CCS1\ w invbdot net 1 and CCS1\ winvbdot net 2) , and a fourt h login is a Windows
group login ( CCS1\ winv bdot net ) com pr ising each of t he t wo Windows user
account s. This sect ion present s t he T- SQL code for assigning perm issions t o t he
user account s for t he logins. The perm issions relat e t o t he Em ailCont act s t able.
Ther efor e, creat e t he Em ailCont act s t able w it h a m em ber of t he sysadm in fix ed
serv er r ole, such as t he Windows Adm inist rat or user account or t he SQL Ser ver
sa login.

Se le ct , I nse r t , a nd D e le t e Pe r m ission s for a Ta ble

To evaluat e t he effect of perm ission assignm ent s, you w ill need t w o concurr ent
act ive connect ions t o your dat abase server. Connect once as a m em ber of t he
sysadm in fixed serv er role, and connect a second t im e w it h a SQL Ser ver login—
nam ely, vbdot net 1. Not e t hat if you ran t he code show n ear lier t o drop t he
vbdot net 1 login account , y ou’ll need t o rer un t he code t hat creat es t he account .
To confirm t hat t he user account for t he vbdot net 1 login has no perm issions in
t he Chapt er07 dat abase, at t em pt t o r un t he follow ing script w it h t he user account
for t he login. Not ice t hat t he at t em pt ret urns an error m essage say ing, in effect ,
t hat SELECT perm ission is denied on t he Em ailCont act s obj ect in t he Chapt er07
dat abase.
--SelectInsertDeletePermission
--The SELECT succeeds if the user has
--SELECT permission.
USE Chapter07
SELECT * FROM EmailContacts

To rem edy t he er r or condit ion, y ou need t o assign SELECT perm ission for t he
Em ailCont act s t able t o t he vbdot net 1 user account . Fr om your session init iat ed by
a sysadm in m em ber, run t he follow ing line of T- SQL. You m ust inv ok e t his line of
code from y our session for t he sysadm in r ole m em ber. You can also always
assign perm issions from a session w it h any m em ber of t he db_ow ner fixed
dat abase roles. Sessions for select ed ot her user account s w ill w or k in special
circum st ances; see t he “GRANT” t opic in Books Online for det ails. Recall also t hat
m em bers of t he sysadm in r ole hav e perm ission t o perform all t asks on a
dat abase serv er .
--Assign SELECT permission for the EmailContacts
--table to the vbdotnet1 user account.
GRANT SELECT ON EmailContacts TO vbdotnet1

Not ice t hat y ou can assign a SELECT perm ission wit h t he GRANT T- SQL
st at em ent . The sam ple in t he preceding T- SQL st at em ent uses t he SELECT
keyw ord. This k eyw ord denot es t he perm ission t o r un a SELECT st at em ent , such
as t he sam ple t o select all colum ns for all rows from t he Em ailCont act s t able. You
can opt ionally assign I NSERT, UPDATE, DELETE, and REFERENCES per m issions
for a t able. When concurr ent ly assigning m or e t han one perm ission, delim it t he
it em s in y our list of per m issions w it h com m as. Aft er t he perm issions, use t he
keyw ord ON and t hen specify t he row source, which is t he Em ailCont act s t able in
t his dem onst rat ion. Conclude t he GRANT st at em ent w it h t he TO k eyword followed
by t he account t o w hich you ar e grant ing perm ission. The pr eceding GRANT
st at em ent designat es t he user secur it y account for t he vbdot net 1 login. You can
alt er nat ively specify a SQL Ser ver role for one or m or e user account s or t he user
secur it y account s for a Windows user or a Windows gr oup account .
Aft er invok ing t he pr eceding GRANT st at em ent , t he session for t he vbdot net 1
user can ex ecut e a SELECT st at em ent against t he Em ailCont act s t able. Howev er,
t he follow ing at t em pt s from t he vbdot net 1 connect ion t o insert a r ow and t hen
delet e t he row fail w it h a pair of er r or m essages about denied I NSERT and
DELETE perm issions. Again, t he problem is t hat t he vbdot net 1 user doesn’t have
t he proper perm issions.
--Run from Chapter07 database context for vbdotnet1 user.
INSERT INTO EmailContacts
      VALUES(3,’Tony’, ’Hill’, ’thill@cabinc.net’)
SELECT * FROM EmailContacts
GO

DELETE
FROM EmailContacts
WHERE Email1 = ’thill@cabinc.net’
SELECT * FROM EmailContacts
GO

Running t he follow ing st at em ent fr om t he sysadm in session enables t he
vbdot net 1 user account wit h t he pr oper perm issions t o ex ecut e t he pr eceding
script . Not ice t hat t he synt ax for adding m ult iple perm issions is t he sam e as for
adding a single perm ission except t hat you delim it perm issions w it h a com m a.
The follow ing st at em ent adds I NSERT and DELETE per m issions t o t he exist ing
SELECT perm ission for t he vbdot net 1 user account .
--Delimit more than one permission in a GRANT
--statement by using a comma.
GRANT INSERT, DELETE ON EmailContacts TO vbdotnet1

You can drop all perm issions for t he vbdot net 1 user account by r evok ing or
denying t hem . When you are work ing w it h an indiv idual user account t hat doesn’t
belong t o any role, you can eit her revoke or deny ex ist ing perm issions for t he
account . Use t he REVOKE st at em ent w it h t he ALL k ey word t o r em ove any ex ist ing
perm issions from a user account . The follow ing one- line script dem onst rat es t he
synt ax for dr opping t he SELECT, I NSERT, and DELETE perm issions from
vbdot net 1.
--Use the ALL keyword to concurrently
--drop all existing permissions.
REVOKE ALL ON EmailContacts TO vbdotnet1



Pe r m ission t o Cr e a t e a Ta ble

When y ou assign t he perm ission t o creat e a t able t o user account s for any login
not in t he sysadm in fix ed serv er role, y ou com plicat e how an applicat ion m ust
refer t o t ables. This is because all m em bers of t he sysadm in fix ed serv er r ole ar e
t he dbo user. This dbo user belongs t o all dat abases. You cannot dr op t he dbo
user from a dat abase— j ust as no one can dr op t he sa login fr om an inst ance of
SQL Ser ver. The rules for r efer encing t ables cr eat ed by t he dbo user are differ ent
t han t hose for t ables cr eat ed by any ot her dat abase user.
Ev er y user can refer im plicit ly t o t ables cr eat ed by t he dbo user . When t he
sam ples in t he preceding sect ion referenced Em ailCont act s, t hey im plicit ly
referred t o dbo.Em ailCont act s because t he t able was cr eat ed by a m em ber of t he
sysadm in fixed serv er role. SQL Serv er requires you t o explicit ly refer t o t ables
creat ed by ot her users.
When a user w ho doesn’t qualify as a dbo user creat es a t able, ot her users can
refer t o t he t able by t he nam e of t he t able’s ow ner and t he t able’s nam e. For
exam ple, if vbdot net 1, who isn’t a dbo user, cr eat es a t able nam ed Em ailCont act s
in t he Chapt er07 dat abase, ot her users m ust r efer t o t he t able as
vbdot net 1.Em ailCont act s. The vbdot net 1 user can refer t o t he Em ailCont act s
t able t hat it cr eat ed as eit her vbdot net 1.Em ailCont act s or j ust Em ailCont act s.
Howev er, if t hat user w ant s t o reference t he dbo Em ailCont act s t able, he m ust
specify dbo.Em ailCont act s. I f any ot her user, w ho didn’t herself cr eat e a t able
nam ed Em ailCont act s, r efers t o a t able w it h Em ailCont act s, SQL Serv er
aut om at ically int erpr et s t his as a r efer ence t o dbo. Em ailCont act s.

                                     N ot e
When y ou perm it non- dbo users t o creat e t ables, a best
pract ice is always t o use t he owner qualifier when r eferring
t o a t able. I f a dbo user cr eat es a t able nam ed
Em ailCont act s, refer t o it as dbo.Em ailCont act s. I f a non- dbo
user, such as v bdotnet 1, cr eat es a t able nam ed
Em ailCont act s, refer t o it as vbdot net 1.Em ailCont act s.
Because users who writ e t heir own T- SQL st at em ent s can
dev iat e fr om t hese rules and t he rules lengt hen T- SQL
st at em ent s in any ev ent , rest r ict t he per m ission t o creat e
t ables t o t he dbo user if at all possible.
The follow ing line of script shows t he sy nt ax for enabling t he vbdot net 1 user t o
creat e a t able. Set t he dat abase cont ext if it isn’t already set t o t he dat abase for
which you want t o grant t he perm ission. Not ice t hat t he sy nt ax for grant ing
perm ission t o ex ecut e a st at em ent is slight ly different t han for an obj ect
perm ission. Aft er t he GRANT k eyw ord, y ou list t he st at em ent for w hich you ar e
grant ing perm ission, but t her e’s no need t o follow t his st at em ent w it h t he ON
keyw ord. I n addit ion t o CREATE TABLE, y ou can refer ence CREATE DATABASE,
CREATE VI EW, CREATE PROCEDURE, CREATE FUNCTI ON, and select ed ot her
st at em ent s. ( See t he “GRANT” t opic in Books Online for t he com plet e list .) As
wit h grant ing obj ect per m issions, y ou can use a com m a delim it er when
concur r ent ly grant ing perm ission for m or e t han one st at em ent . Close t he GRANT
st at em ent wit h t he TO k eyw ord follow ed by t he nam e of t he account t hat is t o
receiv e t he st at em ent perm ission.
--PermissionToCreateATable
--Set the database context before invoking.
GRANT CREATE TABLE TO vbdotnet1

Aft er execut ing t he pr eceding GRANT st at em ent , t he vbdot net 1 user can cr eat e a
t able, such as one nam ed Em ailCont act s. Because vbdot net 1 ow ns
vbdot net 1.Em ailCont act s, it can aut om at ically insert and delet e r ows fr om t he
t able— j ust like m em bers of t he sysadm in fix ed serv er r ole and t he db_ow ner
fix ed dat abase r ole. Howev er , ow ning an obj ect doesn’t aut om at ically conv ey
m em bership in any r ole. Since t he vbdot net 1 login isn’t a m em ber of t he
sysadm in fixed dat abase role, t he vbdot net 1 user cannot be a dbo user. The
follow ing scr ipt shows t he code for cr eat ing t he vbdot net 1.Em ailCont act s t able.
Running t he script from t he session connect ion based on t he vbdot net 1 login
m akes t he vbdot net 1 user t he t able’s owner .
--Invoke the DROP TABLE statement if the EmailContacts
--table already exists for the vbdotnet1 user.
CREATE TABLE EmailContacts
(
ContactID int Not Null PRIMARY KEY,
FirstName nvarchar(20) NULL,
LastName nvarchar(35) NULL,
Email1 nvarchar (255) NULL
)
List ing t he t ables from t he sysadm in session now shows t w o t ables w it h t he nam e
Em ailCont act s. Use t he follow ing scr ipt t o display t he list of t ables wit h
Em ailCont act s as t heir nam e locat ed in t he Chapt er07 dat abase. Figure 7- 3 shows
t he r esult set from t he script . One r ow in t he result set is for t he dbo user , and
t he ot her is for t he vbdot net 1 user .
--List the EmailContacts tables after creating
--a second one with the vbdotnet1 user.
USE Chapter07
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = ’EmailContacts’


      Figu r e 7 - 3 . Th e Tab le _ Sch e m a colu m n in t h e r e su lt se t from t h e
   I N FORM ATI ON _ SCH EM A.TABLES vie w d en ot e s a t a ble ow n e r ’s u ser
                                            n am e .




                                    N ot e
You cannot dr op a user and it s corr esponding login if t he
user owns an obj ect , such as a t able, in a dat abase. I f t he
obj ect s for a user are no longer required, sim ply drop t hem
and t hen drop t he user and it s login. I f you requir e t he
obj ect s t hat are owned by a user who m ust be dropped,
inv oke t he sp_changeobj ect owner sy st em st ored procedure
t o t r ansfer obj ect ownership t o a user who will rem ain in t he
dat abase. Then dr op t he user and login.
You can add r ows t o and delet e rows fr om t he vbdot net 1.Em ailCont act s t able wit h
a script such as t he follow ing. Because t he script references t he t able wit h it s
owner qualifier, you can r un t he script fr om any connect ion based on a login wit h
a user hav ing perm ission t o select , insert , and delet e r ows from t he t able— for
exam ple, t he dbo user or t he vbdot net 1 user . The script generat es a r esult set
wit h t hr ee r ecordset s. The first recordset is em pt y because t he preceding script
creat ing t he t able doesn’t insert any rows. The second r ecordset shows t he new
row for Tony Hill. The t hird r ow shows t he t able em pt y again aft er t he delet ion of
t he r ow for Tony Hill.
--Run from Chapter07 database context.
SELECT * FROM vbdotnet1.EmailContacts
INSERT INTO vbdotnet1.EmailContacts
       VALUES(3,’Tony’, ’Hill’, ’thill@cabinc.net’)
SELECT * FROM vbdotnet1.EmailContacts

DELETE
FROM vbdotnet1.EmailContacts
WHERE Email1 = ’thill@cabinc.net’
SELECT * FROM vbdotnet1.EmailContacts



W indow s Use r s a nd Gr ou ps
Windows users t hat ar e part of Windows group account s in SQL Serv er creat e
special challenges for set t ing secur it y . This is because an indiv idual Windows user
account can deriv e it s perm ission for a t ask fr om m ult iple sources. Ev en if you
revok e a perm ission fr om t he user account for a Windows user, t he Windows user
m ay st ill be able t o perform t he t ask cont r olled by t he perm ission. This can
happen because t he user account for a Windows group, t o which a Windows user
belongs, grant s t he sam e perm ission r evoked for t he indiv idual Window s user
account . I n fact , t his sam e scenar io applies t o SQL Ser ver user- defined roles. A
SQL Ser ver account can belong t o m ult iple roles and hav e perm issions applied
dir ect ly t o it . Revoking one perm ission m ay not fully close all t he r out es by which
a SQL Serv er user account can der iv e perm ission t o per form t he t ask.

                                     N ot e
When work ing wit h a Windows user account t hat can belong
t o a Windows group or a SQL Ser ver user account t hat can
belong t o one or m or e user- defined roles, consider using a
DENY st at em ent t o rem ov e a per m ission. This st at em ent
block s t he per m ission t o per for m a t ask even if t he account
is grant ed perm ission for t he t ask by virt ue of it s
m em bership in anot her Windows gr oup or SQL Ser ver role.
The sp_helpr ot ect syst em st ored pr ocedur e helps you m onit or t he per m ission
assignm ent s for user account s. By default , sp_helpr ot ect r et ur ns a result set wit h
t he obj ect and st at em ent perm issions for all t he user account s in all dat abases on
a dat abase ser ver. You can filt er t he r esult set by specify ing select ed argum ent s.
For exam ple, designat ing a dat abase in t he @nam e argum ent ret ur ns t he
perm issions for j ust t hat dat abase. You can also filt er by t ype of perm ission
( obj ect or st at em ent ) , by account t o whom a perm ission is grant ed, and by w ho
grant ed t he perm ission. I f you assign filt ers so t hat t he r esult set from
sp_helpr ot ect is em pt y, t he pr ocedur e r et ur ns an error m essage for t he condit ion.
The follow ing scr ipt t racks t he assignm ent of perm issions in t he Chapt er07
dat abase. Before t he ex ecut ion of any GRANT st at em ent in t he script , a dat abase
connect ion t o t he Chapt er07 dat abase t hat is based on t he login for
CCS1\ w invbdot net 1 cannot perform a SELECT st at em ent on t he
dbo.Em ailCont act s t able. Aft er t he first set of GRANT st at em ent s, t he
CCS1\ w invbdot net 1 user account can perform a SELECT st at em ent based on t wo
dist inct perm issions. One perm ission is grant ed dir ect ly t o t he user in t he second
GRANT st at em ent . The ot her perm ission is grant ed t o t he user account t hr ough
t he CCS1\ w invbdot net Windows gr oup because CCS1\ w invbdot net 1 is a m em ber
of t his Windows gr oup. The inv ocat ion of t he sp_helprot ect sy st em st or ed
procedur e aft er t he first t hr ee GRANT st at em ent s confirm s t hese t wo perm issions
and one m or e for t he CCS1\ w invbdot net 2 Windows user account .
The next T- SQL st at em ent in t he script r evokes t he SELECT perm ission for t he
dbo.Em ailCont act s t able for t he CCS1\ w invbdot net 1 Windows user . This rem ov es
t he perm ission from t he collect ion of perm issions in t he dat abase. The execut ion
of sp_helpr ot ect in t he next st at em ent confirm s t hat t he perm ission is m issing.
Howev er, rem ov ing t he perm ission doesn’t block t he CCS1\ winvbdot net 1
Windows user fr om perform ing a SELECT st at em ent w it h t he dbo. Em ailCont act s
t able as it s source. This is because t he CCS1\ w invbdot net 1 Windows user der ives
SELECT perm ission for t he t able fr om it s m em bership in t he CCS1\ w inv bdot net
Windows gr oup.
Revok ing SELECT perm ission for t he CCS1\ w inv bdot net Windows group account
in t he dat abase w ill block t he CCS1\ winvbdot net 1 Windows user fr om perform ing
a SELECT st at em ent on t he Em ailCont act s t able. How ev er, t his act ion w ill also
rem ov e SELECT perm ission for t he CCS1\ winvbdot net 2 Windows user. The script
inst ead invokes a DENY st at em ent for SELECT perm ission on t he
dbo.Em ailCont act s t able for t he CCS1\ w invbdot net 1 user account . This st at em ent
rest r ict s j ust t he abilit y of t he CCS1\ w invbdot net 1 Windows user t o perform a
SELECT st at em ent w it h Em ailCont act s as t he source. Any ot her user in t he
CCS1\ w invbdot net Windows gr oup st ill r et ains perm ission for a SELECT st at em ent
against t he dbo. Em ailCont act s t able. The final execut ion of sp_helprot ect rev eals
an explicit perm ission deny ing t he CCS1\ w invbdot net 1 user account fr om
perform ing a SELECT st at em ent on t he dbo.Em ailCont act s t able.
--DenyPermission
--Before granting SELECT permissions, SELECT statements from
--either CCS1\winvbdotnet1 or CCS1\winvbdotnet2 were denied.

--Grant SELECT permission for dbo.EmailContacts for
--a Windows group and its two individual Windows accounts.
GRANT SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet]
GRANT SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet1]
GRANT SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet2]

EXEC sp_helprotect @name=‘dbo.EmailContacts’

--After granting SELECT permission, SELECT statements from
--either CCS1\winvbdotnet1 or CCS1\winvbdotnet2 were granted.

--Revoke SELECT permission for dbo.EmailContacts
--for CCS1\winvbdotnet1.
REVOKE SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet1]

EXEC sp_helprotect @name=‘dbo.EmailContacts’

--After revoking SELECT permission for CCS1\winvbdotnet1, the
--account could still perform a SELECT statement for EmailContacts.

--Deny SELECT permission for dbo.EmailContacts
--for CCS1\winvbdotnet1.
DENY SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet1]

EXEC sp_helprotect @name=‘dbo.EmailContacts’

--Denying SELECT permission makes it impossible
--for CCS1\winvbdotnet1 to SELECT from EmailContacts.

--Clean up permission assignments.
REVOKE SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet]
REVOKE SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet1]
REVOKE SELECT ON dbo.EmailContacts TO [CCS1\winvbdotnet2]
Cha pt e r 8 . Ove r vie w of t he .N ET
Fr a m e w or k
This book is aim ed at pr ofessional developers w ho have an int er est in
program m ing SQL Serv er 2000 w it h Visual Basic .NET. Up t o t his point , t he
book ’s focus was pr im ar ily on SQL Ser ver. I believ e t hat y ou cannot opt im ally
program SQL Ser ver in any language w it hout a firm underst anding of it s basic
wor k ings. Chapt ers 2 t hrough 7 provide a foundat ion in SQL Serv er t hat will serv e
you especially well for dat a access and m anipulat ion t asks, as w ell as r elat ed dat a
definit ion t asks.
Chapt er 1 int roduces you t o beginning Visual Basic .NET and ADO.NET t echniques
so t hat y ou hav e som e cont ext for underst anding how t o apply t he SQL Serv er
2000 t opics present ed in Chapt ers 2 t hr ough 7. This chapt er builds on t he init ial
exposur e t o t echnologies for t he . NET Fr am ew ork t hat appears in Chapt er 1. I f
you j um ped t o t his chapt er wit hout any pr ior ex posur e t o t he .NET Fram ework ,
now is a gr eat t im e t o look over Chapt er 1. To t ake m axim um adv ant age of Visual
Basic .NET for cr eat ing SQL Ser ver solut ions, y ou need t his backgr ound. Chapt er
1 st art s t o conv ey t his background, and t his chapt er finishes t he t ask so you are
ready t o dig int o t he .NET Fram ework code sam ples t hr oughout t he rest of t he
book .
Visual Basic .NET is one of t he core pr ogram m ing languages for t he . NET
Fram ew ork, which Microsoft defines as “a new com put ing plat form designed t o
sim plify applicat ion dev elopm ent in t he highly dist ribut ed envir onm ent of t he
I nt er net .” Micr osoft is t aking a whole new init iat iv e w it h t he .NET Fram ework t hat
radically redefines how businesses can program and deploy solut ions as well as
access resources ov er corporat e int ranet s or t he I nt ernet . I n m any present at ions
on t he bet a v ersions, it was popular t o hear t hat Micr osoft w as bet t ing it s
business on t he .NET Fr am ew ork . Whet her or not t his is pr ecisely t r ue, it is clear
t hat Microsoft has inv est ed heav ily in pr ov iding a com pr ehensiv e new st ruct ur e
for building solut ions, and t he firm has changed in a m aj or way it s m ost popular
program m ing language— Visual Basic. The scope and m agnit ude of t he changes
prov ide Visual Basic dat abase dev elopers wit h challenges and opport unit ies.
This chapt er at t em pt s t o fam iliarize y ou w it h t he archit ect ure of t he .NET
Fram ew ork and relat ed t echnologies, including ASP.NET and XML Web serv ices.
See Chapt er 1 for int roduct ory m at er ial on Visual Basic .NET and ADO.NET. My
goal in t his chapt er isn’t t o em pow er y ou as a program m er wit h t hese
t echnologies. I nst ead, I aim t o show how t he t echnologies com plem ent one
anot her. I n t he process, I feel you will dev elop an appreciat ion of w hy it is
im port ant for y ou t o adopt t he .NET Fram ework and st art program m ing it wit h
Visual Basic .NET. This book ’s r em aining chapt ers exam ine t he program m ing y ou
use for t he t opics int roduced concept ually in t his chapt er and Chapt er 1. This
chapt er cont ains a pr ogram m ing sam ple, but I put it t here j ust for reference
purposes. This chapt er is about concept s— not code. ADO.NET, ASP.NET, and XML
Web serv ices each are cov er ed in a separat e chapt er t hat drills down int o
t echniques for dev eloping solut ions wit h t hem . Plus, t here’s anot her chapt er—
Chapt er 12— on m anaging XML w it h Visual Basic .NET.




An I n t rodu ct ion t o t h e .N ET Fr a m e w or k
This sect ion int roduces you t o cor e .NET Fram ewor k concept s. I t st art s wit h an
ov erv iew of t he .NET Fr am ew ork archit ect ure. Next it m ov es on t o w hat ’s new
about source code com pilat ion. This is a nat ural ent ry point t o discussing how y ou
m anage t he r efer encing of solut ions by client s and how t o deploy solut ions. The
sect ion closes w it h brief looks at select ed .NET Fram ew ork feat ures t hat build on
m at er ial cov ered earlier in t he sect ion and ar e im port ant t o how you will use .NET
Fram ew ork solut ions.

.N ET Fr a m e w or k Ar chit e ct u r e

Perhaps t he m ost dom inant archit ect ural elem ent of t he .NET Fram ew ork is it s
com m on language runt im e. The r unt im e sit s on t op of t he operat ing sy st em .
Program m ers w r it e t o t he r unt im e in any com pliant language. The runt im e
ev ent ually wr it es w hat is called m anaged code t o t he specific operat ing sy st em on
which it r uns. As I wr it e t his chapt er, t he operat ing syst em s t hat support t he
com m on language runt im e include t hose based on t he 32- bit v ersions of
Windows, including Windows 98, Windows Millennium , Windows NT, Windows
2000, and Windows XP. Micr osoft has a Window s .NET Serv er oper at ing syst em in
bet a t hat likely w ill include t he .NET Fram ework . I n addit ion, y ou can ex pect t he
runt im e t o pr oduce code suit able for t he fort hcom ing 64- bit version of Windows.
While t he com m on language r unt im e r uns on t op of Windows syst em s, one of t he
great st r engt hs of runt im e- com pliant solut ions is t heir int er operabilit y wit h ot her
operat ing syst em s. This follows fr om r unt im e support for XML and XML Web
serv ices. The core t echnologies for XML and XML Web serv ices r ely on
indust ry wide st andards. Because ot her vendors are endorsing t hese st andards
along w it h Microsoft , y ou can be assured of a level of int er operabilit y for t he
solut ions t hat y ou cr eat e w it h t he r unt im e. I f v endors follow t hr ough on t heir
endorsem ent s for t he st andards and y ou build y our solut ions w it h code m anaged
by t he runt im e, y ou can achiev e lev els of int er operabilit y acr oss operat ing
syst em s not pr ev iously enj oy ed by applicat ion dev elopers.

                                      N ot e
Learn m or e about XML in Chapt er 6 and Chapt er 12. XML
Web services is t he t opic of t he closing sect ion in t his chapt er
as well as t he whole of Ch a pt e r 1 3 .
When y ou develop solut ions for SQL Serv er, y ou will benefit fr om t he fact t hat t he
com m on language runt im e can be host ed by SQL Ser ver 7 and lat er v ersions and
Micr osoft I nt er net I nfor m at ion Serv ices v ersions 4.0 and lat er ; I I S is t he
Micr osoft Web serv er for Windows NT and Windows 2000. This giv es you a chance
t o int egrat e t ight ly y our dat abase and Web solut ions w it h t he m anaged code
generat ed by t he runt im e. For exam ple, t he .NET Fram ewor k ships w it h m anaged
prov iders for SQL Ser ver and OLE DB dat a sour ces. The SQL Serv er provider
offers subst ant ial per for m ance advant ages because of it s opt im izat ion for SQL
Ser ver 7 and SQL Serv er 2000. I n addit ion, ASP.NET is a part of t he .NET
Fram ew ork t hat I I S host s. ASP.NET is t he next generat ion of dev elopm ent
t echniques for t hose creat ing solut ions w it h ASP now. I n order for ASP.NET pages
t o r un, t hey m ust be com piled by t he r unt im e. ASP.NET is an int egr al part of I I S
4, j ust as I I S 3 host s t he ASP obj ect m odel. I n addit ion, ASP.NET can int eract
wit h SQL Ser ver t hr ough t he .NET Fram ew ork dat a prov iders. ( See Chapt er 11.)
Figur e 8- 1 shows a sim plified schem at ic of t he pat h from source code in Visual
Basic .NET ( or anot her r unt im e- com pliant language) t hrough t o int eract ions w it h
SQL Ser ver and browser s on a Web. The com m on language r unt im e t r anslat es
t he source code t o m anaged code. This m anaged code can, in t urn, int eract wit h
t he Windows operat ing syst em , SQL Serv er , and browsers. Wit h t he aid of a
m anaged pr ov ider, such as t he one for SQL Serv er, y our solut ions can access and
m anipulat e dat a. You can use t he ASP.NET com ponent of t he .NET Fram ework t o
creat e ASP.NET pages t hat r eside on an I I S ser ver. These pages can serv e
dynam ic elem ent s t o br owsers on a Web. I n addit ion, t he pages can offer t he
browsers t he opport unit y t o access and m anipulat e dat a on a SQL Ser v er .

   Figu re 8 - 1 . A sch e m a t ic illu st r a t ing t h e role of t h e com m on lan gu a ge
ru n t im e an d it s m an ag e d cod e in in t e ra ct ing w it h t h e W ind ow s op er a t in g
                             syst e m , SQL Se r ve r , a n d I I S.




Com pilin g Sou r ce Code

The .NET Fram ew ork support s m ult iple program m ing languages in a com m on
way . I n addit ion t o Visual Basic .NET, Visual St udio .NET support s t he preparat ion
of source code in ot her languages, such as C# and Visual C+ + . Web developers
who are used t o building solut ions in JScr ipt w ill appreciat e t he fact t hat t hey can
creat e ASP.NET solut ions wit h JScript .NET. I n fact , t hese dev elopers can use
JScr ipt .NET t o im plem ent solut ions across t he full range of .NET Fram ewor k
capabilit ies because JScript .NET is runt im e- com pliant . I n addit ion, t hird- part y
vendors ar e readying ot her languages for r unt im e com pliance. This pr oliferat ion
of languages w ill offer dev elopers a wide range of opt ions in which t hey can
program t he .NET Fram ework .

                                      N ot e
JScript .NET is an ext ension of t he Microsoft JScr ipt
language, which was based on ECMAScript ( ECMA- 262) .
ECMA is t he European Com put er Manufact urers Associat ion.
JScript .NET is ex plicit ly developed for use w it h t he runt im e.
Since JScr ipt .NET generally follows t he ECMAScript
convent ions, it offers a st andards- based rout e t o creat ing
.NET Fram ework solut ions w it h a popular script ing language
am ong Web developer s.
A w onderful t hing about t he .NET Fram ew or k is t hat all languages can have t he
sam e capabilit ies if t hey ar e fully r unt im e- com pliant . For exam ple, Visual Basic
.NET has t he sam e capabilit ies as C# ( and so does JScr ipt .NET) . I n addit ion,
dev elopers in one language can fr eely use obj ect s creat ed by dev eloper s in ot her
languages. This cross- language funct ionalit y wasn’t alway s easy t o im plem ent
befor e t he .NET Fram ework because of slight incom pat ibilit ies in source code
language com pilat ion pr ocessing. The .NET Fram ework act ually readies source
code for execut ion t hrough a series of t w o com pilat ions. The first com pilat ion
conv ert s t he source code t o Microsoft I nt erm ediat e Language ( MSI L) . The second
com pilat ion conv ert s MSI L t o CPU- specific code for t he com put er r unning t he
code.
The first com pilat ion from source code t o MSI L generat es a represent at ion of y our
program t hat capt ur es it s program m ing inst ruct ions and m et adat a about t he
program . The com pilat ion st or es it s out put in a port able ex ecut ion ( PE) file. MSI L
is a language- independent way of expressing y our program m ing logic. The
m et adat a describes t he t ypes t hat your code cr eat es as well as t heir m em bers,
such as m et hods, propert ies, and ev ent s. A t ype is an elem ent , such as a class.
Anot her im port ant m et adat a elem ent is t he descript ion of t he assem bly for an
applicat ion. An assem bly is t he unit for st or ing a solut ion in t he .NET Fram ework .
The assem bly descript ion in t he m et adat a includes an ident it y specificat ion for t he
assem bly, export ed t y pes, r efer enced t ypes, and secur it y per m issions needed t o
run. A r eference t o a t y pe is like a reference t o a class in a t ype library . Because
t he m et adat a for an assem bly includes int ernal t ypes and ext er nally r efer enced
t ypes, t here is no need for r efer ences t o t ype librar ies in Visual Basic .NET and
ot her runt im e- com pliant languages.
The second com pilat ion from MSI L t o m achine code readies y our code for
ex ecut ion on a specific processor. The .NET Fram ework can accom plish t his wit h a
Just - I n- Tim e ( JI T) com piler. JI T com pilers ar e specific t o each support ed CPU
archit ect ure. JI T com pilat ion com piles t he cont ent s of t he PE file as a user
references it s elem ent s dur ing a session. PE file elem ent s, such as a t y pe
m em ber, ar en’t com piled unt il a user r efer ences t hem . Aft er t he init ial
com pilat ion, t he runt im e aut om at ically r efers t o t he com piled v ersion, t hus
reducing t he t im e t o ex ecut e t he code. This pr ocess also saves com pilat ion t im e
by not com piling t hose elem ent s t hat a user doesn’t refer ence dur ing a session.
Unless an adm inist rat or explicit ly designat es ot herw ise, t he com pilat ion t o
m achine code exam ines t he MSI L and it s m et adat a t o det erm ine w het her it is
t ype safe. The t erm t ype safe r efers t o t he fact t hat a t ype accesses only m em ory
locat ions for which it has access perm ission. This securit y check allows t he .NET
Fram ew ork t o enforce secur it y r est r ict ions.

Asse m blie s a nd M a n ife st s

Assem blies and t heir m anifest s are an excit ing innovat ion int roduced w it h t he
.NET Fr am ew ork. They are excit ing because t hey can clear ly elim inat e m any
opport unit ies for .dll conflict s— popular ly referr ed t o as “dll hell.” A .dll conflict can
em erge w hen a user inst alls a new applicat ion t hat wr it es over an ex ist ing .dll file
wit h a new version t hat isn’t fully backward com pat ible. I f anot her, prev iously
inst alled, applicat ion relies on a t ype m em ber t hat is changed or elim inat ed in t he
new .dll, t he pr ev iously inst alled applicat ion w ill fail. Assem blies and m anifest s
offer a couple of workarounds t o t his pr oblem for solut ions based on COM
com ponent s.
A .NET Fram ework solut ion ex ist s as an assem bly of one or m ore files. These files
can include t he MSI L as well as ot her r esources, such as im age files or ot her
docum ent files t hat a solut ion references. An assem bly m ust include a m anifest ,
which cont ains m et adat a about t he assem bly. This m et adat a describes t he files in
t he assem bly . I n t he case of a single- file assem bly, t he m anifest r esides wit hin
t he solut ion’s .dll file, but ot herwise an assem bly ’s m anifest r esides in a separat e
file. A solut ion’s assem bly can consist of up t o four t ypes of elem ent s.

    •   The assem bly’s m anifest
    •   The MSI L code for t he solut ion
    •   The t ype m et adat a for t he MSI L code
    •   Resource files r equir ed by t he solut ion
The assem bly is t he deploym ent unit for solut ions in t he .NET Fram ew ork.
Because all t he elem ent s for a solut ion can ex ist wit hin a single assem bly , y ou
can deploy a solut ion by dist ribut ing t he solut ion’s assem bly of files. St or e t he
assem bly as a dir ect ory or subdir ect or y on a t arget workst at ion. The com m on
language r unt im e m ust be inst alled on t he work st at ion in order t o t ransfor m t he
MSI L t o nat ive m achine code. This appr oach is part icular ly convenient w her e a
solut ion perform s t asks t hat y ou don’t care t o share wit h ot her solut ions.
Som e solut ions are ut ilit ies. When t hese ut ilit y solut ions are likely t o be a part of
m any ot her solut ions, y ou can st ore t he ut ilit y solut ions in t he Global Assem bly
Cache ( GAC) . There is one GAC per com put er. When y ou place an assem bly in
t he GAC for shar ing by one or m ore ot her solut ions, t he shared assem bly in t he
GAC m ust hav e a st rong nam e. The st r ong nam e uniquely ident ifies an assem bly
in t he GAC t o avoid conflict s from t wo assem blies t hat m ay hav e t he sam e t ext
for a nam e. Visual St udio .NET includes t ools t o sim plify t he cr eat ion of st rong
nam es t hat are based on t he t ext for an assem bly’s nam e, it s v ersion num ber,
cult ur e inform at ion, public key , and a digit al signat ure.
The .NET Fram ew ork SDK discourages locat ing assem blies in t he GAC unless
essent ial because it can com plicat e deploym ent and adm inist rat ion. For exam ple,
deploy ing a solut ion can r equire copy ing t wo dir ect or ies— one for t he m ain
assem bly and t he ot her for t he shar ed assem bly in t he GAC. I n addit ion, t he GAC
resides in t he syst em direct ory. This direct ory oft en has r est rict ed access. These
access rest r ict ions m ay necessit at e perm issions for copy ing an assem bly t o t he
GAC t hat t he user inst alling an applicat ion doesn’t hav e.

  D e ploy a Solut ion—X COPY a Folde r
You can creat e .NET Fram ew ork solut ions for Windows t hat
are t ot ally self- cont ained in a single folder . When y ou cr eat e
a .NET Fr am ework solut ion using t he Windows Applicat ion
t em plat e, Visual St udio .NET by default cr eat es a folder for
your solut ion in t he last direct or y in w hich you sav ed a
previous solut ion. This folder has a root folder and at least
t wo subfolders— bin and obj . You can st or e t he resour ces for
your solut ions, such as cust om classes, im age files, and XML
schem a files, anywhere y ou need in t he r oot folder ( or even
out side t he root ) . The advant age of st oring all files for a
solut ion in t he r oot folder , or any of it s subfolders, is t hat
you can t hen deploy y our solut ion wit h an XCOPY com m and,
or any equiv alent t echnique, t hat copies t he solut ion’s folder.
All t he Visual Basic .NET solut ions included in t his book ’s
sam ple files ar e av ailable as folders t hat you can copy t o
your com put er. I f y ou copy t hem t o a m achine wit h t he
proper configurat ion— for ex am ple, one wit h t he com m on
language runt im e— y ou can run t he solut ions from t he folder
t o w hich y ou copy t hem .
While I am t alk ing about solut ion folders, it is probably wort h
m ent ioning a couple of special files w it hin a solut ion folder .
The solut ion’s .exe file resides in t he bin subfolder . You can
launch t he solut ion by inv oking t his file. By default , t he .exe
file has t he sam e nam e as t he solut ion. Therefor e, if your
solut ion has t he nam e WindowsApplicat ion1, t he .exe file for
st ar t ing t he solut ion has t he nam e Window sApplicat ion1.exe.
To open t he solut ion for edit ing in Visual St udio .NET, y ou
can open a file wit h t he solut ion’s nam e and t he ex t ension
.sln, such as WindowsApplicat ion1.sln. This file resides in t he
root folder for t he solut ion.

                                    N ot e
Whet her you deploy an assem bly in a dir ect ory or in t he
GAC, t here is no need t o add set t ings t o t he syst em r egist ry
in or der t o be able to use t he solut ion based on t he
assem bly. Just reference t he solut ion assem bly in t he client
applicat ion.

Se le ct e d .N ET Fr a m e w or k Fe a t u r e s

Ev en from t he short int r oduct ion t o t he .NET Fram ework t o t his point , it should be
clear t hat t he .NET Fram ework is m assive in scope. This sect ion present s a few of
t he feat ures t hat I find m ost wort hy of br ief m ent ion and discussion. I n order t o
m anage t he book’s lengt h, I leav e out m any t hat also ar e wort hy of y our
considerat ion.
The runt im e garbage collect or can aut om at ically m anage t he r elease of m em or y
for an applicat ion, and it can cut back on t he incidence of m em ory leak s for long-
running applicat ions. This is because t he garbage collect or can aut om at ically
recover m em ory for r efer ence t ypes— t hings such as classes and ar rays— t hat
consum e m em ory when t here are no longer point ers t o t hem in m em ory.
The runt im e garbage collect or recovers unused m em ory based on sever al r ules,
one of which has t o do wit h no m ore space available for recent ly creat ed
reference t ypes. The good news is t hat you no longer hav e t o worr y about
clearing m em or y for inact ive refer ence t ypes. The bad news is t hat you cannot
t ell pr ecisely when t he garbage collect or w ill r ecover m em ory. I n addit ion, t he
collect or doesn’t w ork for unm anaged r esources, such as r efer ences t o files. I n
t his case, you can invok e t he Dispose m et hod, but y ou should also disable t he
garbage collect or , checking for any obj ect s explicit ly disposed of. You can inv ok e
t he Syst em .GC.Suppr essFinalize m et hod for t he obj ect disposed of t o accom plish
t his t ask. Anot her appr oach is t o use t he Close m et hod, which calls t he Dispose
m et hod. You can also use t he Close m et hod t o prom pt ly r em ove select ed
m anaged obj ect s, such as SQL Ser ver dat abase connect ion obj ect s. Alt hough t he
garbage collect or w ill ev ent ually r em ove such m anaged it em s as SQL Serv er
connect ion obj ect s, you can im pr ove t he responsiveness of y our applicat ions by
elim inat ing t hem when you k now t hey are no longer needed.
Nam espaces ar e a m eans of organizing and refer r ing t o groups of elem ent s in t he
runt im e. I n addit ion, y our own cust om applicat ions hav e nam espaces— by default ,
t hese nam espaces bear t he solut ion’s nam e. The .NET Fram ew ork SDK list s t he
nam es of all t he runt im e nam espaces. As a dat abase dev eloper, y ou ar e lik ely t o
hav e special int er est in t he Syst em .Dat a, Syst em .Dat a.SqlClient ,
Syst em .Dat a.SqlTypes, and Syst em .Dat a.OleDb nam espaces. Table 8- 1 includes
brief sum m aries of each of t hese nam espaces. Not ice t hat t he nam es of t he
nam espaces follow a hierarchical nam ing convent ion. The Syst em .Dat a
nam espace repr esent s t he br oadest gr ouping of elem ent s in Table 8- 1. The
Syt em .Dat a.SqlClient , Syst em .Dat a.SqlTypes, and Syst em .Dat a.OleDb
nam espaces denot e subset s of t he broader Syst em .Dat a nam espace.
            7DEOH  6HOHFWHG 5XQWLPH 1DPHVSDFHV IRU 'DWDEDVH 'HYHORSHUV
          1DPH                                            6XPPDU\
Syst em .Dat a             Represent s m ost ly elem ent s in t he ADO.NET archit ect ure.
Syst em .Dat a.SqlClient Represent s elem ent s in t he SQL Serv er .NET dat a
                         prov ider .
Syst em .Dat a.SqlTypes Represent s elem ent s for SQL Serv er nat iv e dat a t ypes.
Syst em .Dat a.OleDb         Represent s elem ent s in t he OLE DB .NET dat a prov ider .
The nam espaces parallel t he k ind of funct ionalit y t hat Visual Basic developers
used t o enable by adding refer ences t o t ype libr aries. You can now accom plish
t he sam e t hing by using t he I m port s st at em ent for a nam espace, w here t he
elem ent s in a nam espace are analogous t o t he classes and m em bers of a t ype
library . Look in Chapt er 10 for code sam ples illust rat ing t he use of t he
Syst em .Dat a.SqlClient nam espace. As indicat ed in a not e in t he “ Assem blies and
Manifest s” sect ion, t he way t o r efer ence a serv er solut ion assem bly in a client
solut ion is t o refer ence t he serv er solut ion assem bly fr om t he client assem bly. An
I m port s st at em ent in t he client solut ion assem bly perm it s you t o r efer ence t he
nam espace for t he serv er solut ion assem bly. Chapt er 9 dem onst rat es t he synt ax
for t his st at em ent . You will find num erous code sam ples im plem ent ing t he
I m port s st at em ent t hroughout t he r est of t his book .
By now , y ou should underst and t hat t he .NET Fr am ew ork is t he way of t he fut ur e
for t hose dev eloping solut ions w it h Microsoft pr oduct s. Nevert heless, it is likely
t hat y ou eit her hav e built or ar e using solut ions based on t he pr ev ious Micr osoft
dev elopm ent fram ewor k — COM. Ther efor e, Microsoft int r oduced t echnology t o
help ease you t hrough t he t ransit ion per iod. For exam ple, Visual St udio .NET
offers graphical t echniques for im port ing COM obj ect s wit hin .NET Fram ework
solut ions. Visual St udio .NET also offers graphical t ools for export ing .NET
Fram ew ork solut ions so t hey can int er operat e w it h y our prev iously creat ed COM
solut ions. Because t her e are fundam ent al incom pat ibilit ies bet w een COM and t he
.NET Fr am ew ork, t hese t ools don’t alw ays work perfect ly. See t he
“Tr oubleshoot ing I nt eroperabilit y” t opic in t he Visual St udio .NET Help files for an
enum erat ion of som e issues t hat you m ay encount er along w it h suggest ed
rem edies.




An Ove r vie w of ASP.N ET
ASP.NET is a specialized com ponent of t he .NET Fram ework . You can use
ASP.NET t o cr eat e Web applicat ions t hat ar e accessible fr om browsers t hat can
connect t o t he page. The sam e basic t echniques ( plus som e m or e) apply t o t he
creat ion of XML Web ser vices solut ions. This chapt er aim s t o or ient you t o .NET
Fram ew ork Web t echnologies.

H ow D oe s ASP.N ET Re la t e t o ASP?

ASP.NET is sim ilar but not ident ical t o ASP ( Act ive Ser ver Pages) . Many
professional Visual Basic developers found ASP a serv iceable way t o creat e Web
solut ions. One im port ant reason for t his is t hat ASP can cr eat e form s on Web
pages t hat any br owser can r ead. Nevert heless, ASP has dr awbacks. For
exam ple, ASP m ix es HTML page design code and program m ing logic in t he sam e
file. This leads t o a t ype of spaghet t i coding t hat is difficult t o r ead and int erpr et .
I n addit ion, you can cr eat e y our program m ing logic in any of a v ar iet y of
languages, but pur e Visual Basic isn’t one of t hem . The closest y ou can get is
VBScr ipt . Furt herm ore, t he Visual Basic developm ent env ironm ent isn’t suit able
for creat ing ASP Web pages. Som e Visual Basic dev elopers adopt ed Visual
I nt erDev, and t hese dev elopers could use t he Visual I nt erDev developm ent
env ir onm ent . However, t he Visual I nt erDev dev elopm ent env ironm ent had a
different look and feel t han t he one for Visual Basic. As a consequence, m any
dev elopers used Not epad or anot her favor it e t ext edit or t o cr eat e ASP Web pages
from scrat ch.

                                   N ot e
What do y ou need t o creat e solut ions w it h ASP.NET? Fir st ,
you need any Windows operat ing syst em t hat inst alls I I S
aut om at ically or allows you t o inst all it opt ionally. This is
because I I S is t he Web serv er for ASP.NET solut ions, and it
cont ains t he ASP.NET obj ect m odel, j ust as it does t he ASP
obj ect m odel. Second, you need t he .NET Fr am ework. I f y ou
inst alled Visual St udio .NET on your m achine, your com put er
alr eady has it . Visual St udio .NET provides a friendly, fam iliar
dev elopm ent environm ent for creat ing ASP.NET solut ions.
Thir d, you need MDAC version 2.6 or lat er for dat a access
and m anipulat ion. Visual St udio .NET inst alls MDAC version
2.7, w hich is m ore t han sufficient . However , you can
download t he lat est MDAC version, free of charge, fr om t he
Microsoft sit e at
ht t p: / / www.m icrosoft .com / dat a/ download.ht m .
I believe ASP.NET w ill becom e im m ensely popular w it h Visual Basic dev elopers
because it solv es t he t hree problem s described in t he pr eceding paragr aph.

   •   ASP.NET separat es page design and pr ogram logic int o t w o separat e but
       relat ed files. This ends t he need t o m ingle HTML layout code and pr ogr am
       logic code in t he sam e file.
   •   You can cr eat e ASP.NET Web solut ions w it h Visual Basic. No longer do you
       hav e t o develop in anot her language t hat is alm ost lik e Visual Basic—
       nam ely, VBScr ipt . I n addit ion, t he solut ions you dev elop w it h Visual Basic
       .NET can int eract wit h solut ions cr eat ed by Web dev elopers cr eat ing
       solut ions in JScr ipt .NET because bot h languages are runt im e- com pliant .
   •   The Visual St udio .NET dev elopm ent env ironm ent has t he sam e look and
       feel w hen you work w it h Web Form s as it does when y ou work w it h
       Windows Form s. For ex am ple, y ou hav e a Toolbox. You can drag and drop
       cont r ols on a Web page j ust as you do w it h a Windows form . I n addit ion,
       t he Toolbox insulat es y ou from t he HTML sy nt ax under ly ing t he cont rols
       you use on Web Form s.


                                           N ot e
       Visual Basic dev elopers m igrat ing t o ASP.NET from ASP m ay
       not ice t hat a couple of fam iliar t ools are gone. First , y ou no
       longer code solut ions in VBScr ipt — as indicat ed above, y ou
       can creat e bot h Window s and Web solut ions wit h Visual Basic
       .NET. Second, Visual I nt erDev is gone t oo. Now y ou can use
       t he sam e Visual St udio .NET developm ent env ironm ent for
       Windows and Web solut ions. I f y ou are a Visual Basic
        dev eloper who has been wait ing unt il t he t im e w as right t o
        do Web dev elopm ent , com e on in— developing for t he Web
        will feel fam iliar and be j ust as m uch fun t o const r uct as
        Windows applicat ions. I f you ar e a Visual Basic dev eloper
        who is experienced at Web developm ent , t her e’s no bet t er
        t im e t han r ight now t o drast ically speed up y our Web
        dev elopm ent cy cles by t aking advant age of ASP.NET.
Ther e is anot her cr it ical difference bet w een ASP.NET and ASP t hat m er it s your
at t ent ion. ASP.NET is com piled, and ASP code is int erpret ed. Com piled code r uns
fast er, so y ou ar e lik ely t o enj oy perform ance benefit s w hen you ar e r unning t he
com piled code. Of course, t he first t im e ASP.NET uses a m odule, t here is a delay
associat ed wit h t he com pilat ion of t he code. As a dev eloper , y ou w ill lik ely
encount er t his com pilat ion delay m uch m or e t han y our users sim ply because your
j ob is t o fine- t une t he code for opt im al perform ance. Each fine- t uning adj ust m ent
requir es a new com pilat ion.
I n spit e of all t he differences bet ween ASP and ASP.NET, t here ar e m any
sim ilar it ies. You can r un ASP and ASP.NET pages side by side on t he sam e Web
serv er. Your ASP Web pages hav e an .asp ext ension. Your ASP.NET pages will
t ypically hav e an .aspx ext ension. This side- by - side capabilit y allows y ou t o
gradually int roduce new funct ionalit y wit h ASP. NET int o a prev iously ex ist ing
solut ion init ially creat ed wit h ASP.
Select ed obj ect s, such as Applicat ion and Session, ex ist in bot h ASP and ASP.NET.
Applicat ion obj ect s serv e as global var iables across an applicat ion. When y ou
need t o m ak e sur e t hat som e values are available t o all users of an applicat ion,
Applicat ion obj ect s repr esent an opt ion. ASP.NET also offers t he ASP.NET cache
as a m eans of shar ing dat a across all t he users of an applicat ion. As in t he past ,
Session st at e var iables allow t he shar ing of inform at ion bet ween HTTP ( Hypert ext
Transport Prot ocol) request s of a browser w it hin a session. ASP.NET im prov es on
t he Session var iables av ailable in ASP by allow ing you t o share Session var iables
across a Web farm w it h m ult iple com put ers designed t o offer t he sam e Web
applicat ion. I f an applicat ion sav es a Session v ariable in response t o an HTTP
request t o one com put er in a Web farm , a second request from t he sam e user t o
a differ ent com put er in t he Web farm can st ill gain access t o t hat sam e Session
variable.

Cr e a t in g a n ASP.N ET W e b Applica t ion

You can cr eat e a new ASP.NET solut ion by click ing t he New Proj ect link on t he
Visual St udio St art Page and choosing t he ASP.NET Web Applicat ion t em plat e.
When y ou do t his, Visual St udio suggest s a default locat ion for t he solut ion’s
assem bly on t he local I I S serv er , such as ht t p: / / localhost / WebApplicat ion1. You
can choose any ot her solut ion nam e on any ot her I I S t o w hich y ou can connect .
( You need t he .NET Fram ework inst alled on any com put er from which you plan t o
run ASP.NET pages.) Clicking OK opens t wo folders— one on t he Web serv er and
anot her in t he default locat ion w here Visual St udio st or es it s solut ion assem bly
folders. I f t he applicat ion has t he nam e WebApplicat ion1, launching a new
ASP.NET Web applicat ion cr eat es a new folder nam ed WebApplicat ion1 wit hin t he
wwwr oot direct ory of t he inet pub dir ect or y.

                                    N ot e
To rem ove an ASP.NET solut ion from your com put er and
elim inat e it from appearing in t he Visual St udio St ar t Page,
you m ust delet e bot h of it s folder s.
When Visual St udio .NET opens your applicat ion, you see a blank page. Solut ion
Explor er shows t hat t he page’s t it le is WebForm 1.aspx. You can assign a m ore
m eaningful nam e for t he page’s t it le pr opert y fr om t he Propert ies window. The
page init ially opens w it h a pageLayout propert y set t ing of GridLayout . This set t ing
let s you align cont rols on t he Web page according t o t he gr id m ar ks. You can
change t he pageLay out propert y in t he Propert ies window. The ot her possible
pageLay out propert y set t ing is FlowLay out . I n t his m ode, Visual St udio arranges
your cont rols from t op t o bot t om in classic Web page lay out m ode— lik e a word
processor. Not ice t hat t he Solut ion Explorer and Propert ies windows serv e t he
sam e k inds of funct ions for t his Web applicat ion as t hey do for ot her, non- Web,
applicat ions.
Choosing t he HTML t ab at t he bot t om of t he page exposes t he em pt y Web page in
HTML v iew. Bet w een t he body t ags on t he Web page, not ice t he form t ags. The
for m t ag has a r unat set t ing of serv er. ASP.NET pages ar e designed t o accept
for m s and cont rols t hat run on t he serv er.

Addin g Con t r ols t o a n .a spx Pa ge

Sw it ch back t o Design v iew by clicking t he Design t ab at t he bot t om of t he page.
Choose Toolbox from t he View m enu. I f t he Toolbox isn’t open t o t he Web Form s
sect ion, click t hat sect ion heading. This act ion perm it s y ou t o add Web serv er
cont r ols t o y our .aspx Web page. Web ser ver cont r ols ar e highly abst ract ed for
program m ing in your Visual St udio dev elopm ent env ir onm ent . They insulat e you
from HTML convent ions and prov ide r icher funct ionalit y t han is available t hr ough
st andard HTML form cont r ols, such as < input > elem ent s. I n addit ion, t he Web
serv er cont rols offer a wider ar ray of cont rol opt ions t han is available wit h HTML
for m cont r ols. For exam ple, t he Web server cont rols include a Calendar cont r ol
and a configurable RadioBut t onList cont r ol. I n spit e of t he abst ract ing, Web
serv er cont rols r ender HTML t o a browser .

                                    N ot e
I n som e cases, Web server cont rols r equir e client - side
scr ipt ing t o per form proper ly. For t his r eason or per form ance
reasons, you m ay care t o swit ch t o anot her t ype of Web
cont rol for select ed applicat ions.
You can add a cont r ol t o a Web form by double- click ing t he cont r ol in t he
Toolbox . Then y ou can drag t he cont r ol t o w her e y ou want it on t he for m . Add a
but t on cont rol and a label cont r ol from t he Toolbox t o t he Web form ,
WebForm 1.aspx.

Addin g Code Be hin d a n .a spx W e b Pa ge

Now you’r e ready t o work w it h t he code behind t he Web form and it s cont r ols. On
t he form , double- click t he but t on cont rol. This opens t he Code Edit or for t he file
t hat cont ains t he form code. The filenam e is WebForm 1.aspx.vb, w hich appears
on a t ab at t he t op of t he Code Edit or. You should be able t o see
WebForm 1.aspx.vb in Solut ion Explor er. I f not , click t he Show All Files icon on t he
Solut ion Explorer t oolbar and t hen click t he + next t o WebForm 1.aspx . ( Recall
t hat Windows displays t he nam e of a t oolbar icon w hen you hold t he m ouse
point er ov er it .)
Ent er t he code in Figur e 8- 2 in t he Code Edit or for WebFor m 1.aspx.vb. When t he
page opens init ially, t here is no code in eit her t he Page_Load or But t on1_Click
ev ent procedure. The Page_Load event procedur e init ializes t he page by assigning
a capt ion t o t he but t on and insert ing an em pt y st ring for t he label cont r ol. The
But t on1_Click ev ent pr ocedur e assigns t he t ext Hello Wor ld t o t he label when t he
user clicks t he but t on. This page w orks in very old br owsers. For exam ple, I used
I nt er net Explor er 4 t o v iew t he WebForm 1.aspx page, and it w ork ed per fect ly .
The com put er running t he br owser didn’t hav e t he .NET Fram ew ork inst alled
eit her .

  Figu re 8 - 2 . A pa ir of eve n t p roced u r e s for a n ASP.N ET W e b ap plica t ion
                 w it h a ve r sion of t h e classic H ello W orld sa m ple.




XM L W eb Se r vices
XML Web serv ices facilit at e com put er- t o- com put er int eract ion in t he sam e
general way as ASP.NET facilit at es com put er- t o- hum an int eract ion t hrough an
.aspx Web page. This sect ion t r ies t o acquaint y ou wit h w hy XML Web serv ices
are a part of t he .NET Fram ework. The cont ent in t his sect ion pr ov ides an
ov erv iew of t he t echnologies used t o im plem ent XML Web serv ices. See Ch ap t er
1 3 for m ore cov erage of XML Web serv ices, w it h specific at t ent ion t o how y ou
creat e, t est , and deploy XML Web ser vices as well as how client s use an XML Web
serv ice.

W ha t Ca n XM L W e b Se r vice s D o f or M e ?

As a professional dev eloper, y ou should be v ery int erest ed in XML Web serv ices.
This is because XML Web serv ices can expand t he r each of your ex ist ing
solut ions. The m or e folk s your applicat ions serv e, t he m or e t hose applicat ions ar e
wort h ( and t he m ore m oney you can m ak e fr om t hem ) .
I n t he preceding sect ion on ASP.NET, you gained som e exposur e on how t o
creat e classic Web solut ions w it h t he .NET Fram ework , or m ore specifically
ASP.NET. I n ASP.NET, y ou creat e a Web- based solut ion for an indiv idual t o r ead
and int eract wit h t hr ough a browser . Whet her users access your Web page for
solv ing a problem ov er an int ranet or an ext ranet , t he end result is t hat it
appears in a browser. A user, which is anot her nam e for a person, has t o do
som et hing wit h it . XML Web serv ices pr ov ide an env ir onm ent for creat ing
solut ions t hat m achines— not people— consum e. Howev er, bot h classic Web pages
and solut ions creat ed w it h XML Web serv ices work ov er t he Web. To be m ore
specific, XML Web ser v ices let m achines int eract wit h each ot her and shar e
inform at ion across t he Web. The beaut y of t he underly ing XML Web ser vices
archit ect ure is t hat t he m achines can be using different operat ing syst em s
( Windows vs. Unix, for exam ple) , and t he pr ogram m ing language used t o cr eat e
a solut ion on one m achine can be different fr om t he program m ing language in
which a client solut ion accept s result s from a serv er ( Java vs. Visual Basic .NET) .
So again, how are XML Web serv ices going t o help y ou? XML Web serv ices
prom ise t o deliver univ ersal access t o y our soft ware solut ions no m at t er w hat t he
operat ing syst em or pr ogram m ing language on client and ser ver m achines. I n
addit ion, t his isn’t j ust a Microsoft init iat ive. I t is an open init iat ive w it h sponsors
from leading soft w ar e firm s. For exam ple, one of t he t echnologies under ly ing XML
Web serv ices is UDDI ( Univ ersal Descript ion, Discovery, and I nt egrat ion) . I ’ll
describe t his t echnology in a m om ent , but I m ent ion it her e because it s
dev elopers include I BM, I nt el, SAP, Ar iba, and Micr osoft . I n addit ion, t he
t echnology rest s on indust ry st andards, such as t hose published by t he W3C
( Wor ld Wide Web Consort ium ) . By building new solut ions t hat t ak e advant age of
XML Web serv ices or ret rofit t ing XML Web serv ices t o ex ist ing solut ions, you are
posit ioning y our effort s t o support t he leading inform at ion t echnology firm s and
t he m ost w idely accept ed com put ing indust ry st andards.

Ov e r vie w of t h e XM L W e b Se r vice s I n fr a st r u ct ur e

XML Web serv ices perm it client and server m achines t o int eract w it h each ot her
as if t hey wer e t wo m achines on t he sam e LAN wit h all com pat ible syst em s—
except t hat t he m achines can be connect ed ov er a Web w it h incom pat ible
syst em s. The client m achine can r equest t he server m achine t o perform a
t ransact ion, such as m ove m oney from one account t o anot her. I n t his scenar io,
t he client passes t he param et ers for t he t ransact ion. I n ret urn, t he serv er can
perform t he t ransact ion and r et urn an out com e t o t he client workst at ion.
Alt er nat ively, a client can request som e inform at ion fr om a serv er, such as a
docum ent . The server can ret r iev e t he docum ent from it s archiv es and r et urn it t o
t he client ov er popular t ransport pr ot ocols as a self- describing, t ext - based
m essage ( t hink XML docum ent s described by XSD schem as) . XML Web serv ices
support a couple of popular pr ot ocols— nam ely HTTP ( bot h PUT and GET m et hods)
as well as SOAP ( Sim ple Obj ect Access Prot ocol) , w hich is a W3C st andard. I f I
were a differ ent k ind of aut hor and t his w er e a different k ind of book, I would say
XML Web serv ices dev elopers can use SOAP t o clean up t heir applicat ions.
A couple of ot her r eally cool feat ur es about XML Web ser vices deser ve m ent ion.
One of t hese is t hat t he t echnology helps y ou find XML Web serv ices; UDDI
im plem ent s t his feat ure. The ot her bit of t echnology is a language t hat enables an
XML Web serv ice r unning on a serv er t o describe it self so t hat a client m achine
can det erm ine how t o int eract w it h it . This language has t he nam e Web Ser v ices
Descript ion Language ( WSDL) .

A Close r Look a t t h e Un de r ly in g Te ch n ologie s

The preceding ov erv iew confirm s t hat XML Web serv ices r ely on t hree m ain
t echnologies.

    •   UDDI can prov ide a way of discov ering w hat ’s available as a Web serv ice.
    •   WSDL is an XML- based gram m ar for describing XML Web serv ices.
    •   SOAP is anot her XML- based st andard, but t his st andard t arget s t he
        exchange of inform at ion bet ween t w o loosely coupled com put ers.

UDD I
UDDI offers a direct ory serv ice capabilit y . The UDDI online dir ect ory ser vice
allows firm s t o publish cont act inform at ion for t heir organizat ion, sum m ar ies of
XML Web serv ices offer ed, and st andards w it h which client s m ust com ply t o
access t heir XML Web ser vices. You can discover m ore about t he UDDI
im plem ent at ion from it s organizat ion sit e at ht t p: / / www.uddi.org. Those w ho
want t o m ak e t heir XML Web ser vices available for use can r egist er w it h a UDDI
dir ect or y serv ice. Those searching for an XML Web serv ice can go t o t he UDDI
sit e t o discover XML Web serv ices t hat m eet t heir search cr it er ia. The UDDI
ret ur ns URLs for learning m or e about XML Web serv ices. A searcher can use t he
URLs t o discover t he locat ion of one or m or e docum ent s in WSDL describing each
XML Web serv ice.

                                     N ot e
At t he t im e t hat I w rit e t his chapt er , y ou can regist er y our
business and it s XML Web services at
ht t p: / / www.uddi.or g/ r egist er.ht m l.

W SD L

A WSDL docum ent describes t he t hings t hat an XML Web serv ice does. Such a
docum ent also declar es wher e and how t o get t he XML Web serv ice t o m ake
t hose t hings happen. A WSDL docum ent is expr essed in XML. The W3C for m al
specificat ion is available at ht t p: / / www.w3c. org/ t r / wsdl. This docum ent describes
and dem onst rat es t he obj ect ives of WSDL as w ell as specify ing t he XML synt ax ,
elem ent s, and at t r ibut es for a WSDL docum ent . A WSDL docum ent describes an
XML Web serv ice in t er m s of six elem ent s, as shown in Table 8- 2.
                                  7DEOH  :6'/ (OHPHQWV

(OHPHQW                                        'HVFULSWLRQ
t ypes     Encloses dat a t ype definit ions used in m essages exchanged bet ween t he
           XML Web serv ice and it s client s.
m essage Specifies an abst ract definit ion of t he m essage exchanged bet w een t he
         XML Web serv ice and it s client s.
port Type Refers t o an abst ract set of operat ions— each operat ion has an
          associat ed input m essage and one or m ore out put m essages.
binding    Designat es a concr et e prot ocol and dat a form at specificat ion for
           operat ions and t heir m essages relat ing t o a specific port Type. The
           binding can be t o HTTP, SMTP ( Sim ple Mail Transport Prot ocol) , or som e
           ot her com m unicat ion prot ocol or m edium .
port       Designat es a single com m unicat ion endpoint , nam ely, t he com binat ion
           of a binding and an address, for an operat ion.
serv ice   Refers t o a collect ion of relat ed port s.

SOAP

SOAP ( v ersion 1.1) is t he t hird m ain t echnology underpinning XML Web serv ices.
Go t o ht t p: / / w ww.w3c.org/ t r / soap for t he st andard’s specificat ion. The SOAP
st andard is an XML- based m echanism for exchanging m essages bet w een t wo
com put ers. SOAP is a one- way m essaging form at for rem ot e procedure calls, but
you can adapt it for a request / r esponse m essage par adigm as well as a
request / m ult iresponse paradigm .
The SOAP specificat ion has t hree part s, but only t he first is m andat ory. This part
designat es w hat ’s in a m essage, w ho t he m essage is for, and w het her t he
m essage is opt ional or m andat ory. The SOAP specificat ion r efers t o t his first part
as t he SOAP Env elope elem ent .
The second and t hird part s aren’t m andat or y. I n it s second part , t he SOAP
specificat ion designat es a ser ializat ion schem e for exchanging applicat ion- specific
dat a t ypes t hat ar e out side t he scope of nat ive XML dat a t ypes. The t hird part of
t he specificat ion denot es t echniques for r epresent ing r em ot e procedure calls and
t heir responses. The client for an XML Web ser vice is lik ely t o call som e m et hod
for t he XML Web ser vice. This m et hod can opt ionally require a r esponse.
Visual St udio .NET perm it s you t o cr eat e XML Web serv ices and client s wit hout
wor k ing int im at ely w it h t he UDDI , WSDL, and SOAP st andards. Nev ert heless,
hav ing a basic grasp of t he issues t hat accom pany t hese underly ing st andards w ill
equip you t o underst and bet t er how XML Web serv ices work and how t o cr eat e
t hem .
Cha pt e r 9 . Cr e a t ing W indow s
Applica t ion s
Windows applicat ions in t he .NET Fram ew or k ar e applicat ions based on one or
m or e Windows Form s. These applicat ions t arget com put ers t hat can run code
behind a form and prov ide a r ich env ir onm ent t o t he user. Each form in a
Windows applicat ion is an inst ance of t he Windows Form class. This class behaves
sim ilar ly t o t he form s in prior v ersions of Visual Basic ( and ot her Microsoft
dev elopm ent env ironm ent s such as Microsoft Access form s) , but t he Windows
Form class in t he .NET Fram ework is dist inct and independent of form s in ear lier
Micr osoft dev elopm ent env ir onm ent s. I t is conv enient t o t hink of t he Form class
as a die or a m old from which you der ive specific inst ances of a form . Like ot her
classes, t he For m class is a collect ion of propert ies, m et hods, and ev ent s. The
for m s in y our Windows applicat ions inher it t he Form class propert ies, m et hods,
and ev ent s.
This chapt er cov ers creat ing solut ions wit h Windows applicat ions and m anaging
t he Windows Form s in t hose applicat ions w it h Visual Basic .NET code. The focus
of t he chapt er is on int erm ediat e t o advanced t opics, such as cr eat ing and using
classes, inherit ance, ev ent pr ogram m ing, and handling run- t im e er ror s wit h
st ruct ur ed except ion handling. For each t opic cov er ed, I ident ify what ’s new for
t he t opic w it h Visual Basic .NET. I n som e cases, such as inherit ance and
st ruct ur ed except ion handling, t he em phasis is wholly on what ’s new because
Visual Basic .NET int r oduces t hese capabilit ies t o Visual Basic program m ers.




Ge t t in g St a r t e d w it h W in dow s For m s
Windows Form s ex ist wit hin Windows applicat ions. You can cr eat e t he shell for a
Windows applicat ion from a t em plat e w it hin Visual St udio .NET. Windows
applicat ions ar e for env ironm ent s t hat find it efficient t o t ake advant age of t he
local processing power of client w or kst at ions. When developing solut ions based
on t he Windows Applicat ions t em plat e, you w ill oft en use Windows For m s t o
m anage int eract ion w it h users and display infor m at ion t o users. This sect ion
int r oduces y ou t o t he basics of creat ing and m anaging solut ions based on
Windows Form s.

St a r t w it h For m 1 in a W in dow s Applica t ion

You can cr eat e a Windows applicat ion fr om t he Visual St udio .NET St art Page. I f
you follow ed t he inst r uct ions in Chapt er 1 for configuring Visual St udio .NET and
t he St art Page, you can open t he St art Page by click ing t he Windows St art
but t on, choosing Program s, select ing t he Micr osoft Visual St udio .NET folder, and
t hen select ing Micr osoft Visual St udio. Begin a new Windows applicat ion by
click ing New Proj ect on t he St art Page and select ing t he Windows Applicat ion
t em plat e in t he New Pr oj ect dialog box . Next ent er a pr oj ect nam e, such as
St art Wit hForm 1. Visual St udio assigns a default folder for your pr oj ect ’s assem bly
of files, but y ou can ov err ide t he default locat ion for a solut ion’s assem bly folder
by eit her t yping t he pat h t o t he alt er nat e folder or br owsing t o it . Figur e 9- 1
illust rat es t he New Pr oj ect dialog box set t o creat e a new Windows applicat ion
nam ed St art Wit hForm 1 in t he VisualSt udioPr oj ect s folder of t he C: \ Docum ent s
and Set t ings\ Adm inist rat or\ My Docum ent s pat h.
       Figu re 9 - 1 . St ar t a W in dow s a pplica t ion by se le ct in g W ind ow s
                    App licat ion in t h e N e w Proj e ct dia log box .




Click OK in t he New Pr oj ect dialog box t o creat e a new proj ect for a Windows
applicat ion. Visual St udio opens t he Windows Form s Designer env ironm ent . The
Windows Form s Designer w indow, Form 1.vb[ Design] , enables y ou t o graphically
m anipulat e t he form for an applicat ion. For ex am ple, y ou can use t he Toolbox t o
add cont r ols t o a form , and y ou can add code behind t he ov erall form as well as
t he cont rols on a form in t he Windows Form s Designer. The ov erall Visual St udio
.NET dev elopm ent env ir onm ent should show t hr ee w indows at t his point . I n
addit ion t o t he Windows Form s Designer, y ou should see t o t he r ight Solut ion
Explor er and t he Proper t ies w indow. Solut ion Explorer pr ov ides a t r ee view, m uch
lik e Windows Explor er, of t he it em s in t he proj ect for a solut ion. The Pr opert ies
window pr ov ides an int erface for m anually v iewing and updat ing t he set t ings for
select ed it em s in Solut ion Explorer or t he it em s on a form .
Figur e 9- 2 shows a blank form — Form 1—in t he Windows For m s Designer . Solut ion
Explor er displays t he Form 1.vb file. This file cont ains your graphical design
changes as well as any code behind t he form . The Assem bly .vb file in t he Visual
St udio .NET dev elopm ent envir onm ent enables you t o v iew assem bly at t ribut es,
such as version num bers for a solut ion. I expanded t he Refer ences folder in
Solut ion Explorer so you can see select ed refer ences available t o Form 1, including
t he Syst em .Windows.Form s nam espace. The Pr opert ies w indow below Solut ion
Explor er shows t hat t he Text pr opert y set t ing for t he form is Form 1. You can t ype
ov er t he Text propert y set t ing t o assign a m or e m eaningful capt ion t o y our form .

 Figu re 9 - 2 . Th e in it ia l layou t for a W in d ow s a pp lica t ion in clu de s a bla n k
               for m a n d a few re fe re n ce s t o se lect e d n a m esp ace s.
M a n a gin g W in dow s For m s

You can m anage Windows Form s in at least t hr ee st andard ways. First ,
m anipulat e t he pr opert ies of t he form . Second, add cont r ols t o a form t hat
facilit at es com m on t ask s, such as user input . Third, add code behind a for m .
The for m in Figure 9- 2 inher it s it s init ial pr opert ies, m et hods, and ev ent s from t he
Form class in t he Syst em .Windows.Form s nam espace. Use a form ’s Tex t pr opert y
t o set it s capt ion, for ex am ple, from Form 1 t o My First Form . You can posit ion a
for m w it h t he Deskt opLocat ion and Locat ion pr opert ies. Form class m et hods let
you m anipulat e for m inst ances. Use t he ShowDialog m et hod t o open a m odal
for m inst ance. When y ou open a form wit h t his m et hod, you m ust close t he form
( w it h t he Close m et hod) befor e you can nav igat e t o anot her open form . By
opening a form wit h t he Show m et hod, you enable users t o nav igat e t o anot her
for m w it hout closing t he m odeless form opened wit h t he Show m et hod.
                                   N ot e
A nam espace can serv e as a reference t o a t ype library in
Visual Basic 6. I t is t he reference t o Syst em .Windows.For m s
t hat prov ides t he proper t ies, m et hods, and event s for a
Windows form , such as t he one in Figur e 9- 2.
To m ake a form part of a Windows applicat ion, you can add cont rols t o t he form .
I n addit ion, you can w r it e code for t he form and t he cont rols on it . Choose
Toolbox fr om t he View Menu in Visual St udio .NET t o open a w indow wit h m ult iple
sect ions, or t abs, from which you can drag cont rols and ot her obj ect classes ont o
your form s. I n t he Windows Form s sect ion of t he Toolbox, y ou can select from
several differ ent t ypes of cont rols.

   •   A w ide var iet y of fam iliar cont r ols facilit at e t he input and out put of
       inform at ion and user int eract iv it y. These fam iliar cont r ols include but t on,
       t ext box, com bo box, slider or t rackbar, label, t ab, radio but t on, check
       box, t w o differ ent list box cont r ols, and dat a grid.
   •   Anot her set of it em s in t he Windows Form s sect ion of t he Toolbox includes
       cont r ols t hat aren’t t ypical, but t hey st ill help y ou m anage t he way a form
       displays inform at ion and operat es. For exam ple, use t he Toolt ip class t o
       prov ide help t o a user about t he purpose of cont rols on a form when a
       m ouse hov ers ov er a cont r ol. Ot her special Toolbox it em s facilit at e t he
       creat ion and m anagem ent of m enus, t he highlight ing of cont rols w it h
       invalid dat a, and t he pr ov ision of Help.
   •   A final set of elem ent s in t he Windows Form s sect ion of t he Toolbox
       includes a num ber of com m on dialog box es. Applicat ion dev elopers can
       use t hese Toolbox elem ent s t o give t heir cust om applicat ions t he look and
       feel of a st andard Windows applicat ion. There are sev en of t hese cont rol
       it em s: OpenFileDialog, Sav eFileDialog, Font Dialog, ColorDialog,
       Print Dialog, Print Pr ev iewDialog, and PageSet upDialog.

The Toolbox m ak es ot her set s of select ions available fr om it s Com ponent s and
Dat a sect ions. You can use t he Com ponent s sect ion of t he Toolbox t o insert built -
in com ponent s t hat ship wit h t he .NET Fram ew ork. You can also add t o t his
Toolbox sect ion com ponent s t hat y ou acquir e fr om t hird- part y sources or dev elop
int ernally. I will dem onst rat e t he use of one of t hese com ponent s, t he syst em
t im er, lat er in t his chapt er . The Toolbox’s Dat a sect ion offers com ponent s t hat
facilit at e ADO.NET t asks, such as m ak ing a connect ion wit h a dat a source,
passing a SQL com m and t o a dat a source, and ret ur ning a result set fr om a dat a
source. The it em s in t he Dat a sect ion of t he Toolbox are cov er ed in Chapt er 11.
You can init ialize select ed form propert ies and respond t o user act ions wit h form
cont r ols t hr ough event procedur es. For exam ple, in a Load event procedur e for a
for m , y ou can set t he form ’s Deskt opLocat ion pr opert y. Wit h t he Click event
procedur e for a but t on, you can run Visual Basic .NET code t o perfor m com m on
act ions, such as opening a m essage box. Double- click a form ’s capt ion or a
cont r ol on a form t o open t he Code Edit or window and display t he shell, or st ub,
for an event procedure. The ev ent is t he default one for t he form or cont rol.
When y ou double- click a form , Visual St udio .NET opens t he shell for t he Load
ev ent procedure. You can place any code your applicat ion r equires in t he shell.
The next t im e t he form opens, it runs t hat code. Double- clicking a but t on creat es
t he shell for t he but t on’s Click ev ent .
As w it h t he St art Page and t he Windows Form Designer, Visual St udio . NET opens
t he Code Edit or on a t ab, which in t he case of Form 1 is labeled Form 1.v b. I n m ost
way s, t he Code Edit or is lik e a st andard code window. You can ent er code int o
ev ent procedure shells. You can also add sub pr ocedur es and funct ion procedur es
t o t he code behind a for m . You can use t he Proj ect m enu t o add ot her it em s t o a
Windows applicat ion, such as m or e form s or new cust om classes. Use t he dr op-
down list s at t he t op of t he Code Edit or t o select a class, such as a but t on, and
t hen see all t he event s for t he class. Select ing an ev ent fr om t he list on t he r ight
opens an event procedure shell for t hat event . Visual Basic .NET uses t he fam iliar
nam ing convent ion of a class nam e followed by an underscore and t he ev ent
nam e for event procedure shells. Ther efor e, t he Click event procedure for But t on1
has t he nam e But t on1_Click.

A W in dow s For m w it h Tw o But t on Con t r ols

Dev elopers oft en place but t ons on for m s t o let users int eract wit h an applicat ion.
This sect ion pr esent s a Windows applicat ion w it h t w o but t ons— one for saying
hello and a second for m ov ing t he form around on t he deskt op. When t he
applicat ion opens, t he Form 1_Load ev ent pr ocedur e posit ions Form 1 on t he
deskt op and set s a capt ion for t he form . Form 1 is t he default st art up obj ect for a
Windows applicat ion. The sam ple for t his sect ion com plet es t he St art Wit hForm 1
applicat ion init ially launched in t he com m ent ar y for Figur es 9- 1 and 9- 2.
Figur e 9- 3 shows t hree ev ent procedures for t he St art Wit hForm 1 applicat ion. The
ev ent procedures appear in t he Code Edit or , on t he Form 1.vb t ab. Recall t hat y ou
don’t hav e t o wr it e t he shell— j ust t he cont ent s— of an event procedur e. I did
insert a line cont inuat ion charact er ( _) in t he shell so y ou could see all t he code
generat ed aut om at ically . Not ice a rect angle around Windows Form s Designer
generat ed code. You can expand t he sect ion by click ing t he “+ ” next t o it ; click
t he “- ” next t o t he t op line of t he expanded code t o hide t he sect ion. This region
cont ains code necessary for a form . For exam ple, t he code inst ant iat es an
inst ance of t he Form class. The sect ion also persist s, or saves, your m anual
changes t o t he form and cont r ol propert y set t ings. Visual St udio m anages t he
code in t his sect ion. Don’t m ake y our changes t o t he form from t his sect ion.
I nst ead, use t he Propert ies window for a select ed class, such as t he for m or any
of it s cont rols, or use code in event procedures t o assign propert y set t ings at r un
t im e.

                                    N ot e
The Windows For m s Designer gener at ed code region can be
a conv enient way for lear ning t he synt ax and nam ing
convent ions for m anipulat ing form and cont r ol pr opert ies.
Make changes graphically in t he Windows Form s Designer
and t he Proper t ies window. Then expand t he Windows Form s
Designer gener at ed code region t o view how Visual St udio
cr eat es t he set t ing pr ogr am m at ically.
The Form 1_Load ev ent procedur e uses t wo lines t o set t he init ial locat ion of
Form 1 on t he deskt op. These lines set t he form ’s t op left edge in 450 pix els fr om
t he deskt op’s left border and down 450 pix els from t he deskt op’s t op border . The
synt ax relies on t he Deskt opLocat ion propert y for For m 1 ( r efer r ed t o by it s Me
keyw ord) and t he Point st ruct ur e. The For m 1_Load event procedure assigns t he
st ring Capt ion for Hello World t o t he for m .

                                    N ot e
The Point st ruct ur e represent s values for a pair of xy-
coordinat es in a t wo- dim ensional plane. A st r uct ur e is like a
dat a pr im it ive in t hat it cont ains v alues and you can assign
var iables t o t hose values ( for exam ple, My St art Point in
Figure 9- 3) .

 Figu r e 9 - 3 . Th r e e e ve n t p roce du re s for m a n a ging t h e in it ia l displa y of a
  form a n d h ow a n applica t ion r esp on ds t o click s for e a ch bu t t on on t h e
                                               form .




The Click event procedure for But t on1 displays a m essage box. The MsgBox
st at em ent in t he event procedur e t akes t hr ee param et ers. The first assigns a
st ring for t he m essage box t o display , nam ely, Hello World. The second
param et er specifies t he t ypes of but t ons t hat w ill be display ed in t he m essage
box. The st at em ent designat es a single OK but t on. The closing param et er
indicat es a capt ion for t he m essage box. As wit h Visual Basic 6, t he I nt elliSense
feat ur e in Visual Basic .NET helps y ou specify t he MsgBox st at em ent . For
exam ple, as y ou t y pe t he MsgBox st at em ent y ou can choose fr om an ar ray of
but t on specificat ions for t he m essage box .
The But t on2_Click ev ent procedure r eposit ions t he form on t he scr een from it s
init ial point of ( 450, 450) t o a new point of ( 150, 450) . The ev ent pr ocedur e
m ov es t he form 300 pix els t o t he left . You w ill find t his capabilit y useful when y ou
need t o act iv ely m anage w her e for m s appear on y our deskt op. The event
procedur e’s sy nt ax uses a Point st r uct ur e t o specify t he new locat ion for t he form .
Howev er, t his ev ent pr ocedur e specifies t he posit ion for t he form w it h t he
Locat ion pr opert y inst ead of t he Deskt opLocat ion propert y used in t he
Form 1_Load ev ent procedure. I f a user docks t he Windows t askbar ( w it h t he
St art but t on) on t he t op, Deskt opLocat ion w ill y ield super ior per form ance, but t he
t wo propert ies ot herw ise let y ou set a posit ion anyw here on t he deskt op. I f t he
t askbar is at t he screen’s t op or left border, posit ioning a form w it h a Locat ion
propert y set t ing of ( 0, 0) can obscure part of t he form . How ev er, t he
Deskt opLocat ion pr oper t y set t ing assigns posit ion relat ive t o t he t askbar.
Ther efor e, a Deskt opLocat ion pr opert y set t ing of ( 0, 0) posit ions a for m flush w it h
t he t askbar.
Aft er populat ing a form wit h cont r ols and code behind t he form , y ou w ill want t o
t est your applicat ion. Ther e are a couple of way s t o do t his. First , y ou can choose
St art from t he Debug m enu. This will com pile y our applicat ion and launch it s st art
obj ect . I n t his case, t hat obj ect is Form 1. I f t he code com piles wit hout er ror, your
applicat ion launches. You can t hen st art t o t est it . Second, you can choose t o
com pile y our applicat ion wit hout at t em pt ing t o r un it im m ediat ely. You can
com pile a program int o Micr osoft I nt erm ediat e Language ( MSI L) by choosing
Build Solut ion fr om t he Build m enu. I n t his case, t hat process ret ur ns a file
nam ed St art Wit hForm 1.ex e in t he bin folder of t he solut ion’s assem bly folder. The
assem bly folder has t he nam e St art Wit hForm 1. You can r un t he solut ion’s .ex e
file by double- click ing it in Windows Ex plorer or by t yping t he file’s nam e and
pat h in t he Run dialog box and t hen clicking OK. The Run dialog box is available
by choosing Run from t he Windows St art m enu.
Deploying a solut ion can be as sim ple as copy ing t he St art Wit hForm 1. ex e t o
anot her com put er r unning t he .NET Fram ew ork . You don’t need Visual St udio
.NET inst alled on t he ot her com put er. The .NET Fram ework is av ailable as a
separat e dow nload for com put ers w it hout Visual St udio .NET. See
m sdn.m icr osoft .com / net fram ework / prodinfo/ get dot net .asp for inform at ion on
how t o download t he fram ework from MSDN or order it on CD.

Ope n in g On e W in dow s For m w it h An ot h e r

A form can open anot her form as a m odal form or a m odeless form . A m odal form
doesn’t allow t he user t o act ivat e anot her form unt il t he m odal form is closed. A
m essage box is an exam ple of a m odal form . Users hav e t o respond t o t he
m essage box before t hey can proceed t o any ot her form . A m odeless form does
allow users t o act ivat e anot her form befor e t hey close t he m odeless form . A
t oolbar is an exam ple of a m odeless form . The Find dialog box t hat you can open
by choosing Find And Replace and t hen Find from t he Edit m enu in Visual St udio
is an exam ple of a m odeless form . You can search for a st r ing, sw it ch t he focus
away from t he Find dialog box, and t hen t ransfer t he focus back t o t he Find
dialog box t o search for anot her incidence of a st ring.
A form doesn’t hav e a m odal or m odeless propert y . I nst ead, you can open a form
wit h m et hods t hat expose it as eit her a m odal or a m odeless form . I nv oke t he
ShowDialog m et hod for a form t o open it as a m odal form . To open a for m as a
m odeless form , inv oke it s Show m et hod.
Figur e 9- 4 shows a pair of form s wit h t he capt ions Form 1 and Form 2. These
for m s belong t o a Windows applicat ion nam ed CallOneForm From Anot her. When a
user clicks t he but t on on Form 1, t he but t on’s Click ev ent procedure inv ok es a
procedur e nam ed OpenForm 2. This procedure can open Form 2 as eit her a m odal
or a m odeless form . For m 1 also has a label cont rol. This label cont r ol accent uat es
t he form ’s nam e beyond t he inform at ion in t he form capt ion. Form 2 cont ains
t hr ee cont rols: a label, a t ext box, and a but t on. The label in Form 2 ser ves t he
sam e purpose as t he one in Form 1. The t ext box in Form 2 is for display ing
whet her t he form is open as a m odal or a m odeless form . The applicat ion assigns
t he Text pr opert y of Tex t Box1 at r un t im e. But t on1 closes Form 2 in r esponse t o a
click.
            Figu r e 9 - 4 . A de sign view of a p a ir of form s u se d in t h e
                           Ca llOn e For m From An ot h e r sa m ple.




Som e of t he form cont r ols for t he Windows applicat ion have st at ic propert y
set t ings t hat don’t change at run t im e. When y ou have cont rols lik e t his, you can
assign t he propert y set t ings at design t im e. For exam ple, you can change t he
Text pr opert y of Label1 in eit her form in t he Propert ies w indow.
When a form or it s cont rols have dy nam ic pr opert y set t ings t hat can change at
run t im e in response t o user act ions, your applicat ion’s code m ak es t he propert y
set t ings. The follow ing list ing cont ains t w o ev ent procedures and a sub procedur e.
These procedur es, which m ak e up t he cust om code behind Form 1, m ak e dy nam ic
propert y set t ings and handle int eract ion w it h t he user.
The Form 1_Load ev ent procedur e m akes t hr ee dy nam ic pr opert y set t ings. First it
posit ions t he form t ow ard t he upper left cor ner of t he deskt op w it h a set t ing t hat
is 100 pix els dow n and 100 pix els t o t he left from t he upper left corner . Next t he
procedur e widens t he widt h of But t on1 from it s default set t ing of 75 pix els t o a
new set t ing of 85 pix els. This ext ra w idt h perm it s t he display of t he full Text
propert y set t ing for But t on1, w hich t he pr ocedur e’s last line assigns.
The But t on1_Click ev ent procedure cont ains a single line of code t hat invok es t he
OpenForm 2 procedure. This st andard sub pr ocedur e present s as m any as t wo
m essage box es. The first m essage box asks whet her t o open Form 2 as a m odal
for m . I f t he user clicks t he Yes but t on, t he procedur e execut es a block of code t o
achiev e t hat purpose. Not ice t he use of t he ShowDialog m et hod t o open t he form
in t his code block. Ot herw ise, t he second m essage box appears w it h a prom pt t o
open Form 2 as a m odeless form . I f t he user clicks t he OK but t on, t he applicat ion
opens Form 2 as a m odeless form w it h t he Show m et hod. The user can close t he
m essage box w it hout opening Form 2 by click ing t he Cancel but t on. Recall t hat a
m essage box is a m odal form . Therefore, y ou m ust offer an opport unit y t o close a
m essage box for an applicat ion t o proceed.
Private Sub Form1_Load(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles MyBase.Load

     ’Position the form toward top left area of desktop,
     ’widen Button1’s width from its default setting of 75 pixels
     ’and assign a caption for Button1 as its Text property.
     Me.DesktopLocation = New Point(100, 100)
     Button1.Width = 85
     Button1.Text = “Open Form 2"

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
     ’Invoke the OpenForm2 procedure.
     OpenForm2()

End Sub

Sub OpenForm2()

     ’Declare a pointer reference for Form2.
     Dim MyFormPointer As New Form2()

     ’Assign Text property for Button1 in Form2.
     MyFormPointer.Button1.Text = “Close"

     ’Open a new instance of Form2 as a modal form or a modeless form.
     ’When opening Form2 as a modal form,
     ’   1. Assign a value to the Text property of TextBox1.
     ’   2. Assign a start position 400 pixels down the page.
     ’   3. Use the ShowDialog method for the object reference.
     ’      pointing at Form2
     ’When opening Form2 as a modeless form,
     ’   1. Assign a start position 200 pixels down the page
     ’   2. Use the Show method for the object reference
     ’      pointing at Form2.
     ’   3. Assign a value to the Text property of TextBox1.
     If MsgBox(“Open Form2 as Modal", MsgBoxStyle.YesNo) = _
         MsgBoxResult.Yes Then
         MyFormPointer.TextBox1.Text = “I am modal."
         MyFormPointer.Downpix = 400
         MyFormPointer.ShowDialog()
     ElseIf MsgBox(“OK, I am opening Form2 as a Modeless form.", _
         MsgBoxStyle.OKCancel) = MsgBoxResult.OK Then
         MyFormPointer.Downpix = 200
         MyFormPointer.Show()
         MyFormPointer.TextBox1.Text = “I am modeless."
     End If

End Sub

The code blocks for opening Form 2 as a m odal or m odeless form vary in m or e
way s t han j ust t he use of t he m et hod t o open t he form . For t he block t hat opens
Form 2 as a m odal form , t he block st art s by set t ing t he Text pr opert y of Text Box1
on Form 2. Visual Basic doesn’t allow y ou t o dy nam ically set t he Text propert y of
Text Box1 when Form 2 is open as a m odal form . Therefore, t he applicat ion m ak es
t he set t ing befor e opening t he form . I n t he case of a m odeless form , t he
applicat ion set s t he Tex t propert y for Text Box1 aft er t he form opens. Downpix is
t he cust om Form 2 propert y t hat det erm ines how far dow n on t he desk t op Form 2
appears. By vary ing t he value of Dow npix depending on w het her Form 2 opens as
a m odal or m odeless form , t he applicat ion m ak es it easier t o ident ify how Form 2
is open. Because t he Downpix propert y det erm ines w her e t he form opens on t he
deskt op, you nat urally have t o specify t he propert y’s value before opening t he
for m .
The cust om code behind Form 2 consist s of t he t wo ev ent procedures in t he
follow ing code sam ple along wit h a Public var iable declarat ion. The Public
declarat ion is for t he Downpix var iable. The For m 2_Load ev ent pr ocedure uses
t he value of t his var iable t o specify t he posit ion for opening Form 2 on t he
deskt op. The ev ent pr ocedur e also dy nam ically set s t he Text pr opert y for
But t on1. The But t on1_Click ev ent procedur e dem onst rat es t he synt ax for closing
a form program m at ically wit hout using t he st andard Close but t on on form s. Using
t he Close m et hod is appropr iat e for sit uat ions in which you have t o per form som e
special funct ions at t he t im e t hat a form closes.

                                     N ot e
You can suppr ess t he display of t he st andard Close but t on on
a Windows for m by set t ing t he form ’s Form Bor der St y le
proper t y t o None in t he Proper t ies window.
Public Downpix As Integer
Private Sub Form2_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

     ’Position the form 450 pixels from the desktop’s left border,
     ’and Downpix units from the desktop’s top border.
     Dim MyStartPoint As New Point(450, Downpix)
     Me.DesktopLocation = MyStartPoint
     Button1.Text = “Close"

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

     ’Close the current form (Form2).
     Me.Close()

End Sub




Cr e a t in g a n d Usin g Cla ss Refe r e n ce s
A firm grasp of class developm ent pr inciples is m or e im port ant when cr eat ing
solut ions wit h Visual Basic .NET t han for pr ior v ersions of Visual Basic. I n
addit ion, t hrough nam espace designat ions y ou can refer w it h a com m on sy nt ax t o
bot h cust om classes and built - in .NET Fram ework classes. Built - in classes ar e
m or e prom inent t han in any pr ior version. For exam ple, ev en dat a t ypes behav e
as classes in t hat y ou can inst ant iat e a dat a t y pe w hen you declar e a variable
based on it . Nam espaces and classes underpin one anot her , so a good grasp of
eit her r equir es a work ing know ledge of bot h. This sect ion cont ains a m ix of
com m ent ary on class and nam espace issues along w it h sam ples especially
designed t o j um p- st art your use of classes wit h Visual Basic .NET.

Cr e a t in g a Cla ss t o Pe r for m Ca lcu la t ion s

A t y pical r eason for using classes is t o ensur e t hat select ed calculat ions are
always per form ed exact ly t he sam e way t hroughout an organizat ion. A calculat ion
can be for t ax ing aut hor it ies, account ing r eport s, or scient ific applicat ions. Rat her
t han have every applicat ion t hat needs t he calculat ions separat ely code t he
expression for a calculat ion, y our applicat ions can reference a class wit h t he
calculat ions accurat ely perform ed. This applicat ion for classes elim inat es possible
errors by j unior pr ogram m ers w ho m ay not have t he experience t o code t he
calculat ion pr oper ly. I n addit ion, t he pract ice of coding calculat ions in classes
m akes for easy updat ing of t he com put at ions because t her e is a single point t o
m odify when an updat e is necessary ( for exam ple, because of a new t ax rat e) .
Alt hough y ou can cr eat e a com put at ional class as part of a Windows applicat ion,
you w ill t ypically der iv e m or e v alue fr om t he class by creat ing a st and- alone .dll
file for it . Then any proj ect can creat e a refer ence t o t he class t hr ough it s .dll.
This sect ion dem onst rat es t he overall process of creat ing a .dll for a class t hat
perform s calculat ions.

                                     N ot e
To creat e a Class proj ect , choose t he Class Library t em plat e
fr om t he New Proj ect dialog box ( which, as you’ll recall,
opens w hen y ou click t he New Pr oj ect but t on on t he Visual
St udio St art page) . Assign a nam e for your class. Visual
St udio .NET creat es an assem bly folder for t he class. The .dll
file in t he assem bly folder wit h t he sam e filenam e as t he
proj ect for t he Class Librar y cont ains t he com piled code for
t he class.
To keep t he focus on t he const ruct ion of t he class .dll file, I const ruct a sim ple
sam ple class nam ed Class1 wit h it s com piled code in Arit hm et icClass.dll. ( See t he
follow ing code for t he class, which is available for v iew ing in Class1.vb.) Class1
exposes t wo propert ies and four m et hods. The propert ies repr esent t w o num bers
t hat ser ve as input for one of four calculat ions also defined in t he class. The
propert ies ar e designat ed as Wr it eOnly because applicat ions referencing t he class
m er ely need t o copy values t o t he propert ies, w hich is anot her way of saying
assign values t o t he propert ies. The class ret ur ns values t hr ough it s four funct ion
procedur es, w hich im plem ent t he four m et hods for t he class. The funct ions,
respect ively , add, subt r act , m ult iply , and div ide t he t wo num bers represent ed by
t he class propert y values.
Because t he class calls for Writ eOnly pr opert ies, we cannot use a Public var iable
declarat ion. I nst ead, t he class uses a propert y procedur e t o enforce w rit e- only
access t o each pr opert y . When you use only t he Get clause or only t he Set clause
in a propert y pr ocedur e, y ou m ust also declar e t he propert y wit h eit her t he
ReadOnly keyword or t he Wr it eOnly k ey word. The sam ple dem onst rat es t he
synt ax for using t he Wr it eOnly keyword w it h t he Set clause for t he dblFirst and
dblSecond propert ies of Class1. These propert y nam es are for ext ernal
com m unicat ion wit h t he Class1 in t he Arit hm et icClass proj ect . The class int er nally
m anipulat es dbl1 and dbl2, which cor respond t o dblFirst and dblSecond. The Set
clauses for each pr opert y accept values t hrough t heir dblValue input argum ent .
Aft er t he propert y pr ocedur es for dblFirst and dblSecond, t he list ing shows t he
four funct ion procedures for im plem ent ing t he add, subt ract , m ult iply , and div ide
operat ions bet w een t he t wo pr opert y values. Visual Basic .NET perm it s y ou t o
ret ur n a value from a funct ion pr ocedure in eit her of t wo ways. First , you can
assign a value t o t he funct ion nam e, as you did in prev ious v ersions of Visual
Basic. Second, you can designat e t he funct ion’s value wit h an expression serv ing
as t he argum ent for a Ret ur n st at em ent . The synt ax for bot h approaches appears
in t he Add2dbls funct ion procedure. I com m ent ed out t he t radit ional approach
t hat assigns a value based on t he funct ion’s nam e. The ot her t hr ee funct ion
procedur es dem onst rat e use of t he t radit ional approach for specify ing a r et urn
value.
Public Class Class1
      Private dbl1 As Double
      Private dbl2 As Double

     ’WriteOnly property named dblFirst.
     Public WriteOnly Property dblFirst() As Double
     Set(ByVal dblValue As Double)
         dbl1 = dblValue
     End Set
     End Property

     ’WriteOnly property named dblSecond.
     Public WriteOnly Property dblSecond() As Double
     Set(ByVal dblValue As Double)
         dbl2 = dblValue
     End Set
     End Property

     ’Add dbls.
     Function Add2dbls() As Double
     ’Add2dbls = dbl1 + dbl2
     Return (dbl1 + dbl2)
     End Function

     ’Subtract dbls.
     Function Diff2dbls() As Double
     Diff2dbls = dbl1 - dbl2
     End Function

     ’Multiply dbls.
     Function Mult2dbls() As Double
     Mult2dbls = dbl1 * dbl2
     End Function

     ’Divide dbls.
     Function Div2dbls() As Double
     Div2dbls = dbl1 / dbl2
     End Function

End Class



Re fe r e n cin g a Cla ss f r om a W in dow s Applica t ion

The class const r uct ed in t he pr eceding sect ion has no v isual int erface. I n order t o
use t he class in an int eract ive applicat ion, you need t o t eam t he class proj ect w it h
anot her t ype of pr oj ect , such as a Windows applicat ion. When a Windows
applicat ion r efers t o t he proj ect , you get t he best of bot h. The Windows
applicat ion offers a r ich graphical env ironm ent for gat her ing input and display ing
result s t o users. The class proj ect offers an env ironm ent t hat can efficient ly
perform calculat ions and shar e it s com put at ional engine w it h m any client s
concur r ent ly . Each client can sim ply m ake an inst ance of t he class t o gain access
t o it s propert ies and m et hods.
Figur e 9- 5 shows a Windows applicat ion w it h one form t hat uses Class1 in t he
Arit hm et icClass proj ect . The form t hat appears in Figur e 9- 5 resides in t he
Arit hm et icForm proj ect . When t he user click s one of t he four but t ons on t he form ,
t he Windows applicat ion t akes t he values in t he t op t wo t ext box es and passes
t hem t o t he dblFirst and dblSecond pr opert ies in t he class. Then it inv ok es a class
m et hod t hat cor r esponds t o t he click ed but t on. For exam ple, Figur e 9- 5 shows
t hat t he + but t on was select ed last . Ther efor e, t he applicat ion invoked t he
Add2dbls funct ion procedure and insert ed t he r et ur n value fr om t he procedure in
t he bot t om t ext box on t he form .

  Figu r e 9 - 5 . A W ind ow s a pp lica t ion for u sin g t h e Arit h m e t icClass cla ss
                                      lib ra ry p roj e ct .
The cont r ols on t he for m in Figur e 9- 5 hav e pr opert y set t ings t o m ak e t he
applicat ion’s user int erface v isually appealing. Many developers m ight prefer t o
m ake m ore r efinem ent s while using t hose her e as a base. The but t ons, for
exam ple, hav e a slight ly enlarged font over t he default size t hat appear s in
boldface. Of course, t he but t on size is r educed t o accom m odat e t he side- by - side
display of all four but t ons abov e t he t ext boxes. The Text Align propert y of t he
t ext boxes is set t o Right . This set t ing displays t he t ext box cont ent s wit h an
alignm ent t hat is t ypical for num bers as opposed t o st r ings, which is t he default
Text Align pr opert y value.
Because t he class in t he preceding sect ion resides in a st andalone .dll file, t he
Windows applicat ion whose form appears in Figur e 9- 5 m ust have a refer ence t o
t hat .dll file. This reference perm it s t he form t o int erface w it h t he class propert ies
and m et hods defined in t he Visual Basic .NET code for t he class. ( See t he
preceding sect ion. ) Ther e are t wo t echniques t o help you m anage a r eference t o a
.dll file w it hin a Windows applicat ion. First , y ou can choose t o add a r efer ence t o
t he .dll file. Aft er y ou add t he r eference, you can refine how y our applicat ion
refers t o t he refer enced .dll file w it h t he I m port s st at em ent , which defines t he
second t echnique. The I m port s st at em ent groups t he class elem ent s as it em s in a
nam espace sim ilar t o t he way t he Syst em .Windows.Form s nam espace groups t he
elem ent s under ly ing t he funct ionalit y in a Windows form . I nst ead of using t he full
proj ect nam e and class nam e t o designat e a collect ion of it em s, y ou can define an
alias as a m or e fam iliar nicknam e for t he class. I f t he nam es of elem ent s in y our
class conflict w it h t hose in your proj ect or anot her refer enced nam espace, using
t he nick nam e r esolv es conflict s.

                                     N ot e
Visual Basic doesn’t st r ict ly r equire t he use of an alias
defined by an I m port s st at em ent t o resolve nam ing conflict s
bet ween different nam espaces. Howev er , t he abilit y t o help
resolve conflict s com bined wit h t he oppor t unit y t o define a
cust om fam iliar nam e defined by t he alias is a very at t r act ive
pair of feat ures.
To add a r eference for a proj ect , choose Add Reference fr om t he Pr oj ect m enu in
t he Code Edit or. For exam ple, if you ar e wor k ing wit h a Windows applicat ion, y ou
can choose Pr oj ect and t hen Add Refer ence from t he Form 1.vb t ab. Next select
t he Pr oj ect s t ab. Then click Br owse and nav igat e t o t he .dll t o w hich you want t o
for m a refer ence. For t his exam ple, y ou can nav igat e t o t he bin folder of t he
Arit hm et icClass proj ect assem bly. Select t he .dll file, which has t he nam e
Arit hm et icClass.dll in our exam ple, and click Open in t he Select Com ponent dialog
box. Then click OK t o close t he Add Reference dialog box .
Aft er creat ing a r efer ence t o t he .dll file, you m ust st ill inst ant iat e t he class in t he
code behind a form before you can refer t o it s elem ent s. Use t he I m port s
st at em ent ’s alias for t he class library in t he Dim st at em ent t hat inst ant iat es t he
class. You m ust posit ion t he I m port s st at em ent im m ediat ely aft er t he Opt ion
st at em ent , w hich is t he first st at em ent w it hin t he code m odule behind a form .
The follow ing sam ple list ing shows an I m port s st at em ent t hat creat es an alias
nam ed clsArit h for t he Class1 class in t he Ar it hm et icClass proj ect .

                                       N ot e
Alt hough t he Opt ion st at em ent isn’t st rict ly requir ed, it s use
can help you m anage your code. For exam ple, t he Opt ion
St r ict On declarat ion em braces and ex tends t he Opt ion
Explicit st at em ent . Wit h an Opt ion St r ict On declarat ion, y ou
m ust declare v ar iables wit h a t y pe befor e using t hem . I n
addit ion, t his Opt ion st at em ent prohibit s dat a t y pe
conversions t hat can lead t o dat a loss. Alt hough a r un- t im e
err or accom panies t hese conv er sions, t he Opt ion St rict On
declarat ion flags t hese conversions at com pile t im e. The
Opt ion St rict On st at em ent also prohibit s m ost r efer ences t o
t he Obj ect t ype, which ser ves as a cat chall t ype, m uch lik e
t he Variant dat a t y pe in ear lier v er sions of Visual Basic.
Aft er t he Dim st at em ent , t he code behind t he form r elies on four Click event
procedur es and one sub procedure, PassText BoxValues, called by each ev ent
procedur e. The PassTex t Box Values pr ocedure passes t he values from t he t ext
boxes on t he form t o t he pr opert ies for t he clsArit h class. As t he procedur e
passes t he cont ent s of t he t ext box es, it t ransform s t hem from st ring v alues int o
num er ic values w it h t he CDbl funct ion. All t he event pr ocedur es for t he four
but t ons hav e t he sam e general st ruct ur e. They differ by funct ion nam e and t he
class m et hod inv ok ed. For exam ple, t he first ev ent procedure is for But t on1 wit h
it s Text pr opert y set t o + . This ev ent pr ocedur e inv ok es t he Add2dbls m et hod for
t he clsArit h class. Befor e insert ing t he r et urn v alue fr om t he m et hod int o t he
bot t om t ext box on t he for m , t he pr ocedur e t ransform s t he Double dat a t ype int o
a St r ing dat a t ype for com pliance w it h t he Text propert y of a t ext box .

                                       N ot e
The applicat ion in t he following list ing is a bar e- bones
dem onst r at ion of how t o r efer ence a class. For exam ple, t he
form fails if y ou don’t ent er values in bot h of t he t ext box es
for input before clicking an arit hm et ic funct ion but t on. You
can rem edy t his sit uat ion by assigning default v alues for t he
input boxes or pr om pt s in t he input boxes wit h t he Load
event procedure for Form 1.
Option Strict On
Imports clsArith = ArithmeticClass.Class1
Public Class Form1
    Inherits System.Windows.Forms.Form
‘Windows Form Designer generated code goes here.

    ’Instantiate Class1 from ArithmeticClass for use
    ’with all the code behind Form1.
    Dim MyClass1 As New clsArith()

    Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

    ’Pass text box values to class.
    PassTextBoxValues()

    ’Convert Add2dbls function to a string in TextBox3.
    Me.TextBox3.Text = MyClass1.Add2dbls.ToString()

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button2.Click

    ’Pass text box values to class.
    PassTextBoxValues()

    ’Convert Diff2dbls function to a string in TextBox3.
    Me.TextBox3.Text = MyClass1.Diff2dbls.ToString()

    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button3.Click

    ’Pass text box values to class.
    PassTextBoxValues()

    ’Convert Mult2dbls function to a string in TextBox3.
    Me.TextBox3.Text = MyClass1.Mult2dbls.ToString()

    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button4.Click

    ’Pass text box values to class.
    PassTextBoxValues()

    ’Convert Div2dbls function to a string in TextBox3.
    Me.TextBox3.Text = MyClass1.Div2dbls.ToString()

    End Sub

    Sub PassTextBoxValues()

    ’Pass text box values to class.
    MyClass1.dblFirst = CDbl(Me.TextBox1.Text)
    MyClass1.dblSecond = CDbl(Me.TextBox2.Text)

    End Sub

End Class
.N ET N a m e spa ce Ar ch it e ct ur e

Nam espaces ar e t he m eans by w hich t he .NET Fram ework car ves up and m akes
available it s fundam ent al funct ionalit y . Nam espaces corr espond t o t ypes. I n t he
preceding t w o sect ions, Class1 in t he Ar it hm et icClass proj ect was a t ype. H-
owev er, t his t ype was a user - defined t ype. The .NET Fram ework includes it s ow n
built - in nam espace archit ect ur e. This archit ect ure includes t wo general cat egor ies
of t ypes.
The first of t hese gener al cat egor ies is value t y pes. Value t ypes cont ain values as
well as t he descript ion for a value. For exam ple, a st r ing is a value t ype. The
St r ing value is a sequence of Unicode charact er codes for represent ing t he
charact ers t hat m ak e up t he st ring. The cont ent s in a t ext box are repr esent ed as
a St r ing value t ype. A Double value t ype is a 64- bit float ing- point num ber . Ther e
is a core set of t hese .NET Fram ework value t ypes. Visual Basic .NET has dat a
t ypes t hat correspond t o m any of t he .NET Fram ework dat a t y pes.
The second general cat egory of t ypes is reference t ypes. A reference t ype can be
your cust om class, such as Arit hm et icClass.Class1 or any of t he built - in .NET
Fram ew ork nam espaces. The Syst em nam espace cont ains near ly 100 classes t hat
facilit at e core .NET Fram ework funct ionalit y, such as t he garbage collect or and
except ion handling. The .NET Fram ework offers except ion handling for t he
processing of run- t im e er rors; I dw ell on t his m or e deeply in t his chapt er ’s last
m aj or sect ion. The Syst em nam espace cont ains m any second- lev el and t hird-
level nam espaces t hat handle im port ant funct ionalit y. For exam ple,
Syst em .Windows.Form s is a t hird- lev el nam espace t hat support s t he inst ant iat ion
and m anipulat ion of for m classes wit hin a Windows applicat ion. The Sy st em .Web
nam espace enables t he ASP.NET infrast ruct ur e. The Syst em .Dat a nam espace
perform s corr esponding funct ions for ADO.NET.
Table 9- 1 list s t he m ain value t ypes for t he Syst em nam espace. This t able
includes a Syst em nam espace class nam e, a m at ching Visual Basic dat a t ype
when t her e is one, and a br ief descript ion of t he value t ype.
One im port ant difference bet ween value t ypes and reference t ypes is t hat value
t ypes r et ain values w it h t hem , but reference t y pes point t o values. This sim ple
st at em ent can lead t o som e significant differences in t he behav ior of v ariables
declared as value vs. r eference t ypes. An equalit y assignm ent st at em ent bet ween
t wo var iables point ing t o value t ypes set s t he v alues of t he var iables equal. I f y ou
subsequent ly assign a new v alue for one of t hese var iables, it ’s no longer equal t o
t he ot her var iable. Wit h r efer ence t y pes, t he rules ar e different . When y ou assign
t wo var iables point ing t o reference t ypes equal t o one anot her, y ou set t heir
obj ect r eferences t o t he sam e obj ect . Subsequent ly, set t ing one var iable equal t o
a quant it y assigns t hat quant it y t o bot h var iables. This is because t he var iables
point t o t he sam e obj ect . Alt hough t he behav ior of t hese var iable r efer ences is
subst ant ially differ ent , t he synt ax for m anipulat ing t hem is sim ilar. Just
rem em ber, value t ypes st ore act ual values, but reference t ypes st or e point ers t o
obj ect s. The refer ence t ypes don’t st ore values. I nst ead, t he refer ence t ypes
der iv e value fr om t he obj ect s t o which t hey point .
                 7DEOH  6XPPDU\ RI 6HOHFWHG 1(7 )UDPHZRUN 9DOXH 7\SHV

        6\VWHP      9LVXDO %DVLF                             'HVFULSWLRQ
   1DPHVSDFH         'DWD 7\SH
   &ODVV 1DPH
Byt e               Byt e          8- bit unsigned int eger
I nt 16             Short          16- bit signed int eger
I nt 32             I nt eger      32- bit signed int eger
I nt 64             Long           64- bit signed int eger
Single             Single          32- bit float ing point num ber
Double             Double          64- bit float ing point num ber
Boolean            Boolean         A value t hat can be eit her Tr ue or False
Char               Char            Unicode charact ers w it h hexadecim al values ranging
                                   from 0x0000 t hr ough 0xFFFF
Decim al           Decim al        A signed int eger num ber wit h a m ax im um of 96 bit s
                                   of precision and up t o 28 digit s aft er t he decim al
                                   point
I nt Pt r          No built - in   A signed int eger w hose size depends on t he
                   t ype           plat form ; for exam ple, it can be a 32- bit value on a
                                   32- bit plat form or a 64- bit value on a 64- bit plat form
Dat eTim e         Dat e           Dat es and t im es in t he r ange from 0: 00: 00 January
                                   1, 0001, t hr ough 11: 59: 59 Decem ber 31, 9999
St r ing           St r ing        An im m ut able fix ed- lengt h sequence of Unicode
                                   charact ers
Obj ect            Obj ect         Root of t he t ype hierarchy ; all ot her classes in t he
                                   .NET Fr am ew ork der ive from t his one
To highlight t his dist inct ion, I const ruct ed t he TypeTest s Windows applicat ion. I t
cont ains a Windows for m wit h a but t on t hat inv ok es a procedure w hen you click
it . The procedure dem onst rat es t he pot ent ial v ariable refer ences pit falls as well as
a r em edy. The TypeTest s proj ect also cont ains a built - in class. This class is a
reference t ype. The class definit ion includes a cust om const ruct or funct ion for
init ializing t he class’s propert y v alue as w ell as a propert y procedur e wit h bot h
Get and Set clauses for reading and w r it ing t o it s sole pr opert y.
The follow ing Visual Basic code sam ple shows t he synt ax for t he class definit ion.
Ty peRef is t he class nam e. I t s only pr opert y has t he nam e Value. The Sub New
const ruct or init ializes Value t o m yI nput w henev er an applicat ion inst ant iat es a
new inst ance of t he Ty peRef class. The synt ax for t he Value pr opert y procedure
dem onst rat es how t o specify a read/ w r it e pr opert y for a funct ion.
Public Class TypeRef
       Private intLocal

       ’Intialize Value to myInput.
       Public Sub New(ByVal myInput As Integer)
       Dim Value As Integer = myInput
       End Sub

       ’Read/Write property named Value.
       Public Property Value() As Integer
       Get
           Return intLocal
       End Get
       Set(ByVal Value As Integer)
           intLocal = Value
       End Set
       End Property

End Class

The next code excerpt from t he TypeTest s proj ect shows t he code for
dem onst rat ing t he problem as w ell as a w ork ar ound t o t he problem . The code
excerpt invok es t he ValueRefer enceTypeTest pr ocedur e w hen a user clicks
But t on1. The pr ocedur e has t hr ee sect ions. Each sect ion pauses by pr esent ing a
m essage box t hat show s t he result of var iable assignm ent s for eit her v alue or
reference t ypes.
       Private Sub Button1_Click(ByVal sender As System.Object, _
             ByVal e As System.EventArgs) Handles Button1.Click
     ValueReferenceTypeTest()
     End Sub

     Sub ValueReferenceTypeTest()
     ’Declare and assign values to a type instance (Integer).
     Dim val1 As New Integer()
     Dim val2 As Integer = val1
     val2 = 123
     MsgBox(“val1 = “ & CStr(val1) & vbCrLf & _
         “val2 = “ & CStr(val2), _
         MsgBoxStyle.DefaultButton1, _
         “Type Assignments Test”)

     ’Declare and assign values to a class reference.
     Dim ref1 As New TypeRef(0)
     Dim ref2 As TypeRef = ref1
     ref2.Value = 123
     MsgBox(“ref1 = “ & CStr(ref1.Value) & vbCrLf & _
                 “ref2 = “ & CStr(ref2.Value), _
                 MsgBoxStyle.DefaultButton1, _
                 “Reference Assignments Test1”)

     ’Declare and assign values to two different class references.
     Dim ref3 As New TypeRef(0)
     Dim ref4 As New TypeRef(0)
     ref4.Value = 123
     MsgBox(“ref3 = “ & CStr(ref3.Value) & vbCrLf & _
             “ref4 = “ & CStr(ref4.Value), _
                 MsgBoxStyle.DefaultButton1, _
                 “Reference Assignments Test2”)
     End Sub

The result s in each m essage box r ev eal t he out com e of t he assignm ent
st at em ent s. Figur e 9- 6 shows each m essage box. Because t he boxes have unique
t it les, y ou can m ap t he out com es t o t he differ ent synt act ic const ruct ions.

 Figu r e 9 - 6 . Sim ila r a ssig n m en t st a t e m e n t s ca n yie ld d iffer e n t out com e s
                 for va lu e a n d r efe re n ce t ype va riab le d eclar at ion s.
The first m essage box in Figur e 9- 6 present s t he cont ent s of t wo variables
point ing t o value r eferences. Bot h val1 and val2 point t o I nt eger dat a t ypes,
which ar e value t ypes. The .NET Fram ew ork init ializes an I nt eger value t o 0.
Ther efor e, t he Dim st at em ent for val1 set s t he var iable t o 0. The Dim st at em ent
for val2 set s t he val2 variable equal t o t he curr ent value of val1, w hich is 0 from
t he preceding st at em ent . Next t he procedure assigns t he value 123 t o v al2 and
t hen pr int s t he values of val1 and val2 in a m essage box . As you can see, val1
equals 0, but val2 equals 123. This is because t he value goes w it h t he var iable for
variable assignm ent s t o value t ypes.
The second m essage box in Figure 9- 6 shows t he out com e for t he next block of
st at em ent s. These begin by defining a new v ar iable r eference t o t he Ty peRef
class. This st at em ent ex plicit ly init ializes t he var iable t o 0. ( See t he New
const ruct or for TypeRef.) Next t he procedur e uses a Dim st at em ent t o set r ef2
equal t o ref1. Because r ef1 equals 0, r ef2 also equals 0 aft er t he st at em ent . Then
t he procedure assigns 123 t o t he Value pr opert y of t he r ef2 var iable r eference.
The st at em ent assigns 123 t o t he Value pr oper t y of r ef1 as well. This is because
t he preceding st at em ent set s t he t w o var iables, r ef1 and ref2, equal t o t he sam e
obj ect inst ance of t he TypeRef class. Because t her e is j ust one inst ance, it can
hav e j ust one Value pr opert y . Therefor e, t he m essage box for t he second sect ion
shows bot h var iables equal t o t he sam e value. This is so ev en t hough t he second
Dim st at em ent has t he sam e synt ax in t he first and second sect ions. When
wor k ing w it h variables point ing t o r eference t ypes, y ou m ust separat ely
inst ant iat e a class obj ect for each var iable if y ou want t o m ak e dist inct
assignm ent s t o each of t hem . The final sect ion in t he ValueRefer enceTy peTest
procedur e dem onst rat es t he sy nt ax for achiev ing t his out com e. The final m essage
box in Figur e 9- 6 confirm s t he r esult .

Con ve r t in g Be t w e e n V a lue Typ e s

The value t ypes denot ed in Table 9- 1 hav e fundam ent ally differ ent ways of
represent ing values w it hin a com put er. Nevert heless, applicat ions fr equent ly need
t o pass values back and fort h bet ween different value t ypes. Any t ext box has a
Text pr opert y, which relies on a St ring value t y pe for r epr esent ing it s cont ent s.
Howev er, applicat ions will som et im es need t o gat her num er ic input or display
num er ic out put via a t ex t box . The num er ic represent at ion of a num ber in a t ext
box can r equir e a t ranslat ion fr om a St r ing t ype t o anot her t ype, such as Double
or I nt eger. The t ranslat ion is necessary because it is only in a num er ic
represent at ion t hat a com put er can perform ar it hm et ic calculat ions w it h value
t ypes. I f you don’t ex plicit ly perform t he t r anslat ion, t he .NET Fram ework w ill
perform it im plicit ly. You should underst and t hat y ou m ight not always be able t o
wor k perfect t ranslat ions bet ween all value t ypes. This sect ion and t he next one
include som e sam ples t o acquaint y ou w it h t he kinds of issues t hat affect
t ranslat ions bet w een dat a t ypes.
Visual Basic offers a r ich array of funct ions for conv ert ing bet ween value t ypes. A
ser ies of inline conv ersion funct ions can t r ansform any appropriat e expression
int o a cor responding value t ype. For exam ple, CInt(63.4) ret ur ns an int eger
equal t o 63. The CI nt funct ion r ounds fract ions. The full set of inline conversion
funct ions com pr ises CBool, CByt e, CChar, CDat e, CDbl, CDec, CI nt , CLng, CObj ,
CShort , CSng, and CSt r . For t hese funct ions t o work pr oper ly , t heir argum ent
m ust be suit able for t he value t hey ret ur n. At t em pt ing t o r et urn a value from
CByte(256) raises an except ion, or r un- t im e er ror, because 256 is out side t he
range of legit im at e byt e values. The CType funct ion can explicit ly conv ert an
expression ( or const ant ) t o a value t ype. For ex am ple, y ou can use CType(63.4,
Integer) t o conv ert a value w it h a decim al point t o one w it hout a decim al point .
A conv enient approach for convert ing a num ber t o a st r ing is t o append t he
ToSt r ing funct ion nam e t o t he end of t he num eric value, such as 45.ToString .
Addit ional t ransform at ion funct ions in t he st y le of ToSt r ing are available for ot her
value t ypes.
I updat ed Form 1 in t he TypeTest s proj ect by adding anot her but t on, But t on2, and
a t ext box, Text Box1. I n addit ion, t his sam ple r elies on Opt ion St rict On being t he
first st at em ent in t he m odule behind Form 1 for t he pr oj ect . The code involv es t wo
ev ent procedures. ( See t he follow ing list ing.) The Form 1_Load ev ent pr ocedur e
labels t he but t on Add 1 because click ing it adds 1 t o t he t ext box value. The
procedur e also assigns t he st ring 1 t o t he Text propert y of t he t ext box . The Click
ev ent procedure for But t on2 adds 1 t o t he value in t he t ext box. Wit hout t w o
conv ersions, t he ar it hm et ic for t he conv ersion will fail. First t he Click event
procedur e t ransform s t he st r ing pr opert y of t he value in t he t ext box int o an
int eger . Second t he expression in t he ev ent procedur e uses t he ToSt ring funct ion
t o convert t he num er ic value in t he addit ion ex pression t o a st ring. Wit hout bot h
of t hese conversions, y ou w ill generat e a com pilat ion err or w hen Opt ion St r ict On
is t he first st at em ent in t he m odule.
      Private Sub Form1_Load(ByVal sender As System.Object, _
             ByVal e As System.EventArgs) Handles MyBase.Load

           ’Initialize button and text box text settings.
           Button2.Text = “Add 1"
           TextBox1.Text = “1"

     End Sub

     Private Sub Button2_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button2.Click

         ’Transformations required by Option Strict On.
         TextBox1.Text = (CInt(TextBox1.Text) + 1).ToString
     End Sub


Fr om Lon g t o H e x a de cim a l a nd Ba ck Aga in
Visual Basic has long had t he Hex funct ion for convert ing int eger num eric v alues
t o hexadecim al st rings t hat r epresent t he num eric v alue of t he Hex funct ion
argum ent . The .NET docum ent at ion explicit ly st at es t hat t he funct ion w ill w or k for
Byt e, Short , I nt eger, Long, and Obj ect dat a t ypes. As it t urns out , t he m axim um
value t hat t he Hex funct ion w ill convert is 9,223,372,036,854,775,807, which is
t he m ax im um Long value t ype. Values abov e t his raise an except ion.

                                     N ot e
I f you ar en’t fam iliar wit h conversions bet ween hexadecim al
num bers and base 10, you can use t he Windows Calculat or
t o help ver ify t he operat ion of t he sam ples in t his sect ion.
The follow ing pair of procedur es dem onst rat es how t o use t he Hex funct ion t o
conv ert t he Long value in t he t ext box from t he preceding sam ple t o a Hex value
t hat appears in a m essage box. Click ing But t on3 on t he form in t he Ty peTest s
proj ect launches t he Conv ert LngToHex pr ocedure. This pr ocedur e’s list ing
dem onst rat es t he synt ax for specify ing a condit ional com pilat ion, w hich includes
t he # befor e k eyw ords. The value of BoundCheck is True, so t he com piler insert s
t he opt ional code t hat per form s a bound check t o abort t he conv ersion if t he Hex
funct ion argum ent is great er t han t he m ax im um value t hat t he built - in funct ion
can convert . Condit ional com pilat ion was init ially int roduced int o Visual Basic w it h
version 5. The conv ersion pr ocedur e concludes by display ing t he ret urn value of
t he Hex funct ion ( unless t he procedure abort s because t he argum ent is t oo
large) .

                                     N ot e
Set t ing t he BoundCheck com piler const ant t o False perm it s
you t o generat e an ex cept ion for v alues gr eat er t han t he
m ax im um conversion value— for exam ple,
9,223,372,036,854,775,808.
Private Sub Button3_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button3.Click

     ’Call procedure to convert text box value
     ’from long to hexadecimal.
     ConvertLngToHex()

End Sub

Sub ConvertLngToHex()
    #Const BoundCheck = True

     #If BoundCheck Then
         ’Bound check on input; use CDec to accommodate values
         ’beyond bound check.
         If CDec(TextBox1.Text) > 9223372036854775807 Then
             MsgBox(“Number too large for Hex function.”)
             Exit Sub
         End If
     #End If

     ’Convert from string representation of Long number to
     ’hex character representation of number.
     MsgBox(“Hex value of text box equals:” & vbCrLf & _
         Hex(CLng(TextBox1.Text)))
End Sub

Going from a hexadecim al value t o a Long value is m or e com plicat ed for a couple
of reasons. First , t her e is no built - in funct ion. Second, hexadecim al num bers need
t o be convert ed on a charact er - by - charact er basis t hat reflect s t he char act er’s
posit ion in t he hexadecim al num ber. This t ask is furt her com plicat ed by t hat fact
t hat charact ers go out side t he decim al range of 0 t hrough 9 t o t he hex adecim al
range of 0 t hrough F. The follow ing sam ple per for m s a check t o v er ify t hat t he
hexadecim al st r ing value doesn’t exceed t he m axim um Long value. The hex
represent at ion for t he m axim um Long value is 7FFFFFFFFFFFFFFF.
Aft er perform ing a bound check for t he m ax im um hex adecim al value, t he
Convert Hex ToLng pr ocedur e st art s a loop t hat it erat es t hr ough successiv e
charact ers in t he hexadecim al num ber. St art ing at t he far r ight charact er , t he
loop evaluat es each charact er. The evaluat ion m ult iplies t he hex charact er’s
decim al v alue by a power of 16. The pow ers range in value fr om 0 for t he far
right charact er t o up t o 15 for t he sixt eent h hex charact er ( if t her e is one) . When
t he Conv ert HexToLng procedur e finishes looping t hr ough t he charact er s in t he
hexadecim al num ber, t he pr ocedur e present s a m essage box w it h t he decim al
value of t he hexadecim al num ber in Text Box1.
Private Sub Button4_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button4.Click

    ’Call program to convert a hexadecimal number to
    ’a Long number.
    ConvertHexToLng()
End Sub

Sub ConvertHexToLng()

     ’Assign TextBox1 contents to hexStr.
     ’Dim strValue As String = TextBox1.Text
     Dim hexStr As String = TextBox1.Text

     ’If hexStr greater than 7FFFFFFFFFFFFFFF, then abort.
     Dim hexchars As Integer = Len(hexStr)
     If (hexchars = 16 And hexStr.Chars(0) > “7”) Or _
         hexchars > 16 Then
         MsgBox(“Hex values beyond 7FFFFFFFFFFFFFFF “ & _
         “generate an exception. Enter a smaller “ & _
         “hex value.”)
         Exit Sub
     End If

     ’Variable lnghexstr stores long of hex string in TextBox1,
     ’and i is a loop counter value.
     Dim lnghexstr As Long
     Dim i As Integer

     ’Loop through characters to compute decimal equivalent
     ’of hex string.
     lnghexstr = 0
     For i = 0 To hexchars - 1
         Select Case Mid(UCase(hexStr), hexchars - i, 1)
         Case “0"
             lnghexstr += CLng(0 * (16 ^ i))
         Case “1"
             lnghexstr += CLng(1 * (16 ^ i))
         Case “2"
             lnghexstr += CLng(2 * (16 ^ i))
         Case “3"
              lnghexstr      += CLng(3 * (16 ^ i))
          Case “4"
              lnghexstr      += CLng(4 * (16 ^ i))
          Case “5"
              lnghexstr      += CLng(5 * (16 ^ i))
          Case “6"
              lnghexstr      += CLng(6 * (16 ^ i))
          Case “7"
              lnghexstr      += CLng(7 * (16 ^ i))
          Case “8"
              lnghexstr      += CLng(8 * (16 ^ i))
          Case “9"
              lnghexstr      += CLng(9 * (16 ^ i))
          Case “A"
              lnghexstr      += CLng(10 * (16 ^ i))
          Case “B "
              lnghexstr      += CLng(11 * (16 ^ i))
          Case “C"
              lnghexstr      += CLng(12 * (16 ^ i))
          Case “D"
              lnghexstr      += CLng(13 * (16 ^ i))
          Case “E"

             lnghexstr += CLng(14 * (16 ^ i))
         Case “F"
             lnghexstr += CLng(15 * (16 ^ i))
         End Select
     Next i

    ’Display long value for hex string.
    MsgBox(“Long value for text box equals:” & vbCrLf & _
        lnghexstr.ToString)
End Sub




I nh e r it in g Cla sse s
Classes ar e gr eat because t hey package blocks of Visual Basic code for easy
reuse. Class inherit ance m ult iplies t hat cor e benefit of classes by let t ing one class
inherit t he propert ies, m et hods, and event s of anot her class. I nher it ance for
cust om classes is new t o Visual Basic program m ers w it h Visual Basic .NET. This
sect ion begins w it h an overv iew of design issues and keywords for im plem ent ing
class inher it ance. Next I cover a couple of sam ples t hat dem onst rat e t he synt ax
for im plem ent ing inher it ance w it h different key words. At t he sect ion’s close, you
will discover a discussion of ov er loading. This feat ure can m ak e one m et hod or
propert y w it hin a class easily accept m any different t ypes of value input s. I nst ead
of building capabilit ies int o applicat ions by lay ering one class on t op of anot her or
m anually coding a class t o t est m ult iple value t ypes and t hen r espond
appropriat ely t o t he input value t ype, t he Over loads keyword expands t he
capabilit ies of a single class. I cover t he Ov er loads keyw ord in t his sect ion
because of it s r esem blance t o t he Ov er r iding keyword— one of t he k eyw ords for
m anaging inher it ance— and because Ov er loads widens t he capabilit ies of a class
m uch as inherit ance can.

Ov e r vie w of I nh e r it a n ce
I nher it ance is for classes. I t let s one class inher it t he pr opert ies, m et hods, and
ev ent s of anot her class. My discussion of inherit ance focuses on propert ies and
m et hods t o sim plify t he present at ion. ( See t he “ Program m ing Ev ent s” sect ion
lat er in t his chapt er for m or e on m anaging class event s.) When Class B inher it s
Class A, Class B can offer t he sam e m et hods, propert ies, and event s of Class A.
I n addit ion, Class B can offer new pr opert ies and m et hods as well as m odified
versions of t he pr opert ies and m et hods in Class A. Visual Basic dev elopers didn’t
hav e t his capabilit y for cust om st and- alone classes wit h v ersions of Visual Basic
prior t o t he . NET v ersion. Therefore, it is nat ur al t hat y ou need t o lear n som e new
concept s and sy nt ax t o t ak e adv ant age of inherit ance. We can st art our new
inherit ance vocabulary by r efer r ing t o t he inher it ed class as t he base class. The
class t hat inher it s a base class is a derived class.
When one class inher it s fr om anot her class, t he der ived class m ust cont ain a
declarat ion st at ing from which class it inherit s propert ies and m et hods. Visual
Basic .NET uses an I nherit s st at em ent t o m ake t he declarat ion. The I nher it s
st at em ent t akes as it s argum ent t he nam e of t he base class. You can have j ust
one class nam e as t he argum ent for I nher it s. Therefore, a class can inher it fr om
at m ost one ot her class at a t im e. I f t he der iv ed class adds any new m et hods, it
can offer t he m et hods of t he base class along w it h it s ow n new m et hods. I n
addit ion t o offer ing new m et hods, t he deriv ed class can offer m odified
im plem ent at ions of one or m ore m et hods from t he base class. Anot her new
inherit ance t er m in Visual Basic .NET is polym or phism . I t describes t he abilit y of a
der iv ed class t o change t he im plem ent at ion of a base class m em ber, such as a
propert y or a m et hod. An applicat ion can inst ant iat e inst ances for a der ived class
and it s base class. I n t his way, t he applicat ion can inv ok e an unm odified m et hod
from a base class and an updat ed m et hod w it h t he sam e nam e from a der iv ed
class.
I n order for Visual Basic .NET t o m odify a base class m et hod in a der iv ed class,
your class m et hods r equir e special k eyw ords. First , t he base class m ust m ark t he
m et hod nam e w it h t he Over ridable key word, such as in t he following code:
Class MyBaseClass
       Overridable Function One () As Double
             ’Code for returning a value.
       End Function
End Class

I n addit ion t o a keywor d in t he base class, y ou need a cor responding k eyw ord,
Over rides, in t he der ived class. This k eyword m ust be applied t o a m et hod in t he
der iv ed class wit h t he sam e nam e as t he one in t he base class whose
im plem ent at ion y ou want t o change. For exam ple
Class MyDerivedClass
      Inherits MyBaseClass
      Overrides Function One () As Double
            ’New code for returning a value.
      End Function
End Class

As y ou can see, im plem ent ing polym orphism requir es planning. That is, you m ust
m ark t he base class t hat you want ov er r idden in der iv ed classes wit h t he
Over ridable key word. You m ust also sy nchr onize m et hod nam es bet w een t he
base and der iv ed classes. The m et hod nam es w it hin a class— eit her base or
der iv ed— should generally be dist inct . I n general, you should also keep t he
m et hod and propert y nam es dist inct bet w een base and derived classes. Using t he
sam e nam e for a m et hod or a propert y in bot h base and der ived classes has a
special m eaning t hat we will consider short ly .
I n order for a der iv ed class t o refer back t o a m et hod or pr opert y in a base class,
you need t o use t he special My Base k eyw ord. You w ill t ypically use t he My Base
keyw ord wit hin a funct ion in a der iv ed class t hat ov err ides an ident ically nam ed
funct ion in a base class. You can also use t he MyBase k eyw ord t o set and get
propert y values for a base class from a der iv ed class. Then you can use t he
My Base k ey word t o invoke a m et hod w it h t he v alues t hat y ou passed t o t he base
class. For exam ple, MyBase.One() in a deriv ed class invokes t he One m et hod in
t he base class.
The Shadows keyword can apply t o propert ies and m et hods in a der iv ed class.
This k eyw ord essent ially blocks t he availabilit y of ident ically nam ed propert ies
and m et hods in a base class. I n a sense, t he Shadows keyword for a propert y or
m et hod in a derived class cast s a shadow ov er an ident ically nam ed pr opert y or
m et hod in a base class. The Shadows keyword is m ore flex ible and pow er ful t han
t he Ov erridable/ Ov er r ides keywords. For exam ple, t he Ov er ridable/ Ov er r ides
keyw ords apply only t o m et hods im plem ent ed wit h sub procedures or funct ion
procedur es. The Shadows keyw ord apples t o m et hods as well as pr opert ies. I n
addit ion, you can shadow a m et hod in a base class wit h a pr opert y in a der iv ed
class. The Shadows k ey word rem oves t he dependence of a der iv ed class on an
ident ically nam ed obj ect in a base class. This insulat es t he derived class from any
changes t o t he base class t hat could inadvert ent ly cause an er ror in t he der ived
class. The Overr idable/ Ov errides k eywords don’t offer t his prot ect ion for a der ived
class from changes m ade in a base class.
The Ov er loads keyword isn’t st rict ly an inher it ance t opic, but t his k eyw ord
pert ains t o classes, and it s nam e is sim ilar t o Ov er r ides. I n addit ion, using t he
Over loads key word on a funct ion pr ocedur e, sub procedure, or propert y
procedur e can alt er t he behav ior of t he pr ocedure. How ev er , t he Ov erloads
keyw ord can apply t o m et hods or pr opert ies w it hin t he sam e class. A com m on
use of t he Over loads k eyword is t o enable m ult iple v ersions of a funct ion
procedur e t o operat e as one. Each funct ion pr ocedur e in a set of ov erloaded
funct ion pr ocedur es has t he sam e nam e. Howev er , t he argum ent t ypes change
for each funct ion procedur e w it hin a set . Ther efor e, one v ersion of a m et hod can
accept a st ring argum ent , but anot her v ersion can accept a double dat a t ype as
an ar- gum ent . The . NET Fram ework w ill aut om at ically inv ok e t he r ight funct ion
procedur e based on an input ’s dat a t ype! That ’s t he power of t he Over loads
keyw ord.

An I n h e r it in g a n d Ove r r iding Sa m ple

Any Windows applicat ion apply ing class inher it ance w ill cont ain at least t hr ee
unit s of code. You need t wo unit s of code for t he classes: one for t he base class
and a second for t he derived class. A t hird unit of code is necessary t o inst ant iat e
one or m or e classes and inv ok e t he m et hods or m anipulat e t he pr ocedur es in t he
der iv ed class or it s base class. I n a Windows applicat ion, y ou can inst ant iat e
classes and m anipulat e t he inst ances from event procedures for but t ons on a
for m . One or m ore t ext boxes on a form can prov ide v ehicles for users t o specify
input values as argum ent s for m et hods and propert ies.
The sam ple for t his sect ion is a Windows applicat ion t hat includes a for m ( Form 1)
wit h m ult iple but t ons and t ex t box es for users t o m anipulat e. The first sam ple
uses But t on1 along w it h Text Box1 and Text Box 2. Click ing But t on1 launches an
ev ent procedure t hat inst ant iat es a base class, Ar it hm et icClass1, and a der ived
class, Class1. The procedur e m anipulat es t hese class inst ances in various way s
wit h input fr om t he ent r ies in Text Box1 and Tex t Box2. I will det ail t he
m anipulat ions by describing t he But t on1_Click ev ent pr ocedur e aft er discussing
t he code in t he Arit hm et icClass1 and Class1 classes.

                                    N ot e
The sam ple for t his sect ion and t he nex t t wo sect ions
dem onst r at ing inherit ance wit h Visual Basic .NET all use t he
sam e solut ion, I nherit ingSam ple. You can double- click
I nherit ingSam ple.sln in Windows Ex plorer t o open t he
solut ion in Visual St udio. To r un t he applicat ion fr om
Windows Explor er, invoke t he I nherit ingSam ple1.exe file.
The filenam e for t he .ex e file ret ains t he original nam e for
t he solut ion.
Ar it hm et icClass1 is a variat ion of t he st and- alone class in t he Ar it hm et icClass
proj ect discussed in t he “Cr eat ing and Using Class Refer ences” sect ion. This base
class resides in t he I nherit ingSam ple solut ion. The code for t he base class follows.
I t begins by specify ing t wo w r it e- only pr opert ies.
Ar it hm et icClass1 also specifies t wo m et hods— bot h based on funct ion pr ocedur es.
The Add2dbls m et hod follows dir ect ly fr om t he Arit hm et icClass present ed earlier
in t his chapt er; t he m et hod adds t wo values w it h a Double value t ype. A sub
procedur e im plem ent s t his m et hod. The input for t he funct ion pr ocedur e is fr om
t he Writ eOnly pr opert ies, which specify t he double values t o add. A funct ion
procedur e im plem ent s t he second m et hod, Add2dbls2, in Ar it hm et icClass1. Using
argum ent s for t he funct ion pr ocedur e elim inat es t he need t o r ely on propert ies t o
specify t he values t o add. The Ov err idable k ey word appears at t he st art of t he
Add2dbls2 m et hod specificat ion. This m eans t hat anot her class inher it ing
Ar it hm et icClass1 can ov er r ide t he code for t he m et hod t hat appears below.
Public Class ArithmeticClass1
       Private dbl1 As Double
       Private dbl2 As Double

     ’WriteOnly property named dblFirst.
     Public WriteOnly Property dblFirst() As Double
         Set(ByVal dblValue As Double)
             dbl1 = dblValue
         End Set
     End Property

     ’WriteOnly property named dblSecond.
     Public WriteOnly Property dblSecond() As Double
         Set(ByVal dblValue As Double)
             dbl2 = dblValue
         End Set
     End Property

     ’Add dbls.
     Function Add2dbls() As Double
         Return (dbl1 + dbl2)
     End Function

     ’Overridable version of Add dbls.
     Overridable Function Add2dbls2(ByVal MyNum1 As Double, _
           ByVal MyNum2 As Double) As Double
         Add2dbls2 = MyNum1 + MyNum2
     End Function

End Class

The code for Class1 has t hr ee m aj or sect ions; t he full list ing for t he class appears
next . The first sect ion inher it s Ar it hm et icClass1. The I nher it s st at em ent m akes
Class1 a der iv ed class wit h Ar it hm et icClass1 as it s base class. Class1 can
reference all t he propert ies and m et hods of Ar it hm et icClass1 t hr ough t he My Base
keyw ord.
The next sect ion in Class1 adds a new m et hod wit h t he Nt hPower funct ion. The
funct ion com put es t he v alue of t he base v alue t o a power, such as 2 3 equaling 8.
This funct ion accept s ar gum ent s for t he base and power var iable values.
The final sect ion of code in Class1 defines a new im plem ent at ion for t he
Add2dbls2 m et hod init ially specified in t he base class. ( See t he preceding code for
Ar it hm et icClass1.) The Over rides k eyw ord at t he beginning of t he m et hod
specificat ion in Class1 along w it h t he m at ching Over ridable key word for t he sam e
m et hod nam e in Ar it hm et icClass1 perm it s t he overr ide. The new im plem ent at ion
for t he Add2dbls2 m et hod doubles t he value com put ed in t he base class. The
My Base k ey word facilit at es t he r efer ence back t o t he base class. The ar gum ent s
passed t o t he Add2dbls2 m et hod in Class1 t ransfer t o t he base class t hrough t he
argum ent s in t he expression cont aining t he My Base k ey word.
Public Class Class1
       ’Class1 class inherits from ArithmeticClass1.
       Inherits ArithmeticClass1

     ’Added method to complement inherited method
     ’from ArithmeticClass1.
     Public Function NthPower(ByVal base As Double, _
         ByVal power As Double) As Double
         NthPower = (base ^ power)
     End Function

     ’The Add2dbls2 method in Class1 overrides the
     ’overridable Add2dbls2 method in ArithmeticClass1.
     Overrides Function Add2dbls2(ByVal MyNum1 As Double, _
           ByVal MyNum2 As Double) As Double
         ’The following code calls the original method in the base
         ’class, and then modifies the returned value.
         Add2dbls2 = MyBase.Add2dbls2(MyNum1, MyNum2) * 2
     End Function

End Class

The Click event for But t on1, w hich appears nex t , begins by hiding som e cont rols
t hat ar en’t necessary for t his use of t he form . Then t he ev ent pr ocedur e
inst ant iat es Ar it hm et icClass1 as t he arclass1 variable and Class1 as t he c1
variable. The pr ocedur e uses t wo t ext boxes on t he form so t hat users can specify
double values for t he m et hods in t he classes. Because t he t ext box values requir e
conv ersion t o m ak e t hem Double values for t he procedures im plem ent ing t he
m et hods, t he sam ple com put es t he conversion once and st ores t he result s in t w o
variables w it h a Double value specificat ion.
Aft er concluding t he pr eceding pr elim inary st eps, t he event procedur e st art s
com put ing and display ing result s. I nit ially t he procedure passes t he Double
values saved in num 1 and num 2 t o t he propert y pr ocedur es assigning values t o
t he dblFirst and dblSecond propert ies in Arit hm et icClass1. Next t he procedur e
inv okes t he Add2dbls m et hod w it hin t he Arit hm et icClass1 and co- nv ert s t he
out com e t o a st r ing wit h t he ToSt r ing m et hod for display in a m essage box. Aft er
a user clears t he m essage box from t he screen, t he event procedure invok es t he
Nt hPow er m et hod in Class1. Again, t he m essage box argum ent conv ert s t he
num ber t o a st r ing for display . The last pair of MsgBox funct ions in t he ev ent
procedur e inv ok es t he Add2dbls2 m et hod. The first m essage box display s t he
Add2dbls2 m et hod out com e from it s base class im plem ent at ion ( in
Ar it hm et icClass1) . The procedure concludes by inv ok ing t he sam e m et hod from
Class1. This result appearing in t he second m essage box w ill be t w ice as large as
it s pr edecessor . This is because different funct ion pr ocedur es im plem ent t he
m et hod in each class. ( Cont rast t he code for Add2dbls2 in t he t wo pr eceding class
list ings.)
     ’Sample to demonstrate basic inheritance to add a
      ’new method or override an existing one.
     Private Sub Button1_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button1.Click

          ’Hide unnecessary text controls.
          Button2.Visible = False
          Button3.Visible = False

          ’Instantiate objects based on the ArithmeticClass1
          ’and Class1 classes.
          Dim arclass1 As New ArithmeticClass1()
          Dim c1 As New Class1()

          ’Declare num1 and num2 variables and assign values
          ’to the variables based on text box entries.
          Dim num1 As Double
          Dim num2 As Double

          num1 = CDbl(TextBox1.Text)
          num2 = CDbl(TextBox2.Text)

          ’Set properties and invoke the Add2dbls method from
          ’the ArithmeticClass1 class.
          arclass1.dblFirst = num1
          arclass1.dblSecond = num2
          MsgBox(arclass1.Add2dbls.ToString, , _
              “Return from Add2dbls in ArithmeticClass1”)

          ’Invoke the NthPower method in Class1, which is a
          ’new method not in ArithmeticClass1.
          MsgBox(c1.NthPower(num1, num2).ToString, , _
              “Return from NthPower in Class1”)

          ’Invoke the Add2dbls2 method for the ArithmeticClass1
          ’and Class1 classes; the Add2dbls2 method in Class1
          ’overrides the Add2dbls2 method in ArithmeticClass1.
          MsgBox(arclass1.Add2dbls2(num1, num2).ToString, , _
              “Return from Add2dbls2 in ArithmeticClass1”)
          MsgBox(c1.Add2dbls2(num1, num2).ToString, , _
              “Return from Add2dbls2 in Class1”)

     End Sub

Figur e 9- 7 sum m ar izes t he r esult s. On t he left is t he form aft er I ent er ed values
in bot h t ext box es and clicked But t on1. Not ice t hat But t on2 and But t on3 ar en’t
t here; t hat ’s because t he But t on1_Click ev ent procedur e m ade t hem invisible on
t he form by set t ing t heir Visible pr opert y t o False. The four m essage box es on t he
right display t he r esult s in t he order t hat t he But t on1_Click ev ent procedur e
com put es t hem . The capt ion for each m essage box specifies t he source, including
t he m et hod and t he class, for t he displayed r esult . Not ice in part icular t he last
t wo m essage box es. These result s in coordinat ion w it h t he list ing for t he
But t on1_Click ev ent pr ocedur e docum ent and confirm how you can overr ide a
m et hod in a base class wit h a differ ent im plem ent at ion in a der iv ed class.

   Figu re 9 - 7 . By cr e a t in g in st a n ce s for bot h a b ase class an d a de rive d
class, you ca n in vok e m et h od s for b ot h cla sse s, a n d som e of you r m e t h od
      r efe re n ce s in a d e rived cla ss ca n over r ide t h ose in a ba se cla ss.
A Sha dow in g Sa m ple

As indicat ed in t he “ Ov erv iew of I nher it ance” sect ion, shadow ing act s sim ilar ly t o
ov err iding but is m or e flex ible. The sam ple for t his sect ion dem onst rat es t he use
of t he Shadows k eyw or d. You can use t he Shadows keyw ord in a der iv ed class;
doing so doesn’t require any corresponding changes t o a base class. The sam ple
in t he pr eceding sect ion required t he Over ridable k eyw ord in t he base class for
t he Ov errides keyword in t he der iv ed class t o funct ion pr oper ly .
The sam ple in t his sect ion uses t he TypeRef1 class t hat follows as t he base class.
Not ice t hat t he list ing for TypeRef1 includes a propert y procedure for a propert y
nam ed Value. The pr ocedur e includes bot h Get and Set clauses. This class is
sim ilar t o t he TypeRef sam ple present ed ear lier in t his chapt er. The sole
dist inct ion bet w een TypeRef1 and TypeRef is t hat TypeRef1 com m ent ed out t he
New m et hod. Recall t hat in t he prior sam ple using TypeRef, t he New m et hod was
helpful in set t ing an init ial value for a var iable inst ant iat ed on t he class. Howev er,
when y ou use a class as t he base class for an I nherit s st at em ent , t he base class
cannot include a m et hod nam ed New. The inabilit y t o specify a New m et hod
wit hin t he class isn’t m aj or because an applicat ion can assign a value t o a
variable based on t he class im m ediat ely aft er inst ant iat ing t he v ar iable.
Public Class TypeRef1
       Private intLocal

     ’Intialize Value to myInput -- not permissible in
     ’inherited class.
     ’Public Sub New(ByVal myInput As Integer)
     ’    Dim Value As Integer = myInput
     ’    MsgBox(Value.ToString, , “in new”)
     ’End Sub

     ’Read/Write property named Value.
     Public Property Value() As Integer
         Get
             Return intLocal
         End Get
         Set(ByVal Value As Integer)
             intLocal = Value
         End Set
     End Property

End Class

The shadow ing sam ple also relies on a second sam ple nam ed Class2. This class
inherit s TypeRef1, so Class2 is a der iv ed class wit h TypeRef1 as it s base class.
Because TypeRef1 has j ust one pr opert y, Class2 m ust have a m em ber by t he
sam e nam e if it is t o shadow t he pr opert y procedur e in TypeRef1. I specifically
used t he t erm m em ber. This leav es open t he possibilit y of t he shadow ing elem ent
being eit her a propert y or a m et hod. The only r equirem ent is t hat t he shadow ing
elem ent hav e t he sam e nam e as t he m em ber t hat it shadows. Alt hough t he
follow ing list ing for Class2 dem onst rat es t he use of t he Shadows k eyw ord, t he
use of t his keyw ord is opt ional for im plem ent ing shadow ing. As y ou can see from
t he follow ing list ing, t he shadow ing v ersion of t he pr opert y procedure for Value in
Ty peRef1 adds 2 t o t he input . The or iginal v ersion of t he propert y pr ocedur e for
t he Value propert y in Ty peRef m erely echoes t he input .
Public Class Class2
      ’Class2 inherits from TypeRef1
      Inherits TypeRef1

     Private intLocal

     ’Read/Write property named Value in Class2
     ’shadows property with the same name in TypeRef1.
     Public Shadows Property Value() As Integer
         Get
             Return intLocal
         End Get
         ’New version adds 2 to initial input.
         Set(ByVal Value As Integer)
             intLocal = Value + 2
         End Set
     End Property

End Class

Click ing But t on2 on For m 1 in t he I nherit ingSam ple solut ion launches an ev ent
procedur e, w hich appears next . The pr ocedure uses But t on2 and Text Box1 ( along
wit h it s label) . Therefore, t he event procedure st art s by hiding t he ot her cont rols
on t he form . Next t he procedur e conv ert s and copies t he cont ent s of Text Box1 t o
num 1, which t he pr ocedur e declares as an I nt eger variable. This value t ype
specificat ion for num 1 is consist ent w it h t he Value pr opert y in TypeRef1 and
Class2. Aft er st oring t he conv ert ed t ext box ent r y in a v ar iable for t he event
procedur e, t he procedur e assigns t he value saved in num 1 t o t he Value propert y
in TypeRef1 and Class2. Finally, a pair of MsgBox funct ions echoes t he quant it y in
t he propert y.
      ’Sample to demonstrate shadowing with inheritance.
      Private Sub Button2_Click(ByVal sender As System.Object, _
             ByVal e As System.EventArgs) Handles Button2.Click

          ’Hide unnecessary text controls.
          TextBox2.Visible = False
          Label2.Visible = False
          Button1.Visible = False
          Button3.Visible = False
           ’Instantiate objects based on the TypeRef1
           ’and Class2 classes.
           Dim trclass1 As New TypeRef1()
           Dim c2 As New Class2()

           ’Declare num1 variable and assign a value
           ’to the variable based on the text box’s entry.
           Dim num1 As Integer

           num1 = CInt(TextBox1.Text)

           trclass1.Value = num1
           c2.Value = num1

           MsgBox(trclass1.Value.ToString, , _
               “Return from Value property in TypeRef1”)
           MsgBox(c2.Value.ToString, , _
               “Return from Value property in Class2”)

     End Sub

Figur e 9- 8 shows t he shadow ing sam ple. On t he left panel, y ou see t he t ext box
and but t on for launching t he event procedure. Not ice t hat t he t ext box cont ains
t he value 3. On t he r ight side, y ou see t he t w o m essage box es cont aining t he
echoed Value pr opert ies fr om TypeRef1 and Class2. Alt hough t he input t o bot h
propert ies was t he sam e, t he out put is differ ent because t he one expression in
Class2 is dist inct from it s count erpart for a shadowed pr opert y in TypeRef1.

   Figu r e 9 - 8 . Sh ad ow in g m ak e s it e a sie r for a de rive d cla ss t o re t u r n a
   d iffer e n t r esu lt t h a n a pr op er t y w it h t h e sam e n a m e in a ba se cla ss.




An Ov e r loa din g Sa m ple

Bot h ov err iding and shadow ing are about doing m or e t hings w it h t he sam e
m et hods and pr opert ies. The Ov er loads k eyw or d is one m ore exam ple of a
keyw ord t hat sim plifies how y ou can do m or e w it h t he code in y our sam ples. I n
essence, it allows y ou t o const ruct a set of pr ocedur es all of which hav e t he sam e
nam e but w it h differ ent argum ent t ype specificat ions. When a user invokes a
m et hod based on t he set of procedures, t he .NET Fram ew ork aut om at ically
det ect s t he specific pr ocedur e t hat m at ches t he input dat a t y pe. You don’t hav e
t o use t he Ov erloads k eyword in an inherit ance cont ext , but it can work wit h
inherit ance. For sim plicit y, t his sect ion dem onst rat es t he use of t he Ov erloads
keyw ord wit hout inv olv ing inherit ance.

                                     N ot e
You can also achieve overloading wit hout t he Ov erloads
key word. Just m ak e sure all t he pr ocedure nam es are
ident ical, wit h differ ent value t ype specificat ions for t he
argum ent s in each m em ber wit hin t he set of pr ocedures.
However, if you use t he Overloads keyword for at least one
m em ber in t he set , you m ust use it for all m em bers.
The Class3 list ing shows a sim ple over loading sam ple. The class cont ains t wo
inst ances of t he TenPer cent OfI t funct ion procedur e. These inst ances collect iv ely
im plem ent t he TenPercent OfI t m et hod for Class3. I f a user ent ers an ar gum ent
wit h a Double v alue t ype, such as 55.5, in t he TenPercent OfI t m et hod, Class3
responds by inv ok ing t he first funct ion pr ocedur e. This m ight happen if t he user
inv okes t he m et hod from a dat abase w it h a colum n of Double values. On t he
ot her hand, when t he input for t he TenPercent OfI t funct ion is a st ring, such as
55.5, Class3 aut om at ically inv ok es t he second funct ion procedure. This m ight
happen if an applicat ion passes a value dir ect ly from a t ext box t o t he class
m et hod. By using t he Over loads k eyw ord in fr ont of bot h versions of t he funct ion,
t he dev eloper can leav e it t o t he .NET Fram ework t o figur e out wit h w hich specific
funct ion pr ocedur e t o im plem ent t he m et hod. As m or e pot ent ial dat a sources
becom e available, it is easy t o add a new copy of t he funct ion pr ocedur e wit h
different v alue t ype declarat ions for t he argum ent s.
Public Class Class3
      Overloads Function TenPercentOfIt(ByVal It As Double) As Double
           Return (It * 0.1)
      End Function

    Overloads Function TenPercentOfIt(ByVal It As String) As Double
        Return (CDbl(It) * 0.1)
    End Function
End Class

The follow ing Click event procedure for But t on3 dem onst rat es a t est of t he
ov erloading feat ure im plem ent ed in Class3. Aft er hiding t he unnecessary cont r ols
on t he form , t he applicat ion inst ant iat es c3 as an inst ance of Class3. Next it
assigns a Double value of 55.5 t o num 1. The final pair of MsgBox funct ions
inv okes t he TenPercent OfI t m et hod in Class3 w it h t he num 1 Double value t ype or
a St r ing value t ype based on t he cont ent s of Text Box1. Because t he r et ur n fr om
t he m et hod is a Double value, t he argum ent for t he MsgBox funct ions inv ok es t he
ToSt r ing m et hod on t he r et urn value. The im port ant point t o not e is t hat ev en
t hough t he t w o MsgBox funct ions invoke t he TenPercent OfI t m et hod w it h
different v alue t ypes, t hey bot h invok e exact ly t he sam e m et hod wit h exact ly t he
sam e synt ax.
‘Sample to demonstrate overloading within a class.
Private Sub Button3_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button3.Click

     ’Hide unnecessary text controls.
     TextBox2.Visible = False
     Label2.Visible = False
     Button1.Visible = False
     Button2.Visible = False

     ’Instantiate Class3 with overloaded functions and declare
     ’a variable with a Double type for one of the functions.
     Dim c3 As New Class3()
     Dim num1 As Double

     ’Assign a value to the Double variable type and
     ’invoke one version of the overloaded function.
     num1 = 55.5
     MsgBox(c3.TenPercentOfIt(num1).ToString, , _
         “Return based on a double input”)

     ’Invoke another version of the overloaded function with
     ’string input instead of numerical input.
     MsgBox(c3.TenPercentOfIt(TextBox1.Text).ToString, , _
         “Return based on a string input”)

End Sub

Figur e 9- 9 confirm s t hat you can obt ain ident ical result s from t he TenPercent OfI t
ov erloaded set of funct ions based on t w o differ ent input value t ypes. The form on
t he left shows 55.5 in a t ex t box. This t ext box cont ains a St r ing value. The t w o
m essage box es on t he r ight show ident ical ret ur n values. How ev er , t heir capt ions
confirm t hat t hey have different input value t ypes, and all our code did t o get t his
result was t o use t he Over loads k eyw ord. Som et im es Microsoft can m ake life so
sweet !

Figu re 9 - 9 . Ove rloa din g au t om at ica lly m a t ch e s t h e p roce du re in vok e d t o
t h e d at a t yp e of t h e ar gu m en t in a st a t e m e n t ca llin g a se t of ove rloa de d
                                         p roce du re s.




Pr ogr a m m in g Even t s
An ev ent is a not ificat ion t hat som et hing happened. As Visual Basic program m ers,
you are well awar e of event s from built - in obj ect s, such as form s and but t ons.
Many int erm ediat e and advanced program m ers r egular ly creat e cust om classes
t hat generat e cust om event s wit h pr ior v ersions of Visual Basic. Adding ev ent s t o
cust om classes allows obj ect s based on t he classes t o conv ey inform at ion back t o
t he applicat ions t hat inst ant iat e t he obj ect s.
Visual Basic .NET ret ains t he ev ent funct ionalit y fr om earlier v ersions w hile it
adds new capabilit ies as well, relat ed t o defining cust om event handlers and
wor k ing w it h new sources for ev ent s. This sect ion r ev iews t he basics of ev ent
program m ing t o prov ide a st andard background for m or e adv anced t opics,
including t he abilit y t o dynam ically define ev ent handlers and new com ponent s
t hat can raise ev ent s.

Ev e nt Pr ogr a m m in g Con ce pt s

Ev en when work ing w it h built - in ev ent s for form s and t heir cont rols, it helps t o
hav e a basic underst anding of ev ent program m ing concept s, but a k nowledge of
t his t opic is essent ial w hen you dev elop event s for cust om classes. Happily, a few
core concept s t hat ar e easy t o grasp can enable you t o declar e and m anage
cust om ev ent s.
Ev ent s hav e a source or a sender. This source is t he elem ent t hat sends out t he
not ificat ion t hat an event happened. A class t hat you cr eat e can be a source. A
for m class can be a source. For exam ple, Visual Basic raises t he Load event w hen
it opens a form inst ance. Sim ilarly, when a user clicks a but t on on a for m
inst ance, t his raises t he Click event for t he but t on. For a source t o raise an ev ent ,
t wo t hings m ust happen. First , t he ev ent m ust be declared for t he obj ect . You can
declare an Ev ent st at em ent . Second, som e code inside t he class for t he obj ect
inst ance m ust inv ok e t he RaiseEvent st at em ent . The RaiseEvent st at em ent
t riggers an ev ent declared wit h t he Ev ent st at em ent . You can raise an ev ent only
from t he class in w hich it occurs. Ther efor e, a but t on cannot raise a Load ev ent
for a form on which it r esides. Sim ilarly , a der iv ed class cannot use t he Raise-
Ev ent st at em ent t o t rigger an ev ent declar ed in it s base class.
Ev ent handlers pr ocess an ev ent . Just because a class inst ance raises an ev ent
doesn’t m ean t hat an applicat ion has t o acknowledge t he ev ent . Clicking a but t on
befor e y ou add a sub pr ocedur e t o process t he click has no effect . The sub
procedur e is an ev ent handler. Ev ent handlers allow applicat ions t o r espond t o
ev ent s r aised by class inst ances. Visual Basic can aut om at ically cr eat e em pt y
ev ent handlers for t he Windows For m s and t heir cont rols. These em pt y ev ent
handlers ar e called st ubs. A st ub includes t he sub procedure declarat ion w it h a
nam e for t he procedur e, a list of argum ent s, and a t erm inat ing st at em ent for t he
procedur e ( nam ely, End Sub) . St ubs also include a Handles clause t hat associat es
t hem w it h a class inst ance and an ev ent nam e. You can det erm ine how your
applicat ion r esponds t o an ev ent by placing your own code inside t he sub
procedur e.
When y ou w rit e ev ent handlers for cust om classes, y ou m ay need t o cr eat e y our
own st ub. I f y ou use t he Wit hEv ent s k eyw ord when y ou inst ant iat e an obj ect
based on a class, y ou can use t he Visual St udio dev elopm ent envir onm ent t o
creat e a st ub for y ou aut om at ically. When using t he Wit hEvent s k eyw or d, you
m ust inst ant iat e your obj ect at t he m odule lev el. Wit hout t he Wit hEv ent s
keyw ord, ev ent s don’t propagat e from a class t o an obj ect inst ance based on it .
Est ablishing an associat ion bet w een an event handler and an ev ent w it h t he
Wit hEv ent s k eyw ord requir es you t o specify t he ev ent handler at design t im e.
The AddHandler and Rem ov eHandler st at em ent s allow you t o dy nam ically add
and rem ov e a handler for an event at r un t im e. You can also use t hese
st at em ent s at design t im e. Wit h t hese t w o st at em ent s, y ou don’t have t o
inst ant iat e an obj ect using t he Wit hEv ent s keyw ord in order t o process ev ent s
raised by t he obj ect . I n t ur n, t his m eans t hat y ou can inst ant iat e w it hin a
procedur e or at t he m odule lev el. Recall t hat t he Wit hEv ent s k eyw ord r equires
inst ant iat ion at t he m odule lev el. When using t he AddHandler st at em ent t o
associat e an event w it h an ev ent handler, y ou m ust wr it e y our own st ub for t he
ev ent handler. I will dem onst rat e how t o do t his in a sam ple t hat illust r at es t he
use of t he AddHandler st at em ent .
Usin g Bu ilt - I n For m Ev e n t s

Ther e ar e a couple of w ays of m anaging built - in ev ent s wit h Windows Form s and
t heir cont r ols fr om t he Windows For m s Designer. Double- clicking a for m ’s capt ion
in t he Windows Form s Designer opens t he st ub for t he form ’s default ev ent , t he
Load ev ent , in t he Code Edit or. This sam e t echnique works for t he cont r ols on a
for m . For ex am ple, double- click ing a but t on on a form opens t he st ub for t he
but t on’s default ev ent , a Click ev ent . Aft er adding one or m or e cont r ols on a
for m , y ou can select any event for any cont r ol in t he Code Edit or. Choose t he
cont r ol nam e from t he Class Nam e dr op- dow n list at t he upper left of t he Code
Edit or , and choose t he ev ent nam e fr om t he Met hod Nam e list at t he r ight . Aft er
you click an ev ent for t he cont r ol, a st ub for t he ev ent pr ocedur e appears
aut om at ically. To display a nondefault event for t he form , select ( Base Class
Ev ent s) from t he Class Nam e list and t hen choose a desir ed ev ent fr om t he
Met hod Nam e list .
I f you search t hrough t he event s for a form or any of t he cont r ols on a form , you
will quickly discover an exceedingly large array of ev ent s. Alt hough t he large
num ber of ev ent s is useful for fine- grained cont rol ov er t he operat ion of an
applicat ion, it m ay be difficult for som e program m ers t o discern t he order of t he
ev ent s so t hey can k now which one t o use. The follow ing excerpt fr om t he Code
Edit or for Form 4 in t he Ev ent sSam ples solut ion dem onst rat es a st rat er gy for
t racking ev ent s. Wit hin each ev ent pr ocedur e is a MsgBox funct ion indicat ing
which ev ent generat ed t he cur rent m essage box in an applicat ion. For exam ple,
t he m essage box for t he form Load ev ent fir es befor e Form 4 is display ed. When
you click t he form ’s Close but t on, y ou w ill not ice t hat t he Closing ev ent fir es pr ior
t o t he Closed ev ent . See t he follow ing not e for det ailed inst ruct ions on m aking
Form 4 t he st art up obj ect for t he Ev ent sSam ples solut ion.

                                      N ot e
A Windows applicat ion st art s by default wit h For m 1, which is
t he obj ect t hat Visual St udio .NET m akes aft er opening a
Windows applicat ion for design. By default , t he Windows
applicat ion opens t o t his obj ect when you run t he solut ion.
However, you can choose anot her obj ect for a Windows
applicat ion t o open when it st art s t o r un. Right - click t he
solut ion’s nam e in Solut ion Explor er , and choose Propert ies
t o open t he Propert y Pages dialog box for t he solut ion. Use
t he St art up Obj ect drop- dow n list t o select anot her obj ect .
For ex am ple, select ing For m 4 will cause t his form t o open
init ially when a user chooses t o run t he solut ion.
Ev ent s som et im es fire so quick ly t hat m essage boxes can pile up and m ake
discover ing t heir order confusing. I n cases lik e t his, y ou can som et im es set a
propert y for an obj ect on t he form — and t hus change it s appearance— t o help
indicat e t he order of ev ent s. The procedures for t he MouseEnt er , MouseHov er,
and MouseLeav e ev ent s fr om But t on1 dem onst rat e t his appr oach. These ev ent
procedur es change t he Back Color pr opert y for But t on1. I nit ially posit ioning t he
m ouse over But t on1 changes t he BackColor pr opert y from it s default set t ing t o
Syst em .Drawing.Color .Cyan. Because Visual St udio aut om at ically cr eat es a
reference t o t he Syst em .Draw ing nam espace w hen it init ializes a Windows
applicat ion, y ou can abbreviat e t he set t ing t o Color. Cyan. Leav ing t he m ouse
ov er a but t on event ually invok es t he MouseHov er ev ent , which changes t he
Back Color set t ing t o Sy st em .Draw ing.Color.Red. Rem ov ing t he m ouse from ov er
t he but t on rest or es t he default BackColor set t ing of
Syst em .Drawing.Syst em Colors.Cont rol. Clicking But t on1 displays a m essage box
and shift s t he focus fr om For m 4 t o t he m essage box. This But t on1_Click ev ent is
ort hogonal t o t he MouseEnt er and MouseHover ev ent s in t hat click ing t he but t on
can int errupt t he t r ansit ion fr om t he MouseEnt er event t o t he MouseHover event .
Private Sub Form4_Load(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load
      MsgBox(“Just before I load.”)
End Sub

Private Sub Form4_Closing(ByVal sender As Object, _
    ByVal e As System.ComponentModel.CancelEventArgs) _
    Handles MyBase.Closing
    MsgBox(“From Closing event.”)
End Sub

Private Sub Form4_Closed(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles MyBase.Closed
    MsgBox(“From Closed event.”)
End Sub

Private Sub Button1_MouseEnter(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Button1.MouseEnter
    Me.Button1.BackColor = System.Drawing.Color.Cyan
End Sub

Private Sub Button1_MouseHover(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Button1.MouseHover
    Me.Button1.BackColor = System.Drawing.Color.Red
End Sub

Private Sub Button1_MouseLeave(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Button1.MouseLeave
    Me.Button1.BackColor = System.Drawing.SystemColors.Control
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    MsgBox(“You clicked Button1”)
End Sub

Befor e proceeding t o a second sam ple, it m ay be useful t o r ev iew t he synt ax for
an ev ent pr ocedure. Not ice t hat t hey ar e sub pr ocedur es m eant for operat ion in
t he cur rent m odule, as specified by t he use of t he Privat e keyw ord. Pr ivat e m arks
t he ev ent procedur e for exclusive use in t he cur rent m odule. The argum ent s list
can offer you a way of changing t he operat ion of t he ev ent pr ocedur e. The nex t
sam ple dem onst rat es t he use of an ev ent argum ent t o cont r ol t he behavior of t he
Closing event . Aft er t he argum ent list , t he Handles clause specifies t he obj ect and
ev ent t hat t he sub procedur e handles. You cont rol t he operat ion of t he ev ent
procedur e by placing cust om code bet ween t he Sub and End Sub st at em ent s.
The next select ion of ev ent pr ocedur es shows a pair of procedures for cont rolling
how a user can close a form . When a user chooses t o close a form by clicking t he
for m ’s Close but t on, t he applicat ion fir es t he Closing ev ent . This event occurs
befor e t he form closes. By set t ing t he Cancel ev ent argum ent t o Tr ue in t he
Closing event , you can block t he Close ev ent fr om occurr ing ( nam ely , t he form
will rem ain open) . The default value for t he Cancel ev ent argum ent is False. You
can use t his feat ur e t o perform ot her act ions j ust before closing a for m . For
exam ple, y ou can display a m essage blocking t he operat ion of t he form ’s Close
but t on and inst ruct ing t he user t o click a but t on t hat launches t he ot her act ions
you want done befor e invok ing t he form ’s Close m et hod. Because t he Close
m et hod raises t he Closing event , y ou m ust const ruct t he form ’s Closing ev ent
procedur e t o opt ionally by pass set t ing t he Cancel argum ent t o Tr ue.
The follow ing code excerpt for For m 5 dem onst r at es how t o disable a form ’s Close
but t on and redirect t he user t o a but t on on t he for m . The solut ion uses t wo
ev ent s. First t he Form 5_Closing event procedure blocks t he Close ev ent from
occurr ing by set t ing t he Cancel ev ent argum ent t o bolDisableClose. The m odule-
level declarat ion for bolDisableClose set s t he variable’s default value t o Tr ue. The
I f…Then…Else st at em ent in t he pr ocedur e displays a m essage box dir ect ing t he
user t o click But t on1 t o close t he form . The Click ev ent pr ocedur e for But t on1
set s bolDisableClose t o False befor e inv ok ing t he Close m et hod for t he Me
keyw ord t hat r efers back t o t he curr ent form , w hich is Form 5 in t his case. The
inv ocat ion of t he Close m et hod, in t ur n, launches t he Form 5_Closing event
procedur e, but t his t im e t he pr ocedur e t ak es a different pat h t hr ough it s
I f…Then…Else st at em ent because of t he new value for t he bolDisableClose
variable.
‘bolDisableClose controls Cancel argument.
Dim bolDisableClose As Boolean = True

‘Conditionally block close of form.
Private Sub Form5_Closing(ByVal sender As Object, _
    ByVal e As System.ComponentModel.CancelEventArgs) _
    Handles MyBase.Closing
    If bolDisableClose Then
         e.Cancel = bolDisableClose
         MsgBox(“Click Button1 to close form.", , _
         “After clicking Close button”)
    Else
         MsgBox(“From form’s Closing event.", , _
         “After clicking Button1”)
    End If
End Sub

‘Enable form close by setting bolDisableClose to False.
Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    ’Perform any other necessary actions before closing Form5.
    bolDisableClose = False
    Me.Close()
End Sub



Pr oce ssin g Eve n t s Using t h e W it hEv e n t s Ke yw or d

The ev ent processing t echniques for t his sam ple and t he next t w o all em anat e
from Form 1 in t he Event sSam ple solut ion. Figur e 9- 10 shows t his form t wo
different way s. At left is t he form as it looks in t he Windows Form Designer— in
design v iew. At r ight is t he form as it appears when y ou r un t he
Ev ent sSam ple.ex e file. The differences bet w een t he t wo v iews of t he form ar e t he
result of t he Form 1_Load ev ent pr ocedur e. ( See t he follow ing sam ple.) This
procedur e adds t ext t o som e cont rols and clears it from ot her cont rols. I n
addit ion, it form at s t he alignm ent for t he label and t ext cont r ols as well as resizes
t he default Widt h propert y set t ing for t he but t on cont rols. This t ransfor m at ion
dem onst rat es a use for t he form Load event t hat m akes it easy t o spot changes
t o t he default set t ings for t he cont r ols on a form . I f you need t o duplicat e form
set t ings acr oss m ult iple form s or syst em at ically change set t ings across m ult iple
for m s, t his k ind of procedure can prove especially conv enient .
Figu r e 9 - 1 0 . Usin g a form Loa d e ven t pr oce d u r e t o d ocu m e n t you r form a t
 se t t in gs for a for m ca n h elp in docu m en t ing t h ose se t t in gs an d ap plyin g
    t h ose se t t in gs in a u n ifor m w a y t o m u lt iple form s in a n a pplica t ion .




Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
    ’Set selected properties for form controls at load time.

     ’Set Text and Width properties for Button1.
     Button1.Text = “Add"
     Button1.Width = 90

     ’Set TextAlign property for text boxes.
     TextBox1.TextAlign = HorizontalAlignment.Right
     TextBox2.TextAlign = HorizontalAlignment.Right
     TextBox3.TextAlign = HorizontalAlignment.Right

     ’Set Text property for labels.
     TextBox1.Text = “"
     TextBox2.Text = “"
     TextBox3.Text = “"

     ’Set TextAlign align property for labels.
     Label1.TextAlign = ContentAlignment.MiddleRight
     Label2.TextAlign = ContentAlignment.MiddleRight
     Label3.TextAlign = ContentAlignment.MiddleRight

     ’Set Text property for text boxes.
     Label1.Text = “Byte1"
     Label2.Text = “Byte2"
     Label3.Text = “Sum"

     ’Set Text and Width properties for Button2.
     Button2.Text = “Open Form2"
     Button2.Width = 90

     ’Set Text and Width properties for Button3.
     Button3.Text = “Open Form3"
     Button3.Width = 90

     ’Set Text and Width properties for Button4.
     Button4.Text = “Close App"
     Button4.Width = 90

End Sub
The for m at right in Figur e 9- 10 per m it s a user t o ent er t wo Byt e value t ype
quant it ies in t he Byt e1 and Byt e2 t ext box es. When a user clicks t he Add but t on,
t he form r et urns t he t ot al of t he t w o quant it ies in t he Sum t ext box . I f t he sum
happens t o exceed 255, which is t he m ax im um legit im at e Byt e value, t he
applicat ion displays a m essage box w it h a r em inder of t he pr oblem . Because t he
applicat ion com put es t he sum as a Decim al value t ype, ret ur n values great er t han
t he m ax im um don’t generat e a run- t im e er ror. Howev er, you can raise an ev ent
t hat ident ifies sum s great er t han 255. I f a user ent ers a value gr eat er t han 255 in
eit her t he Byt e1 or Byt e2 t ext box, Visual Basic raises an error because t he Add
but t on’s Click ev ent pr ocedur e uses t he CByt e funct ion t o conv ert t he t ext box
values t o Byt e dat a t ypes.
Befor e rev iew ing t he code behind Form 1 t hat m anages t he operat ion of t he form ,
it w ill be useful t o exam ine t he code list ing for t he Byt eArit hm et ic class. Form 1
relies on t he class t o save t he values in t he t wo input t ext box es, com put e t he
sum , and raise t he ev ent . The class list ing includes an ev ent declarat ion, a Privat e
st at em ent for declaring t wo int ernal var iables, t wo propert y pr ocedur es, and a
funct ion pr ocedur e. The Public accessibilit y qualifier for t he event declar at ion at
t he t op of t he list ing m akes t he ev ent available t hr oughout t he Ev ent sSam ple
solut ion assem bly. I f By t eArit hm et ic ex ist ed as a st and- alone class proj ect wit h a
.dll ext ension, t he Public declarat ion would per m it t he accessibilit y of t he event in
ot her pr oj ect s t hat r efer ence t he .dll file.
The propert y pr ocedur es nam ed Byt e1 and Byt e2 can accept conv ert ed dat a fr om
t ext boxes on Form 1. The class represent s t hese pr opert y set t ings int er nally w it h
t he byt 1 and byt 2 var iables, which ar e declared direct ly below t he ev ent
declarat ion. A funct ion procedur e, Add2byt e, in Byt eArit hm et ic com put es t he sum
and condit ionally raises an er ror. This procedure com put es t he sum of t he t wo
t ypes as a Decim al value t ype, w hich it saves in t he m ysum var iable. This design
feat ur e av oids t he pot ent ial of a r un- t im e er ror fr om a sum t hat exceeds t he Byt e
value lim it . How ev er, Add2byt e also checks for sum s t hat exceed 255. When it
finds a sum t hat exceeds t he m ax im um Byt e value, it raises t he TooHigh ev ent
and ret ur ns as an event argum ent t he m ysum v ariable value. The Add2byt e
procedur e list ing concludes wit h a Ret ur n st at em ent t hat passes back t he value of
m ysum t o t he procedure t hat invoked t he Byt eAr it hm et ic class inst ance.
Public Class ByteArithmetic
       ’You need to declare an event before you can raise it.
       Public Event TooHigh(ByVal ReturnValue As Decimal)

     ’Local variables for property values.
     Private byt1, byt2 As Decimal

     ’Property procedures for Byte1 and Byte2.
     Public Property Byte1() As Byte
         Get
             Return byt1
         End Get
         Set(ByVal Value As Byte)
             byt1 = Value
         End Set
     End Property

     Public Property Byte2() As Byte
         Get
             Return byt2
         End Get
         Set(ByVal Value As Byte)
             byt2 = Value
         End Set
     End Property
     ’Function procedure for the Add2byte method.
     Function Add2byte() As Decimal
         Dim mysum As Decimal

           ’Compute mysum.
           mysum = byt1 + byt2

           ’Raise event if sum is too high.
           If mysum > 255 Then RaiseEvent TooHigh(mysum)

           Return mysum

     End Function

End Class

The next code excerpt shows t he code behind Form 1 t hat works w it h t he
Byt eAr it hm et ic class. The list ing st art s wit h a declarat ion of an inst ance nam ed ba
for t he Byt eArit hm et ic class. There ar e t w o especially im port ant feat ur es of t his
declarat ion. First , t he declarat ion includes t he Wit hEv ent s k eyw ord. This allows
Form 1 t o process ev ent s raised by ba. Second, t he declarat ion occurs at t he
m odule lev el. This is m andat ory when y ou use t he Wit hEvent s k eyw ord in t he
declarat ion for a class inst ance.
I generat ed t he st ub for t he But t on1_Click ev ent procedure by double- clicking t he
cont r ol in t he Windows Form s Designer. The ev ent pr ocedur e is generat ed by t he
double click on t he cont rol because Click is t he but t on’s default ev ent . Wit hin t he
Click event are t wo blocks of code. First t he procedur e conv ert s t he t ex t box
ent r ies wit h t he CBy t e funct ion t o Byt e value t y pes from t heir nat iv e St ring value
t ypes. Second t he pr ocedur e inv ok es t he Add2byt e m et hod for t he ba class
inst ance and st or es t he ret ur n value as a st r ing in Text Box 3.
The second procedur e is t he event handler for t he TooHigh event from t he ba
class inst ance. I n t he Code Edit or for Form 1, y ou can cr eat e t he st ub for t he
ev ent procedure aut om at ically by choosing ba in t he Class Nam e box and click ing
TooHigh in t he Met hod Nam e box t o it s r ight . Aft er Visual St udio cr eat ed t he st ub,
I had t o add j ust one line of code, which pr esent s a m essage box r em inding t he
user t hat t he sum is t oo large for a legit im at e Byt e value. The m essage box also
cont ains t he value r et urned as t he sum .
‘WithEvents keyword must apply to module-level declaration;
‘the keyword permits events to pass from event source (ByteArithmetic
).
       Private WithEvents ba As New ByteArithmetic()

     Private Sub Button1_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button1.Click

           ’Copy converted text box entries to Byte1 and
           ’Byte2 properties in ByteArithmetic class.
           ba.Byte1 = CByte(TextBox1.Text)
           ba.Byte2 = CByte(TextBox2.Text)

           ’Display result of addition in TextBox3.
           TextBox3.Text = (ba.Add2byte).ToString()

     End Sub


     ’Handles clause in event sub stub requires a WithEvents keyword
     ’in variable declaration for event source (ByteArithmetic).
     Private Sub ba_TooHigh(ByVal ReturnValue _
           As Decimal) Handles ba.TooHigh

        ’Display event message.
        MsgBox(“Sum of “ & ReturnValue & “
too large for byte value.”)

     End Sub

Figur e 9- 11 shows t he out com e of t ry ing t o add 4 and 252 w it h t he applicat ion
det ailed in t he preceding t wo code segm ent s. Each quant it y alone is a legit im at e
Byt e v alue. However, t heir sum exceeds t he m axim um Byt e value. Ther efor e, t he
applicat ion displays t he m essage box shown at t he left of Figure 9- 11 befor e
populat ing Text Box3 w it h t he r et urn value from t he Byt eAr it hm et ic inst ance.
Form 1 appears on t he r ight side of Figur e 9- 11, wit h t he t wo input values and
t heir sum . To proper ly close t he solut ion, a user m ust click t he Close App but t on.

    Figu r e 9 - 1 1 . You can u se a cu st om e ven t t o disp la y a m e ssa ge b ox .




Pr oce ssin g Eve n t s w it h t h e AddH a n dle r St a t e m e nt

Below t he t hird t ext box in Figur e 9- 11 is t he Open Form 2 but t on. Click ing t his
but t on opens a second form t hat dem onst rat es how t o use t he AddHandler
st at em ent t o process a raised event . Form 2 has j ust t wo but t ons. That ’s because
t his form uses t he t ext boxes on Form 1 t o display input and out put from t he
inst ance of Byt eArit hm et ic t hat it declares. Ther efor e, anot her benefit of t his
sam ple is t hat it r ev eals how t o pass v alues back and fort h bet ween t w o form s.
The only way t hat t he applicat ion will open For m 2 is by a click t o t he Open Form 2
but t on on Form 1. The applicat ion’s logic requir es t hat t her e be num eric ent ries in
t he Byt e1 and Byt e2 t ex t box es befor e t he click. Failing t o populat e t he t ext
boxes w it h appropr iat e values befor e t he click will generat e a r un- t im e err or . The
Click event procedur e for But t on2 on Form 1 follows. Not ice t hat t he But t on2_Click
ev ent procedure com m ences by inst ant iat ing an inst ance of Form 2 and
referencing it wit h t he fr m Form 2 v ariable. Wit h t he frm Form 2 var iable, t he event
procedur e can t hen access elem ent s in t he code behind Form 2. As a subsequent
list ing shows, t wo of t hese elem ent s ar e var iables nam ed frm 2byt e1 and
frm 2byt e2. The assignm ent st at em ent s in t he Click event procedur e dem onst rat e
t he synt ax for copying convert ed t ext box values from one form ( For m 1) t o
variables in t he m odule behind anot her form ( Form 2) . The event procedur e
concludes by showing Form 2 and hiding Form 1.
Private Sub Button2_Click(ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button2.Click

     ’Instantiate a new instance of Form2 class.
     Dim frmForm2 As New Form2()

     ’Populate variables in module behind Form2 with
     ’Text property settings of text boxes in Form1.
     frmForm2.frm2byte1 = CByte(TextBox1.Text)
     frmForm2.frm2byte2 = CByte(TextBox2.Text)

     ’Show Form2 in a modeless window and
     ’hide currently open form (Form1).
     frmForm2.Show()
     Me.Hide()

End Sub

For ease in grasping how t he program m ing elem ent s behind Form 2 work am ong
t hem selves and int erplay w it h Form 1, t he follow ing list ing includes t he whole
m odule behind Form 2. The paragraphs aft er t he list ing select ively highlight
different aspect s of t he code.
Public Class Form2
     Inherits System.Windows.Forms.Form

‘Region for “ Windows Form Designer generated code “

     ’You can instantiate variables for classes within a procedure
     ’when you specify event handler with AddHandler statement. Howeve
r,
     ’to make ba class instance available in two procedures, this
     ’sample declares ba variable at the module level.
     Dim ba As New ByteArithmetic()

     ’Declare variables.
     Public frm2byte1, frm2byte2 As String
     Private temp As Decimal

     Private Sub Form2_Load(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles MyBase.Load

          ’Set Text and Width properties for Button1.
          Button1.Text = “Add"
          Button1.Width = 90

          ’Set Text and Width properties for Button2.
          Button2.Text = “Open Form1"
          Button2.Width = 90

          ’Assign values to Byte1 and Byte2 properties.
          ba.Byte1 = frm2byte1
          ba.Byte2 = frm2byte2

     End Sub

     Private Sub Button1_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button1.Click
          ’Designate ba_TooHigh sub procedure to process ba.TooHigh eve
nt
          AddHandler ba.TooHigh, AddressOf ba_TooHigh

          'Assign the return value from Add2byte to temp and display th
e
          'method inputs and outputs if the Add2byte method return valu
e
          'is less than or equal to 255.
          temp = ba.Add2byte
          If temp <= 255 Then
              MsgBox("Sum of " & frm2byte1 & " and " & frm2byte2 & _
              " is " & temp & ".", MsgBoxStyle.OKOnly, _
              "Result from Form2")

     End Sub

     Private Sub ba_TooHigh(ByVal ReturnValue As Decimal)

          ’Process event.
          MsgBox(“Result of “ & ReturnValue & “ is too high. “ & _
              “Returning to new Form1.”)

          ’Exit to Form1
          MyForm2Exit()

     End Sub

     Private Sub Button2_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button2.Click

          ’Exit to Form1.
          MyForm2Exit()

     End Sub

     Sub MyForm2Exit()

          ’Declare an instance of Form1 and show it.
          Dim frmForm1 As New Form1()
          frmForm1.Show()

          ’Pass local variables from Form2 module to
          ’text boxes on Form1.
          frmForm1.TextBox1.Text = frm2byte1.ToString
          frmForm1.TextBox2.Text = frm2byte2.ToString
          frmForm1.TextBox3.Text = temp.ToString

          ’Close the current form (Form2).
          Me.Close()

     End Sub

End Class

Form 2 has j ust t w o but t ons on it w it h t he default Text pr opert y set t ings. The
for m ’s Load event procedur e assigns m ore m eaningful Text pr opert y set t ings t han
t he default one: But t on1 becom es t he Add but t on, and But t on2 becom es Open
Form 1. I n addit ion, t he Form 2_Load ev ent pr ocedur e sends t he values
t ransfer red fr om t he t ex t box es on Form 1 t o an inst ance of Byt eArit hm et ic nam ed
ba. This populat es t he Byt e1 and Byt e2 propert ies in Byt eArit hm et ic. I n order t o
facilit at e referencing t he ba v ariable from sev eral differ ent pr ocedur es wit hin t he
m odule behind Form 2, t he sam ple inst ant iat es Byt eAr it hm et ic at t he m odule
level. Not ice t hat t he st at em ent per form ing t he inst ant iat ion doesn’t include a
Wit hEv ent s k eyw ord. Ther efore, unless t he procedur e t ak es ot her m easur es, t he
code behind Form 2 won’t be able t o handle ev ent s raised by t he ba inst ance of
Byt eAr it hm et ic.
As m ent ioned, t he Text propert y for But t on1 is set t o Add. Tr ue t o t his set t ing,
t he But t on1_Click ev ent procedure invok es t he Add2byt e m et hod for t he ba
variable. The ev ent pr ocedur e st ores t he ret ur n value from Add2byt e in a Decim al
variable nam ed t em p. However, before inv ok ing t he m et hod, t he But t on1_Click
ev ent procedure specifies an AddHandler st at em ent . By placing t his st at em ent
befor e t he inv ocat ion of t he Add2byt e m et hod, t he pr ocedur e enables t he code
behind Form 2 t o r espond t o an ev ent raised by t he ba class inst ance of
Byt eAr it hm et ic. The AddHandler st at em ent has t wo clauses. The AddHandler
keyw ord denot es t he st art of t he first clause. The argum ent for t his clause is t he
concat enat ion ( w it h a dot [ .] delim it er ) of t he obj ect nam e and t he nam e of t he
ev ent t o process. I n t his sam ple, t hese ar e ba for t he obj ect and TooHigh for t he
ev ent . I n t he AddressOf clause, y ou designat e t he nam e of t he procedure t hat
handles t he ev ent nam ed in t he first clause. The preceding list ing follow s
conv ent ional nam ing st andards for an ev ent pr ocedur e by specify ing ba_TooHigh
as t he nam e of t he pr ocedur e for handling t he event . I f t he r et urn value fr om t he
Add2byt e m et hod in t he t em p var iable is less t han or equal t o 255, t he
But t on1_Click ev ent pr ocedur e inv ok es a MsgBox funct ion t o display t he r esult .
The ba_TooHigh event procedur e fir es condit ionally w hen t he Add2byt e procedur e
for t he ba obj ect ret ur ns cont rol t o t he Form 2 m odule. I t is t he But t on1_Click
ev ent procedure t hat invok es t he m et hod. How ev er, depending on w het her t he
m et hod raises t he TooHigh event , cont rol can r et urn t o eit her t he But t on1_Click
ev ent procedure or t he ba_TooHigh event procedur e. The condit ion for fir ing t he
ev ent procedure is t hat t he ba obj ect raises t he TooHigh event . When t he ba
obj ect raises t he ev ent , t he ba_TooHigh ev ent procedur e in t he Form 2 m odule
t akes cont rol befor e cont rol ret urns t o t he But t on1_Click ev ent . The ba_TooHigh
ev ent procedure display s a m essage box alert ing t he user t hat t he sum is t oo
large and calls t he MyForm 2Ex it pr ocedur e. Wit hin t he MyForm 2Ex it pr ocedur e,
t he applicat ion copies t he frm 2byt e1, frm 2byt e2, and t em p values back t o t he
t ext boxes in Form 1 and shows Form 1 as it closes Form 2. Because t em p doesn’t
yet receive an assignm ent wit h t he value of t he sum when cont r ol passes t o t he
ba_TooHigh pr ocedur e, t he value of t em p is it s default value, 0, inst ead of t he
sum of frm 2byt e1 and frm 2byt e2.

                                    N ot e
At t he cost of a couple of lines of code, you can m odify t he
applicat ion t o different iat e bet ween a t r ue v alue of 0, such as
t he sum of 0 plus 0, and a value of 0 t o signify an illegit im at e
By t e value. I leave t his as a pr oblem for you because it is
out side t he scope of t he sam ple’s m ain obj ect iv es, which are
t o dem onst r at e t he oper at ion of t he AddHandler st at em ent
and t o illust rat e ev ent processing t echniques gener ally.
The Text pr opert y for But t on2 on Form 2 is set t o Open Form 1 in t he Form 2_Load
ev ent procedure. A click t o But t on2 act ually does m or e t han it s label suggest s.
The But t on2_Click ev ent procedure has j ust a single line, but t hat line calls t he
MyForm 2Exit pr ocedur e. Recall from t he discussion in t he preceding paragraph
t hat t his pr ocedur e copies values from t he m odule behind Form 2 t o t he t ext
boxes in Form 1 as it opens Form 1 and closes Form 2. I f a user clicks But t on2 aft er
com put ing a sum w it h a value less t han or equal t o 255, t he pr ocedur e has a
com put ed t em p var iable value t o pass back fr om Form 2 t o Form 1.
Ther e ar e basically t w o pat hs fr om Form 1 t o Form 2 and back t o Form 1—one pat h
for a sum t hat is a legit im at e Byt e value and anot her for a sum t hat exceeds a
legit im at e Byt e value. The t hree screen shot s at t he left of Figur e 9- 12 show t he
pat h for t ext box ent r ies of 2 and 25 on Form 1. Click ing t he Open Form 2 but t on
t ransfers cont r ol t o Form 2 and conv eys t he Byt e value t y pe equivalent s of t he
t ext box ent r ies in Form 1 int o t he frm 2byt e1 and frm 2byt e2 var iables in t he
m odule behind Form 2. Click ing t he Add but t on on Form 2 com put es t he r esult and
generat es a m essage box describing t he input s and t he legit im at e r et urn value.
Click ing t he Open Form 1 but t on ( But t on2) copies t he t w o Byt e operands and t heir
sum t o t he t ext boxes on Form 1 as it closes For m 2 and opens Form 1.
The right side of Figure 9- 12 shows t he pat h for t he t ext box ent r ies 2 and 255 on
Form 1. Because t hese t wo num bers add up t o m ore t han 255, Form 2 displays a
m essage t o t hat effect when a user clicks t he Add but t on. I n t his case, cont r ol
passes back t o Form 1 w it hout t he need t o click But t on2. When Form 1 opens, it
shows 0 as t he sum t o signify a r esult t hat is t oo large t o display as a Byt e value.

 Figu r e 9 - 1 2 . Eve n t p roce du re s ca n re dire ct t h e pa t h of a p plicat ion s an d
   r esu lt in differ en t fee d ba ck t o u se rs. ( N ot ice p ar t icu lar ly t h e m id dle
                    m e ssa ge b ox e s a n d t h e bot t om dialog box es.)
Pr oce ssin g Eve n t s f r om Se r ve r - Ba se d Tim e r s

I n addit ion t o Windows Form s, t heir cont rols, and t he out com e of com put at ions,
t im ers r epr esent anot her t ypical source for event s. The .NET Fram ew or k offers
t wo t ypes of t im ers— Windows t im ers and Serv er t im ers. Windows t im er s t arget
applicat ions inside Windows Form s. You can add t hem t o y our form s eit her fr om
t he Windows Form s cont rol sect ion of t he Toolbox in t he Windows Form s Designer
or program m at ically . I nst ant iat e t im er inst ances from t he Syst em .Windows.Form s
nam espace. Microsoft init ially int r oduced Windows t im ers w it h Visual Basic 1.0.
Alt hough Serv er t im ers can r un in Windows For m s, t hey t arget t asks t hat don’t
requir e a v isual int erface. Nevert heless, Visual St udio .NET let s you add Ser ver
t im ers t o form s from t he Com ponent s sect ion of t he Toolbox . You can also add
Ser ver t im ers pr ogram m at ically . I nst ant iat e Serv er t im ers from t he
Syst em .Tim ers nam espace.
When y our applicat ions requir e a robust t im er, you should consider a Ser ver
t im er, w hich is m ore accurat e t han a Windows t im er. You can specify t he int er val
of a Serv er t im er bet w een elapsed t im e ev ent s down t o t he level of m illiseconds.
The Windows t im er is lim it ed t o a m inim um int er val of 55 m illiseconds. I n
addit ion, a Windows t im er r uns on a single t hr ead wit hin a Windows for m . A
Ser ver t im er is designed t o w or k w it h m ult iple t hr eads— not j ust one like t he
Windows t im er . Ther efore, Serv er t im ers ar e less lik ely t o degrade t he accuracy
of t heir t im ing behav ior as t he load on a com put er becom es heav y from dat abase
access, int ensiv e calculat ions, or ot her t asks t hat can heav ily consum e com put er
resources.
When y ou drag a Serv er t im er t o a Windows form , t he t im er appears in t he
Com ponent t ray below t he form . All nonv isual com ponent s appear in t his t ray .
Figur e 9- 13 shows a Windows Form s Designer for t he Ev ent sSam ple solut ion j ust
aft er I dragged a Serv er t im er fr om t he Toolbox t o Form 6. The Propert ies window
shows t he default set t ings for t he Serv er t im er com ponent . To use t he t im er, you
m ust set it s I nt erval propert y t o a value in m illiseconds and it s Enabled propert y
t o True. For exam ple, t o set a 3- second int er val for a t im er, set it s I nt er val
propert y t o 3000. The Ser ver t im er raises an Elapsed ev ent at t he end of ev er y
int erval. Wit hout any int er vent ion, t he Serv er t im er runs cont inuously aft er y ou
init ialize it by set t ing it s Enabled pr opert y t o Tr ue. You can st op and r est art t he
t im er wit h t he St op and St art m et hods. To perform act ions associat ed wit h t he
Elapsed ev ent s, y our applicat ion m ust hav e an Elapsed event handler for t he
t im er com ponent .

                                     N ot e
The .NET Fram ework r out inely calls a t hread from it s sy st em -
t hr ead pool for processing Elapsed ev ent s associat ed wit h
Server t im ers. By using any av ailable t hr ead, t he Server
t im er ’s Elapsed event can be m issed by t he t hread
associat ed wit h a Windows form . Therefore, when y ou add a
Server t im er t o a Windows form , Visual St udio .NET
aut om at ically set s t he t im er ’s SynchronizingObj ect propert y
t o t he form ’s nam e. This feat ure ensur es t hat t he ev ent for
processing t he t im er’s Elapsed event is available t o t he
Windows form .

 Figu re 9 - 1 3 . Add a Ser ver t im e r con t r ol t o a form fr om t h e Com pon e n t s
                           t ab or se ct ion of t h e Toolb ox.
One advant age of adding a Serv er t im er from t he Toolbox inst ead of
program m at ically is t hat you can select t he t im er ’s nam e fr om t he Class Nam e
box and t he Elapsed ev ent fr om t he Met hod Nam e box t o aut om at ically creat e a
st ub for t he t im er ’s Elapsed ev ent pr ocedur e. The argum ent s for t he Elapsed
ev ent procedure ar e sender As Obj ect and e As Syst em .Tim ers.ElapsedEv ent Args.
I f you pr ogram m at ically creat e a Ser ver t im er obj ect , you should st art your form
m odule w it h an I m port s st at em ent t hat r efer ences Syst em . Tim ers. Wit h t his
conv ent ion, y ou can specify t he t ype in t he Elapsed ev ent pr ocedur e as
ElapsedEv ent Args inst ead of Syst em .Tim ers.ElapsedEv ent Args.
The left side of Figur e 9- 14 shows t he raw layout of a form t hat m anages Serv er
t im er Elapsed ev ent s. The form ’s capt ion is For m 3; you can get t o For m 3 by
click ing t he Open Form 3 but t on ( But t on3) on Form 1 of t he Event sSam ple
solut ion. You m ust r et urn t o Form 1 by clicking t he Open Form 1 but t on ( But t on2)
on Form 3 and ex it t he Event sSam ples applicat ion by clicking t he Close App
but t on ( But t on4) on For m 1. A form Load ev ent in t he m odule behind Form 3
assigns Text pr opert y set t ings and select ed ot her set t ings t o t he cont rols on
Form 3; see t he follow ing code excerpt . The r ight side of Figur e 9- 14 shows t he
for m im m ediat ely aft er for m at t ing by t he Form 3_Load ev ent pr ocedur e.

Figu r e 9 - 1 4 . A d e sign vie w of For m 3 , w h ich d em on st ra t es t e ch n iqu e s for
                             m a n a gin g Se rve r t im e r eve n t s.
Private Sub Form3_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

     ’Set selected control properties.
     Button1.Text = “Start"
     Button2.Text = “Open Form1"
     Button1.Width = 90
     Button2.Width = 90
     Label1.Text = “Count"
     Label1.TextAlign = ContentAlignment.MiddleRight
     TextBox1.TextAlign = HorizontalAlignment.Right

End Sub

At t he t op of t he m odule are t wo st at em ent s t hat set up t he w hole applicat ion.
First an I m port s st at em ent declar es a link t o t he Syst em .Tim ers nam espace. I t s
synt ax is Imports System.Timers . The st at em ent appears as t he t op line in t he
Form 3 m odule. The nex t crit ical st at em ent t oward t he t op of t he m odule is a Dim
st at em ent t hat inst ant iat es a Serv er t im er w it h t he MyTim er var iable. The synt ax
for t his st at em ent is:
Dim MyTimer as New System.Timers.Timer

Aft er t he proj ect st art s wit h t he form Load ev ent and t he pr eceding t w o
st at em ent s, t w o procedur es com bine t o m anage t he Serv er t im er and it s Elapsed
ev ent s. The But t on1_Click event procedur e assigns t he value 0 t o Text Box1. Next
t he But t on1_Click ev ent procedure set s up an event handler for t he Ser ver
t im er’s Elapsed ev ent s. The procedur e closes by set t ing t hr ee pr opert ies for t he
MyTim er obj ect . Set t ing Synchr onizingObj ect t o Not hing enables t he t im er t o
respond corr ect ly t o ver y short I nt erval propert y set t ings. For exam ple, t he
follow ing list ing shows an I nt erval propert y of only 3 m illiseconds t hat per form s
corr ect ly . Wit h t his shor t I nt erval set t ing, you cannot see screen updat es
associat ed wit h indiv idual Elapsed ev ent s, but t he set t ing m akes t he point t hat
t he Serv er t im er can work w it h exceedingly short int er vals. By set t ing t he
Enabled propert y t o Tr ue, t he code st art s t he t im er.
The MyTim er_Elapsed event pr ocedur e act ually responds t o t he event s raised by
t he t im er. I n t his sam ple, t he Elapsed event pr ocedur e for t he t im er successively
adds 1 t o t he quant it y display ed by Text Box1 for each elapsed event . To act ually
view t he indiv idual increm ent s, assign a larger v alue t o t he t im er’s I nt er val
propert y . By using t he built - in Mod funct ion, t he procedure det ect s values in
Text Box1 t hat ar e ev enly div isible by 3, such as 3, 6, and 9. Whenever t he value
in t he t ex t box is ev enly div isible by 3, t he pr ocedur e st ops t he t im er and in a
m essage box asks whet her t he user want s t o cont inue. Clicking No in t he
m essage box r est art s t he t im er for anot her t hree elapsed t im er ev ent s. When t he
user clicks Yes in t he m essage box , t he t im er rem ains st alled.
Private Sub Button1_Click(ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button1.Click

     ’This procedure and the next one require an
     ’Imports System.Timer statement and a module-level
     ’declaration for the Server timer.

     ’Initialize TextBox1 to 0, if text box has default name.
     If TextBox1.Text = “TextBox1” Then
         TextBox1.Text = “0"
     End If

     ’Declare handler (MyTimer_Elapsed) for the elapsed event
     ’for MyTimer.
     AddHandler MyTimer.Elapsed, AddressOf MyTimer_Elapsed

    ’Enable MyTimer to fire an elapsed event every 3 milliseconds.
    MyTimer.SynchronizingObject = Nothing
    MyTimer.Enabled = True
    MyTimer.Interval = 3
End Sub


Sub MyTimer_Elapsed(ByVal source As Object, _
    ByVal e As ElapsedEventArgs)

     ’Specify what should happen when MyTimer fires its
     ’Elapsed event.

     ’Start incrementing quantity in TextBox1.
     TextBox1.Text = (CInt(TextBox1.Text) + 1).ToString

     ’After adding three units, check whether to stop MyTimer
     ’permanently; initial stop is to suspend incrementing
     ’while waiting for user input.
     If (CInt(TextBox1.Text) Mod 3 = 0) Then
         MyTimer.Stop()
         If MsgBoxResult.No = MsgBox(“Want to stop?", _
         MsgBoxStyle.YesNo) Then
         MyTimer.Start()
         End If
     End If

End Sub

I f t he user click s t he Open Form 1 but t on, t he pr ocedur e shows Form 1 and closes
Form 3. The code for t his Click ev ent follows t he sam e pat t ern of ear lier sam ples.
Private Sub Button2_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button2.Click

     ’Close current form and open Form1.
     Dim frmForm1 As New Form1()
     frmForm1.Show()
     Me.Close()

End Sub
Ex ce pt ion H a ndlin g for Ru n - Tim e Er r or s
Visual Basic .NET int r oduces an at t ract iv e new way of handling r un- t im e er rors
based on st ruct ur ed ex cept ion handling. Run- t im e er rors are er r ors t hat occur
because a com put er isn’t ready t o pr ocess a r equest from y our applicat ion or an
end user fails t o ent er v alues corr ect ly . For exam ple, if your applicat ion at t em pt s
t o connect t o a SQL Ser ver inst ance t hat is t em porar ily off line, a r un- t im e error
m ight be generat ed. Your applicat ions can suffer from run- t im e er r ors even if
your code is synt act ically perfect and your logic is im peccable. All applicat ions
hav e a suscept ibilit y t o run- t im e err ors, and it is t herefore im perat ive t o handle
t hem efficient ly . That ’s why Microsoft upgraded it s support for handling run- t im e
errors w it h Visual Basic .NET.
Visual Basic 6 and ear lier v ersions of Visual Basic offer ed unst r uct ured err or
handling w it h t he On Er ror st at em ent . This st at em ent t ype t ransfers cont r ol
wit hin a pr ocedur e t o anot her point wit h t he GoTo k eyword. Most m oder n Visual
Basic program s av oid t he use of t he GoTo st at em ent for ev eryt hing except r un-
t im e error pr ocessing. Now y ou can avoid apply ing t he GoTo st at em ent ev en for
t his purpose. Visual Basic .NET st ill support s t he On Er ror GoTo st at em ent for
backward com pat ibilit y . However, st ruct ured ex cept ion handling is built int o t he
.NET Fr am ew ork. The new run- t im e er ror pr ocessing capabilit y is t herefore m or e
efficient . This sect ion begins wit h a br ief ov er view of t he new feat ures. Two
sam ples dem onst rat e select ed feat ur es of st r uct ur ed except ion handling in
Windows applicat ions. The sam ples for t his sect ion ar e in t he Except ionsSam ples
solut ion. This sect ion closes wit h best pract ices r ecom m endat ions for st ruct ured
except ion handling.

Ov e r vie w of St r u ct u r e d Ex ce pt ion H a n dlin g

St r uct ured except ion handling is built on a syst em for t racking run- t im e errors
t hat t he .NET Fram ewor k int roduces. Run- t im e er rors t hrow, or raise, built - in
except ions. I n fact , one of t he especially at t ract ive feat ur es of st ruct ured
except ion handling is t hat all r un- t im e errors raise a .NET Fram ew ork except ion.
You can v iew t he full list of except ions by choosing Except ions from t he Debug
m enu in Visual St udio .NET. The Except ions dialog box t hat opens organizes all
possible except ions w it h a t r ee cont rol. Expand t he t r ee branches t o find end
nodes list ing indiv idual except ion nam es. Cont rols on t he Except ions dialog box
facilit at e searching for except ions by nam e and adding y our ow n cust om
except ions t o t hose alr eady built int o t he syst em .
From a synt ax perspect ive, t he prim ary innovat ion of st ruct ur ed except ion
handling is t he int r oduct ion of t he Try …Cat ch…Finally st at em ent . You can place a
block of code v ulnerable t o run- t im e err ors in t he Try clause. Then y ou can cat ch
various except ions in one or m ore Cat ch clauses. Each Cat ch clause cont ains it s
own block of code for recovering fr om a r un- t im e er ror or at least gracefully
ex it ing fr om a run- t im e er ror. For exam ple, y ou can t ell t he user what problem
caused t he er ror and w hat t o do about t he problem . Any given Try clause can
hav e m ult iple Cat ch clauses aft er it . You can design each Cat ch clause for a Try
clause t o t rap one or m ore er rors. For exam ple, one Cat ch clause can r out e
cont r ol t o it s code block for a specific k ind of er ror, but a second Cat ch clause can
rout e all r em aining except ions t o it s code block.
While t he Tr y clause and at least one Cat ch clause are m andat or y for each
Try…Cat ch…Finally st at em ent , t he Finally clause is opt ional. The code block in t he
Finally clause always ex ecut es— ev en if one of t he code block s for a Cat ch clause
inv okes an Ex it Sub st at em ent or an unhandled except ion occurs. The Finally
clause is useful for r eleasing resources, such as closing dat abase connect ions or
open files.
Use t he Throw st at em ent t o creat e program m at ically a cust om except ion. This
enables your applicat ions t o creat e except ions t hat y ou can cat ch j ust like t hose
t hat ar e built int o t he .NET Fram ework . The last sam ple in t his chapt er
dem onst rat es t he synt ax.

Ca t ch ing Er r or s

The first except ion handling sam ple uses Form 1 in t he Except ionsSam ples
solut ion. This sam ple solut ion cont ains t w o form s, Form 1 and Form 2, each of
which is designed t o ser ve, in t urn, as t he st art up obj ect for t he applicat ion. I f
Form 1 isn’t t he st art up obj ect , r ight - click Except ionsSam ples in Solut ion Explor er .
Select Propert ies in t he cont ext m enu. Then choose Form 1 fr om t he St art up
Obj ect drop- dow n list in t he Except ionsSam ples Pr opert y Pages dialog box.
Confirm y our select ion by clicking OK.
Like m any of t he pr ev ious sam ples, t his sam ple perform s form at t ing for t he form
in a form Load ev ent pr ocedur e. Figur e 9- 15 shows Form 1 befor e and aft er
for m at t ing by t he Form 1_Load ev ent pr ocedur e in t he follow ing list ing. Form 1 is
t he first form in t his chapt er t o use RadioBut t on cont r ols. You can drag t hese t o
your form fr om t he Windows Form s t ab of t he Toolbox. By default , t he
RadioBut t on cont rols t hat you drag use t he Windows form as t heir cont ainer.
Click ing one RadioBut t on cont r ol deselect s all r em aining RadioBut t on cont rols on
t he form . The Checked propert y for a RadioBut t on cont rol indicat es w het her t he
cont r ol is select ed.

Figu r e 9 - 1 5 . A de sign vie w of Form 1 a n d it s st a r t u p ap pe a ra n ce fr om t h e
  Exce p t ion sSa m ple s solu t ion t h a t re vea ls t h e for m at t in g e ffect s in t h e
                            For m 1 _ Load e ven t pr oce d u r e.




Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

     RadioButton1.Text = “9223372036854775807D"
     RadioButton2.Text = “9223372036854775808D"
     RadioButton3.Text = “""“ & “1.2.3” & “"""

     RadioButton1.Width = 200
     RadioButton2.Width = 200
     RadioButton3.Width = 200

     RadioButton1.Checked = True

     Button1.Text = “Convert to Hex"
     Button1.Width = 100

     Button2.Text = “Convert/No Try"
     Button2.Width = 100

     Label1.Text = “Input value"
     Label2.Text = “Converted value"

End Sub

The sam ple at t em pt s t o conv ert one of t hree it em s t o a hexadecim al for m at using
t he Hex funct ion. A pr evious sam ple in t his chapt er int r oduced t he Hex funct ion.
I t convert s a Long int eger value t o a cor responding hex adecim al r epr esent at ion.
Users can select a value t o conv ert by picking one of t he t hree radio but t ons on
Form 1 and t hen clicking t he Convert To Hex but t on ( But t on1) . The first
RadioBut t on cont rol is for t he m ax im um value t he Hex funct ion w ill convert . The
second RadioBut t on cont rol is for 1 larger t han t he m ax im um v alue. The t hird
but t on is for a st ring t hat doesn’t conv ert t o a num ber, and it cannot t her efor e be
conv ert ed by t he Hex funct ion. The But t on1_Click event procedur e copies eit her a
Decim al value or a St r ing value t o a local var iable, eit her dec1 or st r1, and
inv okes t he Conv ert DecToHexTr y Cat ch procedure. Ther e are act ually t wo v ersions
of t he Conv ert DecToHex Try Cat ch pr ocedur e t hat im plicit ly ov erload one anot her.
I say im plicit ly over load because t he pr ocedure declar at ions don’t begin wit h t he
Over loads key word. See t he sect ion “ An Over loading Sam ple” for a r ev iew of
ov erloading.
Bot h of t he Conv ert DecToHexTr y Cat ch procedures dem onst rat e basic synt ax for
t he Try…Cat ch…Finally st at em ent . Each pr ocedure has j ust a single Cat ch clause.
I n addit ion, t he Cat ch clause t raps any possible except ion. The code blocks for
t he Cat ch clause in each ov er loaded pr ocedur e hav e t w o lines. The first line j ust
echoes t he st andard er ror m essage. The second line displays a cust om m essage
inst ead of t he default m essage for t he except ion. You can craft t hese cust om
m essages t o conv ey special inform at ion in t er m s of t he cont ext of your
applicat ion. For exam ple, you can suggest act ions for t he user t o t ak e t o
elim inat e t he problem . Not ice t hat t he second line in each over loaded funct ion
displays a differ ent m essage t hat reflect s t he cust om circum st ances causing t he
except ion.
Private Sub Button1_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button1.Click
       Dim dec1 As Decimal
       Dim str1 As String

     If RadioButton1.Checked Then
          ’Verify normal operation with valid input
          dec1 = 9223372036854775807D
          ConvertDecToHexTryCatch(dec1)
     ElseIf RadioButton2.Checked Then
          ’Confirm processing for number too large
          dec1 = 9223372036854775808D
          ConvertDecToHexTryCatch(dec1)
     Else
          ’Confirm processing for invalid format
          str1 = “1.2.3"
          ConvertDecToHexTryCatch(str1)
     End If

End Sub

Sub ConvertDecToHexTryCatch(ByVal dec1 As Decimal)
     ’Convert from string representation of decimal number to
     ’hex character representation of number.
     TextBox1.Text = dec1.ToString
     Try
         TextBox2.Text = Hex(TextBox1.Text)
     Catch er As System.OverflowException
         MsgBox(er.Message & vbCrLf & er.ToString)
         MsgBox(“Custom message for number too large.”)
     End Try

End Sub

Sub ConvertDecToHexTryCatch(ByVal str1 As String)

     ’Store the string representation of number in
     ’TextBox1 for conversion to hex characters.
     TextBox1.Text = str1
     Try
         TextBox2.Text = Hex(TextBox1.Text)
     Catch er As System.InvalidCastException
         MsgBox(er.Message & vbCrLf & er.ToString)
         MsgBox(“Custom message for string representing “ & _
         “number in wrong format.”)
     End Try

End Sub

Figur e 9- 16 cont rast s t he built - in er ror m essage ( t op) w it h t he cust om one
( bot t om ) pr epar ed in t he sam ple. I don’t t hink users ev er like t o see any k ind of
error m essages. Howev er , which er ror m essage would get y ou t he least am ount
of gr ief from your client s? Rem em ber, you add value t o t he solut ion by your
underst anding of t he client ’s needs and t he problem cont ext . Craft y our cust om
error m essages so t hey prov ide t he m ost useful inform at ion t o your com m unit y of
users.

 Figu r e 9 - 1 6 . You can cr aft cu st om e r r or m e ssag e s t h a t ar e sh or t e r an d
                   m or e h e lpfu l t h a n t h e bu ilt - in e rr or m e ssa g es.




The errors generat ed by t he second and t hird radio but t ons aren’t fat al. I f you
run t he applicat ion’s .ex e file out side Visual St udio .NET w it hout a
Try…Cat ch…Finally st at em ent and eit her t he second or t hird radio but t on
select ed, a dialog box is displayed w it h a sum m ary of t he er ror and a Cont inue
but t on. Click ing t he Cont inue but t on ret ur ns cont rol t o Form 1. Wit h a
Try…Cat ch…Finally st at em ent , y ou can by pass t he pause for t he er ror alt oget her.
For exam ple, com m ent out bot h lines w it hin t he Cat ch clause of t he
Convert DecToHex Try Cat ch procedure. The procedur e will cat ch t he er ror, but it
won’t perform any act ion aft er cat ching t he except ion r aised by t he er ror. Coding
a solut ion lik e t his is equivalent t o On Error Resum e Next in unst ruct ur ed r un-
t im e error pr ocessing.

                                    N ot e
The Convert / No Try but t on allow s y ou t o at t em pt t o conv ert
t he values denot ed by t he second or t hir d radio but t on
wit hout any processing via a Tr y…Cat ch…Finally st at em ent .
For brevit y , I include t he code for t he but t on and it s relat ed
procedures ex clusively wit h t his book ’s sam ple files.

Ca t ch ing a n d Fix ing Ru n - Tim e Er r or s

The m ain point of t he pr eceding sam ple is t hat y ou can cat ch er rors. Howev er ,
aft er cat ching t he err or , t he sam ple m er ely displays t he err or m essage— eit her a
st andard one or a cust om one. The pr eceding sect ion also discusses how t o
bypass t he display of a m essage alt oget her. Howev er , neit her of t hese opt ions
does w hat users really want — nam ely, t o fix t he error aut om at ically. Just as you
could achiev e t hat r esult wit h unst ruct ured err or pr ocessing, y ou can achiev e t he
sam e out com e w it h st ruct ured except ion handling.
The sam ple for t his sect ion uses Form 2 as t he st art up obj ect in t he
Except ionsSam ples solut ion. Mak e t his form t he st art up obj ect t o run t he sam ple
in t his sect ion. See t he inst ruct ions at t he beginning of t he preceding sect ion for
changing an applicat ion’s st art up obj ect . The code behind Form 2 enables t he
m ult iplicat ion of t wo Byt e values. The form cont ains t hree t ext box es. The first
t wo t ext boxes display t he values t o m ult iply . You should ent er a num ber
bet ween 0 and 255 in each of t hose t w o box es. The t hird t ext box displays t he
result of t he m ult iplicat ion as a Byt e v alue. A variable declared w it h a Byt e value
t ype st or es t he product . Therefore, any product s great er t han 255 raise a
Syst em .Ov erflowExcept ion except ion. The applicat ion cat ches t his except ion and
t hen aut om at ically ent ers a value in t he t hird t ext box r em inding t he user t hat
t he value is t oo large. This is a fix of sort s in t he sense t hat t he applicat ion
doesn’t j ust st op and leav e it up t o t he user t o change som et hing for t he
applicat ion t o conclude. The conclusion is t he aut om at ic ent ry of a r em inder
m essage in t he t hird t ext box .
Click ing t he Mult iply but t on ( But t on1) launches t he I nvok eByt eProduct procedur e.
This pr ocedur e begins by rounding off any places aft er t he decim al point for t he
values in t he first and second t ext box es, Text Box1 and Text Box2. The procedur e
uses t he Round funct ion, w hich is a part of t he Syst em .Mat h nam espace. Because
t he procedure doesn’t im port t he Syst em .Mat h nam espace, it m ust use t he Mat h
qualifier before t he nam e of t he Round funct ion.
Aft er rounding t he Byt e equiv alent s of t he num bers t hat appear in Text Box1 and
Text Box2 if necessary, t he pr ocedure passes t he num bers t o t he Byt eProduct
funct ion. This funct ion includes a Tr y…Cat ch…Finally st at em ent t hat ex plicit ly
t raps for t he Syst em .Ov er flow Except ion ex cept ion. I f t he Try…Cat ch…Finally
st at em ent det ect s such an except ion, t he Cat ch clause for t he ov erflow assigns
Tr ue t o t he bolByt eOv er flow m odule- level variable behind Form 2. When t he
Byt eProduct funct ion ret ur ns cont rol, t he I nvok eByt eProduct uses t he
bolByt eOv er flow var iable as t he condit ion for an I f…Then…Else st at em ent . When
bolByt eOv er flow is False, which is it s default value, t he procedure t ransfers t he
st ring equivalent of t he Byt e product t o Text Box 3. I f bolByt eOv erflow is Tr ue, t he
code in t he Else clause block copies value t oo large int o Text Box3 and reset s
bolByt eOv er flow t o it s default value.
Dim bolByteOverflow As Boolean

Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    InvokeByteProduct()
End Sub

Sub InvokeByteProduct()

     Dim   byte1 As Byte = CByte(TextBox1.Text)
     Dim   byte2 As Byte = CByte(TextBox2.Text)
     Dim   byte3 As Byte
     Dim   bol1 As Boolean
     Dim   strPrompt As String

     ’Round to drop values after decimal points.
     If Math.Round(CDec(TextBox1.Text), 0) <> CDec(TextBox1.Text) Then
         TextBox1.Text = Math.Round(CDec(TextBox1.Text), 0).ToString
         bol1 = True
     End If

     If Math.Round(CDec(TextBox2.Text), 0) <> CDec(TextBox2.Text) Then
         TextBox2.Text = Math.Round(CDec(TextBox2.Text), 0).ToString
         bol1 = True
     End If

     If bol1 = True Then
         MsgBox(“Truncated any values after decimal points to “ & _
         “provide whole number inputs.”)
     End If

     ’Compute product and save it along with base message.
     ’for summarizing the result
     byte3 = ByteProduct(byte1, byte2)

     ’Show product or “too large” message in TextBox3.
     If bolByteOverflow = False Then
          TextBox3.Text = byte3.ToString
     Else
          TextBox3.Text = “value too large"
          bolByteOverflow = False
     End If

End Sub


Function ByteProduct(ByVal byte1 As Byte, _
    ByVal byte2 As Byte) As Byte

#Const ThrowCustomException = False

    ’Test for specific error or any other error.
    ’Conditionally Throw custom test error.
    Try
        ’Conditionally throw custom exception.
#If ThrowCustomException = True Then
        Throw New Exception(“Custom error for testing.”)
#End If
        Return (byte1 * byte2)
    Catch er As System.OverflowException
        bolByteOverflow = True
    Catch er As Exception
        MsgBox(er.Message)
        Application.Exit()
    End Try
End Function

Not ice t hat t he Byt ePr oduct funct ion includes som e com pilat ion dir ect ives t hat
can force t he funct ion procedur e t o raise a cust om ex cept ion each t im e it opens.
The default set t ing for t he Thr owCust om Except ion com piler const ant is False. I f
you change t he value of t his const ant t o Tr ue and recom pile t he applicat ion, y ou
will raise an except ion on each pass t hr ough t he By t eProduct funct ion. Because
t his except ion doesn’t have t he nam e Syst em . Over flowExcept ion, t he second
Cat ch clause in t he By t eProduct funct ion cat ches it . The code block for t his
second Cat ch clause print s t he Message declared for t he except ion w hen t he
procedur e raised it w it h t he first line inside t he Try clause. Then t he applicat ion
closes. ( You can, of course, do any t hing else Visual Basic perm it s you t o
program .)

Be st Pr a ct ice s for Ex ce pt ion H a n dling

Many developers pr efer t o elim inat e r un- t im e er rors befor e t hey happen. Ot hers
prefer t o let r un- t im e er rors happen t hat t hey can fix w it h a lit t le dat a validat ion
or som e ot her m inor bit of pr ogram m ing. I believ e t hat any real- w or ld solut ions
are likely t o have lot s of opport unit ies for run- t im e er rors no m at t er how her oic
t he effort s of a pr ogram m ing t eam t o elim inat e t hem .
When it is highly lik ely t hat users w ill respond inappr opr iat ely t o a for m , it m ak es
sense t o progr am a solut ion in your r egular program m ing logic. The sam e
considerat ions apply t o hardw ar e- based ext er nal fact ors, such as files not being
in a folder or dat abase ser vers not being available for a connect ion. How ev er,
t here are m any ext er nal fact ors t hat can negat ively im pact y our program . Som e
of t hese hav e a low probabilit y of occurr ence. For t hese rar e cases, it is probably
not wort h t he program m ing effort t o dev elop det ailed solut ions in your st andard
program logic. Rout ine except ion handling m ak es gr eat sense for t hese cases.
I also want t o point out t hat except ion handling is an int egral part of Visual Basic
.NET. This m eans t hat y our program m ing t eam s will gradually achiev e high levels
of proficiency w it h t he approach. Ther efor e, placing your code in Tr y, Cat ch, and
Finally blocks w ill im pr ove it s clarit y t o ot hers w ho k now t he program m ing
paradigm as opposed t o som e ad hoc pr ogram m ing solut ion one of your
program m ing t eam m em bers concoct s.
Alt hough t he On Er ror GoTo st at em ent is fam iliar from ear lier versions of Visual
Basic and st ill available in Visual Basic .NET, I r ecom m end t hat y ou m igrat e away
from it in y our new applicat ion developm ent effort s. The GoTo st at em ent leads t o
unst r uct ured ( “spaghet t i”) code. This code design st yle is w idely recognized t o be
difficult t o debug and m aint ain. I n addit ion, you can hav e only one act iv e On
Er ror GoTo st at em ent at a t im e. You can nest m ult iple Try…Cat ch…Finally
st at em ent s w it hin one anot her.
Finally, I leav e you wit h t wo part ing r ecom m endat ions. First , replace t he built - in
error m essages wit h cust om ones t hat m ax im ize t he am ount of cont ext ual help
your applicat ions get . Second, t ry t o fix pr oblem s rat her t han j ust let a user k now
t hat a problem ex ist s. For exam ple, if y our applicat ion cannot connect t o a
dat abase serv er , at t em pt t o connect t o a backup dat abase serv er w hen one is
available.
Cha pt e r 1 0 . Pr ogr a m m ing W indow s
Solut ions w it h AD O.N ET
Chapt er 1 int roduces you t o ADO.NET concept ually and shows y ou how t o cr eat e
a sim ple ADO.NET applicat ion using Visual St udio .NET graphical design t ools.
This chapt er builds on t he ADO.NET int r oduct ion in Chapt er 1 and t he int erv ening
chapt ers t hat enhance y our SQL Serv er and Visual Basic .NET sk ills. Think of t his
chapt er as a “how t o” guide for solut ions t o t ypical dat abase pr oblem s wit h
ADO.NET. The focus is on program m ing solut ions for Windows applicat ions.
Chapt er 11 delv es int o creat ing solut ions wit h ASP.NET, and Chapt er 12 put s t he
spot light on XML issues as t hey relat e t o ADO.NET and SQL Serv er.
The chapt er has five m aj or sect ions.

    •   The chapt er begins wit h a brief ov erv iew of ADO.NET design issues. This
        sect ion dr ills dow n int o t he dat a set obj ect m odel. This m at er ial w ill help
        you t o pr ogram m at ically coordinat e dat a set obj ect s wit h SQL Serv er
        dat abase obj ect s.
    •   Next t he chapt er pr esent s program m ing sam ples for m ak ing a connect ion
        t o a SQL Server dat abase. This present at ion also dem onst rat es how t o
        secure access t o your SQL Ser ver dat abases. ( See Chapt er 7 for m ore on
        SQL Ser ver secur it y .)
    •   Cov erage m ov es fr om m ak ing a connect ion t o for ward- only, read- only
        dat a access. Sev eral sam ples reveal t he flex ibilit y you can achieve w it h
        t his form of dat a access for display ing dat a. I n addit ion, y ou lear n how t o
        dynam ically configur e t he source t hat a Dat aReader obj ect cont ains at run
        t im e.
    •   The next sect ion int roduces how t o display dat a set obj ect s wit h Window s
        Form s. I t covers how t o program m at ically bind Windows Form s cont r ols—
        such as t ext box es, com bo boxes, and dat a gr ids— t o dat a set obj ect s.
        You’ll also lear n how t o display par ent - child dat a r elat ionships so t hat
        users can cont rol t he display of child dat a by m anipulat ing a cont r ol for
        t he parent dat a.
    •   The chapt er concludes wit h a sect ion t hat dem onst rat es how t o updat e,
        insert , and delet e rows in a SQL Serv er dat abase from a Windows form .

All t he sam ples t hr oughout t his chapt er use t he My ADODOTNETSam ples solut ion.
You can open t he solut ion file ( My ADODOTNETSam ples.sln) in Visual St udio .NET.
This chapt er provides specific inst ruct ions for launching each sam ple from t he
solut ion. By following t he inst ruct ions, y ou’ll gain fam iliar it y w it h how t o st art a
Windows applicat ion from an elem ent w it hin a solut ion ot her t han Form 1—t he
default st art up obj ect .




An Ove r view of AD O.N ET Obj ect s
ADO.NET let s y ou use any of t hree dat a pr ov iders. These pr ov iders can link y our
Visual Basic .NET applicat ion t o a r em ot e dat a source. As a dev eloper concer ned
wit h solut ions for SQL Ser ver dat abases, y ou’ll be pleased t o know t hat one of t he
dat a providers is exclusively for SQL Serv er— in part icular, SQL Serv er 7 and SQL
Ser ver 2000. You can t ake advant age of t he SQL Serv er pr ov ider t hrough t he
Syst em .Dat a.SqlClient nam espace. You can place an I m port s st at em ent at t he
t op of any m odule needing access t o t he ADO.NET obj ect s available t hr ough t he
SQL Ser ver dat a pr ov ider . The synt ax for t his st at em ent is:
Imports System.Data.SqlClient

Ther e ar e six basic ADO.NET obj ect classes. These classes are t he Connect ion
class, t he Com m and class, t he Dat aReader class, t he Dat aAdapt er class, t he
Dat aSet class, and t he Dat aView class. This sect ion prov ides a br ief or ient at ion t o
each of t hese classes t hat focuses on select ed propert ies and m et hods for each
class t hat you are likely t o find useful in y our w ork. Much of t his m at er ial
specifically equips y ou t o underst and t he sam ples t hat appear lat er in t his
chapt er .

Th e Conn e ct ion Cla ss

The Connect ion class enables your applicat ion t o r ead fr om , and opt ionally writ e
t o, a r em ot e dat a source. I nst ant iat e Connect ion obj ect s wit h t he SQL Ser ver
dat a provider as a SqlConnect ion obj ect . You can use t his obj ect t o connect t o a
serv er w it h eit her Windows NT or SQL Ser ver aut hent icat ion. The connect ion
st ring synt ax is very sim ilar t o t hat for ADO. I n addit ion, you can open and close
connect ions wit h t he Open and Close m et hods. You can cat ch except ions dur ing
an at t em pt t o connect t o a serv er and r espond appropriat ely. For exam ple, if you
hav e a back up serv er available for dat a access, you can at t em pt t o connect t o t he
backup ser ver w hen t he pr im ar y serv er is unav ailable. Your applicat ions should
explicit ly close Connect ion obj ect s aft er t her e is no longer a need for t hem .

                                    N ot e
When used wit h a SqlCom m and obj ect , a SqlConnect ion
obj ect can even perm it a client t o adm inist er a SQL Ser ver
inst ance. For exam ple, you can add and r em ove dat abase
obj ect s, such as logins, user - defined funct ions, and st ored
procedures.
The SqlConnect ion obj ect ’s Connect ionSt r ing pr opert y let s you get or set t he
connect ion st r ing for a Connect ion obj ect . The Dat aSource pr opert y r et ur ns t he
SQL Ser ver inst ance t o which a SqlConnect ion obj ect links, and t he Dat abase
propert y denot es t he specific dat abase on t he ser ver t o w hich t he Connect ion
obj ect prov ides access. The Connect ionTim eout propert y allows y ou t o fine- t une
how long an applicat ion wait s for a connect ion fr om a serv er before raising an
except ion because t he ser ver is unav ailable.

Th e Com m a n d Cla ss

The Com m and class encapsulat es SQL inst r uct ions for a r em ot e dat abase serv er.
These inst ruct ions can be sim ple SELECT st at em ent s, dat a m anipulat ion
st at em ent s, or st at em ent s t hat creat e and m anipulat e obj ect s on t he dat abase
serv er. Code your inst ruct ions t o a rem ot e SQL Ser ver inst ance w it h T- SQL. See
Chapt ers 2 t hr ough 6 for exam ples of t he k inds of st at em ent s t hat y ou can
encapsulat e in a Com m and obj ect . Apply obj ect s based on t he Com m and class
wit h anot her obj ect based on eit her t he Dat aReader class or t he Dat aAdapt er
class.
I nst ant iat e a SqlCom m and obj ect t o represent a Com m and obj ect wit h t he SQL
Ser ver dat a provider. Thr ee especially cr it ical SqlCom m and pr opert ies are
Com m andText , Com m andType, and Param et er s. The Com m andText pr opert y
holds a T- SQL st at em ent , a st or ed procedur e nam e, or a t able nam e. By default ,
ADO.NET int erpr et s t he Com m andText propert y as a T- SQL st r ing. The
Com m andType propert y set t ings ar e Text , St oredProcedure, and TableDir ect .
Text is t he default set t ing. Use a St or edPr ocedur e set t ing for Com m andType
when t he Com m andTex t propert y designat es a st ored procedure. When you ar e
select ing all t he rows and colum ns fr om one or m or e t ables, t he TableDirect
propert y set t ing is especially useful. Wit h t he TableDirect propert y set t ing, you
can nam e one or m ore t ables in t he Com m andText propert y . Delim it m ult iple
t able nam es from one anot her wit h a com m a.
The Param et ers pr opert y for a SqlCom m and obj ect ret urns t he Param et ers
collect ion. Use param et ers t o dy nam ically set argum ent s for st or ed procedur es,
ot her dat abase obj ect s, and ev en T- SQL st rings at run t im e. Param et ers ar e
especially useful when y ou’r e per form ing dat abase m anipulat ion t asks, such as
m odify ing r ecords, inser t ing new r ecords, and delet ing r ows from a SQL Ser ver
dat a source. I n t his cont ext , you add t he param et ers t o a Com m and pr opert y of a
Dat aAdapt er obj ect . You can also use t he Param et ers collect ion t o r et r ieve out put
param et ers and ret ur n values fr om st ored procedures.

                                      N ot e
When work ing wit h t he SQL Serv er dat a pr ovider , you m ust
designat e param et er s by nam e inst ead of using a quest ion
m ar k place m arker as y ou can wit h t he OLE DB .NET dat a
provider.
Sev eral m et hods facilit at e t he abilit y of a Com m and obj ect t o im plem ent a T- SQL
st at em ent in it s Com m andText propert y . Use t he Ex ecut eReader m et hod t o
populat e a Dat aReader obj ect based on a SELECT st at em ent . The Ex ecut e-
NonQuery m et hod signals t hat a T- SQL st at em ent doesn’t r et ur n values. This
m et hod is part icularly appropr iat e for T- SQL st at em ent s t hat cr eat e and
m anipulat e obj ect s, such as t hose t hat add logins or m anipulat e perm issions. The
Ex ecut eScalar m et hod ret ur ns a single v alue, inst ead of a set of rows, from a T-
SQL st at em ent . The value cor responds t o t he first colum n value in t he first row of
t he r esult set from t he T- SQL st at em ent on t he serv er .

Th e D a t a Re a de r Cla ss

The Dat aReader class enables read- only , forward- only access t o a r em ot e dat a
source. Obj ect s based on t his class m aint ain an open connect ion w it h t he rem ot e
dat a source. Dat aReader obj ect s let client s r ead dat a, but t hey don’t prov ide
edit ing capabilit y or bidirect ional nav igat ional feat ures. Obj ect s based on t he
Dat aReader class ar e especially w ell suit ed w hen client perform ance t im es ar e
m or e cr it ical t han scalabilit y issues. This is because each Dat aReader obj ect
requir es it s own exclusiv e dat abase Connect ion obj ect . When t he num ber of
act ive Dat aReader obj ect s from client s ex ceeds t he num ber of connect ions
available from a serv er , client s m ust wait for anot her Dat aReader obj ect t o
release a connect ion ( or r et urn at a t im e w hen t her e is less dem and for
connect ions) .
I nst ant iat e Dat aReader obj ect s as inst ances of t he SqlDat aReader class for t he
SQL Ser ver dat a pr ov ider . You populat e SqlDat aReader obj ect s by inv oking t he
Ex ecut eReader m et hod for a SqlCom m and obj ect t hat r et urns a r owset . You can
fr ee t he connect ion associat ed w it h a Dat aReader obj ect by inv ok ing t he Close
m et hod for eit her t he Connect ion or Dat aReader obj ect . Alt hough t he
RecordsAffect ed pr opert y r eport s t he num ber of r ecords t hat a Dat aReader
select s, t his propert y r et urns accurat e r esult s only aft er y ou close t he Dat a-
Reader. I f a query fails t o r et ur n rows, t he FieldCount propert y of a Dat aReader
will equal 0.
I m m ediat ely aft er a Dat aReader is populat ed, it s posit ion is j ust pr ior t o t he first
row . You can access t he first row by invoking t he Read m et hod. Repeat edly
inv ok ing t he Read m et hod allows an applicat ion t o pass t hrough successive r ows
in t he r esult set for a Dat aReader. A r et ur n value of False from t he Read m et hod
indicat es t hat no m ore r ows r em ain in a result set . Ret riev e t he colum n v alues
wit hin a r ow w it h any of a ser ies of Get m et hods, such as Get I nt 32, Get St ring, or
Get SqlDat eTim e. The m et hods allow you t o repr esent colum n values w it h dat a
t ype for m at s. Get m et hods wit h SQL in t heir nam es, such as Get SqlDat eTim e,
ret ur n SQL Serv er dat a t ype values, such as t hose discussed in Chapt er 2. Get
m et hods w it hout SQL in t heir nam es ret ur n values in .NET Fram ework v alue
t ypes, such as t hose discussed in Chapt er 9. Reference indiv idual colum n values
wit hin a r ow by ordinal num ber. For exam ple, drd1.GetString(0) ret urns t he
first colum n value as a st ring for t he curr ent r ow in t he drd1 Dat aReader .

Th e D a t a Ada pt e r Cla ss

The Dat aAdapt er class ser ves as a bridge for connect ing a SQL Serv er dat a
source t o a Dat aSet class inst ance. You can use a Dat aAdapt er obj ect t o init ially
populat e a dat a set , and you can also use a Dat aAdapt er obj ect t o sy nchronize a
local dat a set w it h m at ching dat a in a SQL Ser v er inst ance. The Dat aAdapt er
class is fundam ent al t o ADO.NET, and it is a m aj or design feat ur e enabling t he
high scalabilit y of ADO.NET applicat ions. The Dat aSet class, t oget her w it h it s
hierarchically dependent obj ect s, repr esent s a disconnect ed dat a source.
Ther efor e, t he Dat aAdapt er class doesn’t requir e a const ant connect ion t o a
rem ot e dat a source. Dat aAdapt er obj ect s can link t o SQL Serv er dat a sources
only w hen necessary, fr eeing t he ser ver in int er vening per iods t o serv ice ot her
client s.
I nst ant iat e Dat aAdapt er obj ect s wit h t he SQL Ser ver dat a provider as inst ances of
t he SqlDat aAdapt er class. You m ust use a SqlDat aAdapt er obj ect in concert w it h
a SqlConnect ion obj ect . The SqlConnect ion obj ect t hat a SqlDat aAdapt er obj ect
references is t he conduit t he Dat aAdapt er obj ect uses t o link a local dat a source,
represent ed by a Dat aSet obj ect , t o a rem ot e dat a source on a server. You can
inst ant iat e a SqlDat aAdapt er obj ect w it h an em bedded T- SQL st at em ent or w it h a
reference t o a SqlCom m and obj ect . The T- SQL st at em ent , w het her it is
em bedded or available in a SqlCom m and obj ect , det erm ines which r em ot e
dat abase obj ect s get t apped t o populat e a local dat a set .
Use t he SqlDat aAdapt er Fill m et hod t o populat e a local dat a set . Before you can
inv oke t he m et hod, t he SqlDat aAdapt er m ust have an open connect ion t o a
rem ot e dat a source. Aft er init ially inv ok ing t he Fill m et hod, your applicat ion can
close t he connect ion and work wit h t he local dat a set version.
The SqlDat aAdapt er class facilit at es dat a m anipulat ion for SQL Serv er obj ect s
t hr ough it s Updat e m et hod and it s relat ed Updat eCom m and, I nsert Com m and,
and Delet eCom m and pr opert ies. By specify ing t hese t hree propert ies, y ou can
designat e dat a m anipulat ion inst r uct ions, such as T- SQL sy nt ax for an updat e, an
insert , or a delet e t ask. You can specify t he T- SQL propert y dir ect ly as part of t he
propert y specificat ion or indir ect ly by refer encing a st ored procedur e. I n eit her
case, you w ill m ap colum ns in t he local dat a set t o colum ns in a rem ot e dat a
source by adding par am et ers t o t he com m ands designat ed by t he
Updat eCom m and, I nser t Com m and, and Delet eCom m and Dat aAdapt er propert ies.
I nvok e t he Updat e m et hod t o t ransfer changes t o a rem ot e dat a source from a
local dat a set . The Updat e m et hod— in concert wit h t he Com m and obj ect s
Updat eCom m and, I nser t Com m and, and Delet eCom m and—acco- m m odat es
updat e, insert , and delet e dat a m anipulat ion t asks.
The SqlDat aAdapt er obj ect support s opt im ist ic concur r ency bet w een t he rem ot e
dat a source and t he local dat a set . This follows from t he disconnect ed st at us of
t he local dat a set from t he r em ot e dat a source. I n fact , ADO.NET doesn’t enable
pessim ist ic concurrency . Keyset cursors and connect ed recordset s ar en’t a part of
ADO.NET as t hey are of ADO. While opt im ist ic concur rency helps t o enhance
scalabilit y, it requir es an ext ra m easure of care t o m at ch t he changes in a local
dat a set back t o t he r em ot e serv er. For exam ple, at t em pt ing t o updat e a row in a
rem ot e dat a source fr om a local dat a set t hat changed since y ou last populat ed
t he dat a set raises an opt im ist ic concurr ency v iolat ion. This v iolat ion raises an
except ion.

                                     N ot e
Opt im ist ic and pessim ist ic concur rency are t wo cont r ast ing
ways of m anaging dat a m anipulat ion in a m ult iuser
env ironm ent . Wit h pessim ist ic concurr ency , a lock applies t o
a row as soon as a user signals t he st art of a dat a
m anipulat ion t ask for a r ow. This lock doesn’t release unt il
t he com plet ion of t he t ask. Wit h opt im ist ic concur rency, no
lock s go on a row aft er t he st ar t of a dat a m anipulat ion t ask.
Ther efore, anot her user can change dat a before t he current
user com m it s a change. I f t he dat a does change before t he
com m it m ent of a change by t he curr ent user , t he dat abase
server r aises a concurrency v iolat ion w hen t he curr ent user
at t em pt s t o com m it t he change. Opt im ist ic concur rency
scales bet t er t han pessim ist ic concurr ency. Ther efor e,
opt im ist ic concurr ency is m or e suit able for m ult iuser
applicat ions— par t icularly if t he applicat ions serve m any
users.
ADO.NET pr ov ides t wo t echniques for handling except ions result ing fr om
opt im ist ic concur r ency v iolat ions. First , y ou can creat e an event procedure for t he
RowUpdat ed ev ent . ADO.NET raises t his ev ent aft er each at t em pt t o change a
rem ot e dat a source based on a m odified row fr om a local dat a set . Wit h a
RowUpdat ed ev ent pr ocedur e, y ou can pr ocess except ions as t hey occur for each
row . Second, y ou can set t he Cont inueUpdat eOnEr ror propert y of t he
SqlDat aAdapt er obj ect t o Tr ue before inv ok ing t he Updat e m et hod. This causes
ADO.NET t o com plet e all v alid updat es and wr it e any err or m essages t o t he local
dat a set so t hat you can respond t o t hem aft er t he Updat e m et hod t erm inat es.

Th e D a t a Se t Cla ss

The Dat aSet is a m em or y- resident obj ect t hat can cont ain one or m ore t ables and
relat ionships bet w een t ables. This m em ory - r esident obj ect and it s child obj ect s
m ake up t he disconnect ed dat a source t hat is t he cent erpiece of t he ADO.NET
archit ect ure. Figur e 10- 1 present s an overv iew of t he Dat aSet obj ect m odel. The
balance of t his sect ion describes select ed com ponent s w it hin t hat m odel.

                      Figu re 1 0 - 1 . Th e D at a Se t ob j e ct m ode l.
ADO.NET r efers t o each indiv idual t able w it hin a dat a set as a Dat aTable obj ect .
The collect ion of all t ables wit hin a dat a set is t he Dat aTableCollect ion class. The
t ables w it hin a dat a set can r elat e hierarchically t o one anot her . This m akes it
possible for y ou t o r epr esent t he schem a for t he t ables in t he Nort hw ind dat abase
wit hin a dat a set . The Recordset obj ect from classic ADO doesn’t direct ly
represent hierarchical r elat ionships. I nst ead, classic ADO flat t ens t he
relat ionships bet w een t ables int o a single rowset .
Dat aTable obj ect s consist of Dat aColum n and Dat aRow obj ect s. The set of dat a
colum ns w it hin a Dat aTable obj ect is t he Dat aColum nCollect ion obj ect . The
Dat aColum nCollect ion class defines t he schem a for a Dat aTable obj ect . For
exam ple, t he indiv idual Dat aColum n obj ect s specify a dat a t ype t hat each colum n
can cont ain. Dat aTable obj ect s can hav e a Prim ary Key pr opert y. You can define
t his propert y wit h a Dat aColum n ar ray t hat can cont ain one or m or e Dat aColum n
obj ect s. The Dat aRowCollect ion class repr esent s all rows w it hin a Dat aTable.
Colum n values for a local t able r eside w it hin t he Dat aRow obj ect s t hat m ake up
t he Dat aRow Collect ion obj ect for a Dat aTable obj ect . I nvok e t he New Row m et hod
for a Dat aTable t o creat e a new row. You can t hen assign colum n values t o t he
row and add t he new Dat aRow obj ect t o t he Dat aRow Collect ion obj ect for a
Dat aTable obj ect .
ADO.NET specifies t he r elat ionship bet w een t ables in a dat a set w it h a
Dat aRelat ion obj ect . The set of all Dat aRelat ion obj ect s wit hin a dat a set is a
Dat aRelat ionCollect ion obj ect . Addit ionally, you can specify const raint s for t ables
wit h t he Const raint class. Wit h a Const raint obj ect , you can specify unique or
for eign k ey const raint s. A Dat aRelat ion obj ect bet ween t w o t ables denot es a
parent - child relat ionship bet w een t he t ables. When y ou creat e a Dat aRelat ion
obj ect bet w een t w o t ables, ADO.NET aut om at ically cr eat es a for eign k ey
const raint in t he child t able and a unique const r aint on t he pr im ary k ey in t he
parent t able. A Dat aRelat ionCollect ion class for a Dat aSet obj ect cont ains each of
t he Dat aRelat ion obj ect s in a dat a set . You can access Dat aRelat ion obj ect
m em bers t hrough t he ChildRelat ions and Parent Relat ions propert ies of indiv idual
Dat aTable obj ect s.
Ther e ar e t wo t echniques for elim inat ing a Dat aRow obj ect fr om t he
Dat aRow Collect ion of a Dat aTable obj ect . The first of t hese t echniques is t he
Delet e m et hod, w hich applies t o indiv idual Dat aRow obj ect s wit hin a Dat aTable.
This t echnique assigns Delet ed t o t he Row St at e pr opert y for a Dat aRow, but it
doesn’t act ually r em ov e t he r ow fr om t he local t able. ( Your applicat ion can
rest ore a delet ed r ow wit h t he Rej ect Changes m et hod for a Dat aRow obj ect .)
Alt er nat ively, y ou can com m it t he applicat ion of a Delet e m et hod t o a r ow so t hat
it isn’t r ecov erable by invok ing t he Accept Changes m et hod for t he r ow.
The second t echnique for elim inat ing a row from a local t able is t o invok e t he
Rem ove m et hod for t he Dat aRow Collect ion obj ect wit hin a Dat aTable obj ect . This
m et hod requir es t hat you specify t he index for t he r ow t hat y ou want t o
elim inat e. I ndex values st art wit h 0 and progress by 1 for each Dat aRow obj ect
wit hin a Dat aTable unt il 1 m inus t he count of rows wit hin t he Dat aTable. This
second t echnique doesn’t allow you t o rest ore a row.

                                     N ot e
Use t he Delet e m ethod when you plan t o inv oke t he Updat e
m et hod t o sy nchronize local changes wit h a r em ot e dat a
source. The Updat e m et hod will apply t he Accept Changes
m et hod t o t he row aft er synchronizat ion wit h t he rem ot e
dat a source. Elim inat ing a row w it h t he Rem ov e m et hod will
raise an err or based on a concurr ency v iolat ion bet ween t he
dat a set and t he rem ot e dat a sour ce when you invoke t he
Updat e m et hod.

Th e D a t a V ie w Cla ss

A Dat aView obj ect is t o a Dat aTable as a v iew is t o a t able in SQL Ser ver. You
base a Dat aView obj ect on a single Dat aTable obj ect . The Dat aView obj ect for a
t able support s filt er ing, sort ing, and enhanced searching capabilit ies not direct ly
available from Dat aTable obj ect s. Any given Dat aTable obj ect can hav e m ult iple
Dat aView obj ect s specified for it w it h different propert y set t ings for filt ering and
sort ing. You can filt er t he rows for a Dat aView w it h eit her t he RowFilt er or
Row St at eFilt er propert y . RowFilt er propert y set t ings hav e t he sam e form as a
WHERE clause for a single colum n in a t able. Enclose RowFilt er expr essions in
double quot at ion m ark s. I f t he expr ession cont ains a st ring const ant , enclose t he
const ant in single quot at ion m arks. The Row St at eFilt er pr opert y allows you t o
filt er t he r ows in a Dat aTable obj ect by t he Dat aView RowSt at e propert y set t ing
for each r ow in a t able. By filt ering on t his pr opert y , y ou can det ect rows
elim inat ed wit h t he Delet e pr opert y as well as insert ed rows and r ows w it h
m odified values.
The Sort propert y for a Dat aView obj ect denot es a sort order for t he r ows of a
Dat aView obj ect . You designat e t he Sort propert y as a ser ies of colum n nam es
t hat ar e com m a delim it ed if you specify m ore t han one colum n for sort ing a
Dat aView obj ect . By default , ADO.NET sort s in ascending order . How ev er, y ou
can explicit ly specify an ascending sort order by follow ing a colum n nam e w it h
ASC. Follow a colum n nam e w it h DESC t o designat e a descending sort order for a
colum n. The Dat aView obj ect sort s it s r ows in t he order of t he colum ns list ed for
it s Sort pr opert y.
Alt hough y ou can ret urn a single row or a subset of rows wit h t he RowFilt er
propert y , doing so isn’t an efficient use of it . I n general, y ou should t ry t o set t he
RowFilt er pr opert y j ust once t o sav e on t he cost of index ing a Dat aView obj ect . I f
you need t o find a single row or a subset of r ows, inv ok e eit her t he Find or
FindRows m et hod. For eit her of t hese m et hods t o w or k, y ou m ust first assign a
Sort propert y set t ing for t he cr it er ia t hat y ou use t o find r ows. The FindRows
m et hod ret ur ns an array of Dat aRow View obj ect s. The Find m et hod ret ur ns t he
row index for a r ow m at ching t he Find argum ent . You can t hen use t he row index
value t o display a row fr om t he Dat aView or it s underly ing Dat aTable.




Ma k in g Con n ect ion s
Making a connect ion is som et im es t hought of as a m undane t ask, but it ’s at t he
core of pr oj ect s t hat process dat a from a r em ot e dat abase serv er . When y ou’re
building SQL Serv er solut ions, y our applicat ions will near ly always st art wit h t he
m aking of a connect ion t o a SQL Server inst ance. This sect ion illust rat es t he
synt ax for m ak ing connect ions t o a SQL Ser ver inst ance based on eit her a
Windows login or a SQL Ser ver login. I t also shows you how t o t rap err ors t hat
can ar ise as y ou at t em pt t o open a connect ion. Finally, t he sect ion concludes wit h
a Windows Form s sam ple t hat let s users pick t he st yle of login t hey want for t heir
connect ion at t em pt as well as t he dat abase t o which t hey want t o connect .

Loggin g I n w it h I nt e gr a t e d Se cu r it y

The sam ple in t his sect ion shows t he sy nt ax for logging in t o t he Nort hwind
dat abase wit h Windows NT securit y. The sy nt ax for t he connect ion st r ing refers t o
t he designat ion of Windows NT secur it y as I nt egrat ed Securit y. Recall from
Chapt er 7 t hat t his t ype of login r elies on t he Windows login account for access t o
a dat abase on a SQL Serv er inst ance. The sam ple m ak es a connect ion t o t he
Nort hwind dat abase, w hich is a SQL Serv er sam ple dat abase t hat is inst alled w it h
a guest user account . Ther efor e, any one who can log in t o a SQL Server inst ance
can connect t o t he dat abase.
The sam ple r uns fr om Module1 w it hin t he MyADODOTNETSam ples solut ion. Aft er
opening t he solut ion in Visual St udio .NET, r ight - click t he solut ion’s nam e in
Solut ion Explorer and choose Pr opert ies from t he cont ext m enu. Select Module1
as t he st art up obj ect . Then double- click Module1 in Solut ion Explorer t o open it in
t he Code Edit or w it h t he t ab label Module1.vb. Finally, r em ove t he com m ent
            )
m ark er ( ' from IntegratedCnnToNorthwind() in t he m ain sub pr ocedur e at t he
t op of t he m odule, and m ake sur e all ot her pr ocedur e calls in t he m ain procedure
hav e com m ent m ark ers in fr ont of t hem . You can launch t he pr ocedure t o run it s
lines in one st ep by pr essing t he F5 key. St ep t hr ough t he procedur e one line at a
t im e by pressing F8 once for each successive line. These st eps act ually st art t he
m ain procedur e. Then cont inue pr essing F8 for each st ep t hr ough t he m ain and
I nt egrat edCnnToNort hw ind pr ocedur es. I oft en use F8 t o help debug pr ocedur es
or ev en j ust t o clar ify t he flow of cont rol t hr ough a procedure.

                                    N ot e
Not ice t he I m port s st at em ent at t he t op of Module1 t hat
references t he Syst em .Dat a.SqlClient nam espace. This is
necessary for t he abbreviat ed st yle used by t he sam ple t o
refer t o t he SqlConnect ion class. The sam ple in t he
“Connect ing from a Windows Form ” sect ion lat er in t his
chapt er illust r at es anot her convent ion for r efer encing t he
SqlConnect ion class t hat doesn’t r equire t he I m por t s
st at em ent .
The sam ple code for t he I nt egrat edCnnToNort hwind procedur e appears next . I t
begins w it h a declarat ion for cnn1 as a SqlConnect ion class inst ance. The
st at em ent bot h declar es and inst ant iat es t he cnn1 obj ect r efer ence in a single
st at em ent . The New keyword inst ant iat es a SqlConnect ion obj ect . The argum ent
for t he Connect ion obj ect specifies t he connect ion st ring for t he cur rent Windows
user t o connect t o t he Nort hw ind dat abase on t he local default inst ance of SQL
Ser ver on t he curr ent com put er . When r eferr ing t o t he local default inst ance, you
can designat e t he Dat a Source as eit her “( local) ” or “localhost ”. You can also
designat e a ser ver’s nam e inst ead of t he local one. For exam ple, y ou could ent er
cab2000 as t he argum ent for Dat a Source if you could phy sically connect t o a
SQL Ser ver inst ance nam ed cab2000. The serv er need not hav e t he .NET
Fram ew ork inst alled— j ust t he w orkst at ion running y our .NET applicat ion. The
I nit ial Cat alog elem ent of t he Connect ionSt r ing argum ent specifies t he dat abase
t o w hich y ou want t o open a connect ion. By set t ing t he I nt egrat ed Securit y
elem ent of t he Connect ionSt r ing argum ent t o SSPI , y ou can designat e a
connect ion based on t he curr ent Windows account .
Aft er declar ing and inst ant iat ing cnn1, t he sam ple invokes t he Open m et hod for
t he SqlConnect ion obj ect . Pr ov ided t he Nort hwind dat abase is available on t he
local SQL Server inst ance and t he cur rent local user has perm ission t o access t he
Nort hwind dat abase, t he Open m et hod succeeds. I f you ar e t he adm inist rat or of
t he local ser ver and y ou per form ed a st andard inst allat ion of a r egular SQL Ser ver
edit ion, t he Open m et hod w ill w or k. Aft er m ak ing t he connect ion, t he sam ple
echoes t he connect ion st ring. The synt ax for ret ur ning t he connect ion st ring
eit her t o t he Debug window in Visual St udio .NET or t o a m essage box is in t he
sam ple. ( The m essage box way is com m ent ed out .) Before t erm inat ing, t he
sam ple closes t he cnn1 SqlConnect ion obj ect . You should always explicit ly close
SqlConnect ion obj ect s in y our applicat ions when y ou no longer need t hem .

                                    N ot e
MSDE 2000 ( Microsoft SQL Ser ver 2000 Desk t op Engine)
doesn’t ship wit h t he Nor t hwind dat abase. Therefore, when
using t his dat abase ser ver , you m ust use anot her dat abase
on t he MSDE 2000 ser ver inst ance or cr eat e a Nort hwind
dat abase wit h appropr iat e obj ect s wit hin it .
Sub IntegratedCnnToNorthwind()
    ’Specify connection string for connection via user’s
    ’Windows login; make sure user’s Windows login has access
    ’to the Northwind database or the Northwind database has
    ’a guest user account.
    Dim cnn1 As SqlConnection = _
          New SqlConnection(“Data Source=(local);” & _
          “Initial Catalog=northwind;Integrated Security=SSPI”)

     ’Attempt to open Northwind database with user’s Windows login.
     cnn1.Open()

     ’Echo connection string to either Debug window
     ’or a message box.
     Debug.WriteLine(cnn1.ConnectionString)
     ’MsgBox(cnn1.ConnectionString)

     ’Close connection object to dispose of it.
     cnn1.Close()

End Sub


Loggin g I n w it h SQL Se r ve r Se cu r it y

Alt hough Windows NT secur it y is t he pr eferr ed way t o connect t o a SQL Serv er
dat abase, t her e ar e t im es when SQL Ser ver secur it y is necessary or conv enient .
I n any ev ent , your applicat ions fr equent ly need t o accom m odat e users who
connect t o your applicat ion wit h a SQL Ser ver login. This sect ion pr esent s a
sam ple t hat illust rat es t he synt ax for cr eat ing a Connect ion obj ect based on a
SQL Ser ver login.
Befor e rev iew ing t he code for t he procedure t hat illust rat es t he Connect ionSt r ing
synt ax for a SQL Server login, y ou need t o m ak e sure t hat a SQL Serv er login is
available. I f y ou hav e one av ailable, feel free t o r eplace our sam ple login.
Howev er, t he following T- SQL script builds on t he ear lier w ork conduct ed in
Chapt er 7. I t begins by dropping t he vbdot net 1 SQL Ser ver login. This is a t wo-
st ep process. First y ou m ust drop user account s associat ed wit h t he login, and
t hen you can dr op t he account . Aft er dr opping t he account , t he script r e- creat es
it . However, t he new v ersion explicit ly grant s t he vbdot net 1 login access t o t he
Nort hwind dat abase. By r unning t his script in Query Analyzer, y ou ensure t he
availabilit y of vbdot net 1 as a valid SQL Ser ver login for t he Nort hw ind dat abase
wit h passvbdot net 1 as a password.
--vbdotnet1LoginScripts.sql
--Drop vbdotnet1 login, if it exists.
--Ignore message that login doesn’t exist
--or user doesn’t exist in current database.

USE Chapter07
EXEC sp_revokedbaccess ’vbdotnet1’
EXEC sp_droplogin ’vbdotnet1’

--Add vbdotnet1 login with database access
--for the Northwind database.
USE Northwind
EXEC sp_addlogin
    @loginame = ’vbdotnet1’,
    @passwd = ’passvbdotnet1’,
    @defdb = ’Northwind’
EXEC sp_grantdbaccess ’vbdotnet1’

The connect ion sam ple for t his sect ion r uns fr om t he SqlServ er CnnToNort hw ind
procedur e in Module1 of t he My ADODOTNETSam ples solut ion. I n t he m ain
procedur e for Module1, com m ent out all procedur e calls except t he one for t he
SqlServ er CnnToNort hw ind pr ocedur e. Mak e sur e t hat Module1 is t he st art up
obj ect for t he solut ion ( as described in t he pr eceding sect ion) . Then press F5 t o
run t he sam ple.
The SqlServ er CnnToNor t hw ind pr ocedur e has t he sam e general form at as t he one
in t he pr eceding sect ion. The m ost im port ant dist inct ion bet ween t he t wo
procedur es is t he synt ax for t he Connect ionSt ring argum ent . The
Connect ionSt r ing argum ent for t his sam ple r eplaces t he I nt egrat ed Secur it y
elem ent from t he preceding sam ple w it h user id and password elem ent s. When
connect ing w it h a SQL Ser ver login, y ou m ust specify a login nam e and a
password if t here is one. I t ’s com m on pract ice t o r efer t o t he login as a user id.
The follow ing sam ple uses t he vbdot net 1 login and password cr eat ed by t he
preceding T- SQL scr ipt . Aft er y ou r un t he procedur e in t he follow ing sam ple, t he
Debug window w ill display a line t hat echoes t he Connect ionSt r ing argum ent .
Sub SQLServerCnnToNorthwind()
      ’Specify connection string for connection via vbdotnet1
      ’SQL Server login; make sure vbdotnet1 login has access
      ’to the Northwind database via its own account or guest account.
      Dim str1 As String = “Data Source=(local);” & _
            “Initial Catalog=northwind;” & _
            “user id = vbdotnet1; password=passvbdotnet1"
      Dim cnn1 As SqlConnection = _
            New SqlConnection(str1)

     ’Attempt to open Northwind database with vbdotnet1 login.
     cnn1.Open()

     ’Echo connection string.
     Debug.WriteLine(cnn1.ConnectionString)

     ’Close connection object to dispose of it.
     cnn1.Close()

End Sub



Ca t ch ing SqlCon n e ct ion Ex ce pt ion s

When y ou’r e per form ing dat abase work, t here are lot s of opport unit ies for r un-
t im e errors. You can cat ch t he except ions associat ed w it h t hese err ors and
respond appropr iat ely ( ev en if only t o convey t he except ion m essage t o t he user
and av oid an abnorm al end of y our applicat ion) . One way t o generat e a r un- t im e
error w it h t he pr eceding sam ple is t o drop t he login for vbdot net 1. The following
T- SQL scr ipt perform s t his act ion. The script also r em ov es t he guest user account
from t he Nort hwind dat abase. Ther efor e, a user w it h login r ight s t o a SQL Ser ver
inst ance but no special dat a access perm ission t o t he Nort hwind dat abase will not
be able t o connect t o t he Nort hw ind dat abase.
--Remove access to Northwind database by
--vbdotnet1 through own or guest account,
--then drop vbdotnet1 login.
EXEC sp_revokedbaccess ’vbdotnet1’
EXEC sp_revokedbaccess guest
EXEC sp_droplogin @loginame = ’vbdotnet1’

Aft er y ou run t he pr eceding T- SQL script , t he SqlServ er CnnToNort hw ind
procedur e t hat ran successfully in t he preceding sect ion w ill fail. I n fact , it ends
abnorm ally wit h an except ion dialog lik e t he one in Figure 10- 2. I nt er est ingly, t he
addit ional inform at ion in t he dialog about t he except ion is singular ly
uninform at ive— “Syst em error .” Choose Cont inue on t he dialog t o r ecov er from
t he except ion.
   Figu r e 1 0 - 2 . D e fau lt e xce p t ion dialog from a t t e m p t t o con n e ct t o t h e
             N or t h w in d da t a b ase w it h a n in va lid SQL Ser ve r log in .




Ther e is a single SqlClient except ion for all t he run- t im e er rors t hat could happen.
Happily, t his ex cept ion aut om at ically r et ur ns dist inct m essages for differ ent k inds
of er r ors. The Cat chSQLClient Except ion pr ocedure shows an adapt at ion of t he
SQLServ er CnnToNort hw ind pr ocedur e. The adapt at ion is t o place t he Open and
Close m et hods fr om t he SQLSer ver CnnToNort hwind procedur e in t he Try clause
of a Tr y…Cat ch…Finally st at em ent ; t he sam ple om it s t he opt ional Finally clause.
The Cat ch clause dem onst rat es t he sy nt ax for explicit ly refer encing t he SqlClient
except ion and pr int ing t he associat ed m essage.
Sub CatchSQLClientException()
      ’Specify connection string for connection via vbdotnet1
      ’SQL Server login; make sure vbdotnet1 login doesn’t have
      ’access to the Northwind database if you want to test
      ’Try...Catch...Finally statement.
      Dim str1 As String = “Data Source=(local);” & _
             “Initial Catalog=northwind;” & _
             “user id = vbdotnet1; password=passvbdotnet1"
      Dim cnn1 As SqlConnection = _
             New SqlConnection(str1)
      ’Start looking for exceptions.
      Try
             ’Attempt to open Northwind database with vbdotnet1 login.
             cnn1.Open()

           ’Echo connection string.
           Debug.WriteLine(cnn1.ConnectionString)

           ’Close connection object to dispose of it.
           cnn1.Close()

         ’Print default error message because it is
         ’so short and informative.
     Catch er As System.Data.SqlClient.SqlException
         MsgBox(er.Message)
     End Try

End Sub

The Cat chSQLClient Except ion procedure r esides in Module1. You can r un it lik e
t he preceding sam ples. Nam ely , com m ent out t he calls t o ot her pr ocedur es and
rem ov e t he com m ent m ark er for t he Cat chSQLClient Ex cept ion procedur e in t he
m ain procedur e wit hin Module1. Then press F5. Figure 10- 3 shows t he r esult ing
error m essage— an except ion for an invalid vbdot net 1 login. Cont rast t his error
m essage w it h t he one t hat appears in Figure 10- 2. Not ice how m uch m or e
inform at iv e t he second m essage is com pared w it h t he first one. I t pays t o t rap
t he SqlClient except ion! I n addit ion, if your ser v er wer e down, t he sam e
Cat chSQLClient Except ion procedure would det ect it and display a m essage t hat
indicat es t his. Ther e is no need t o t weak t he code. The procedure aut om at ically
t raps t he err or and displays an appropriat e m essage. By t he way, t he m essage
for an unavailable serv er is, “SQL Ser ver does not ex ist or access denied.”

  Figu r e 1 0 - 3 . SqlClie n t ex ce pt ion dia log fr om at t em p t t o conn ect t o t h e
             N or t h w in d da t a b ase w it h a n in va lid SQL Ser ve r login .




Con n e ct in g fr om a W in dow s For m

Now t hat you hav e experience m aking a connect ion t o a SQL Serv er dat abase
wit h t he appr oaches described in t he pr eceding t hr ee sect ions, you’r e probably
wonder ing how t o int egrat e t hese appr oaches wit h a Windows form . Wit h a form ,
users can nam e t he dat abase t o w hich t hey want t o connect and select eit her a
Windows NT account or a SQL Serv er account for m ak ing t he connect ion. Because
it is so easy t o do, t he form should be sm art enough t o include cont rols for a
user id and password only w hen t he user chooses t o use a SQL Ser ver account for
m aking a connect ion t o a SQL Serv er inst ance.
The sam ple for t his sect ion is av ailable as Form 3 in t he My ADODOTNETSam ples
solut ion. I n Solut ion Ex plor er, r ight - click t he solut ion’s nam e and choose
Propert ies. Fr om t he St art up Obj ect dr op- dow n list , select Form 3 and click OK.
Then double- click Form 3.vb in Solut ion Explor er. This opens Form 3 in Design
view. You can st art t he applicat ion by pr essing F5.
Figur e 10- 4 shows t he sam ple’s Windows form inst ance in Design v iew and at r un
t im e in eit her of t w o different configurat ions. The Design v iew appears on t he left .
I t shows Form 3 wit h t hr ee t ext box es, each w it h m at ching label cont rols. The t op
t ext box is for t he dat abase nam e, and t he next t wo t ext box es ar e for t he user id
and password when a user decides t o m ak e a connect ion w it h a SQL Server login.
I assigned * t o t he PasswordChar propert y for t he bot t om t ext box so t hat
ast erisks would m ask charact ers t yped in t he box. The t wo radio but t ons on t he
lower left port ion of For m 3 allow users t o specify whet her t hey want t o m ake a
connect ion based on t heir Windows login account or use a SQL Ser ver login
account t o m ak e t he connect ion. Finally, t he Click event procedur e of t he Login
but t on ( But t on1) m ak es a connect ion t o a SQL Server inst ance according t o w hat
t he user specifies in t he form ’s ot her cont rols.
The t op r ight form in Figur e 10- 4 shows Form 3 when it init ially opens. Not ice t hat
t he default set t ing is for m ak ing a connect ion w it h a Windows login. The Checked
propert y of t he Window s NT radio but t on is set t o True, and j ust one t ext box
appears w it h t he Login but t on below . All a user has t o do is t ype t he dat abase
nam e in t he sole t ext box on t he form . I f t he login at t em pt succeeds, t he sam ple
displays a m essage confirm ing t hat t he connect ion was m ade. A failed at t em pt
m ight r esult because t he Windows login account isn’t valid for t he SQL Ser ver
inst ance. For exam ple, per haps t her e is no cor r esponding SQL Server login for
t he Windows login. Alt ernat iv ely , t he Windows login m ight not have per m ission t o
access t he dat abase nam ed in t he t op t ext box. I n any event , t he applicat ion
ret ur ns t he SqlClient ex cept ion m essage associat ed w it h t he err or t hat block ed
t he connect ion fr om succeeding.
 Figu re 1 0 - 4 . De sig n view an d ru n - t im e view s of a for m t h a t a ccep t s u se r
inp ut a nd m ak e s a con n e ct ion t o a SQL Ser ver d at a ba se ba se d on eit h e r a
                         W in dow s login or a SQL Se r ve r log in .




The bot t om r ight of Figure 10- 4 shows Form 3 r eady t o accept SQL Serv er login
credent ials, including a SQL Ser ver login and it s password. A user can display t he
t ext boxes for t he login and password by click ing t he SQL Ser ver radio but t on
( RadioBut t on2) . Aft er t he user clicks t he Login but t on, t he applicat ion at t em pt s t o
m ake t he connect ion t o t he dat abase nam ed in t he t op t ext box w it h t he
credent ials specified in t he second t wo t ext box es.
Right - click ing Form 3 in Design v iew and choosing View Code opens t he m odule
behind Form 3. This m odule handles bot h form m anagem ent issues, such as
cont r olling t he v isibilit y of t he second and t hird t ext boxes, and ADO.NET issues,
such as handling t he at t em pt t o connect t o a dat abase.
Three event procedur es and a r egular sub pr ocedur e ( Show LabelsBox es) cont rol
t he form ’s appearance. Users can invoke t hese procedur es by r unning Form 3 or
by clicking cont rols on Form 3. For exam ple, t he Form 3_Load ev ent pr ocedur e
checks RadioBut t on1, t he one labeled Windows NT, and calls t he
Show LabelsBoxes procedur e w hile passing it a value of False. This argum ent
causes t he pr ocedur e t o m ake t he second t wo t ext box es and t heir corr esponding
labels inv isible. This appearance for t he form is consist ent wit h t he default
Windows login offer ed by Form 3.
Click ing t he SQL Ser ver radio but t on inv ok es t he RadioBut t on2_CheckedChanged
ev ent procedure. This procedur e m akes t he second and t hird t ext boxes and t heir
labels v isible by passing t he argum ent True t o ShowLabelsBox es. As a result , a
user can ent er a SQL Serv er login and password so t hat t he form can at t em pt t o
m ake a connect ion based on a SQL Serv er inst ead of a Windows login.
Finally, by click ing t he Windows NT radio but t on, t he user inv ok es t he
RadioBut t on1_CheckedChanged ev ent pr ocedure. This procedure m ak es t he
cont r ols for SQL Server login credent ials invisible if t hey ar e show ing. When t he
user clicks t his RadioBut t on1, it indicat es he or she want s t o m ak e a connect ion
wit h a Windows login. Ther efore, Form 3 doesn’t need t o show t he cont r ols for a
SQL Ser ver login.
Private Sub Form3_Load(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load

     ’Set RadioButton1 to Checked for connection via
     ’Windows NT login.
     RadioButton1.Checked = True

     ’Hide login and password controls because they
     ’aren’t necessary with Windows NT login.
     ShowLabelsBoxes(False)

End Sub

Private Sub RadioButton1_CheckedChanged _
    (ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles RadioButton1.CheckedChanged

     ’Hide login and password controls because they
     ’aren’t necessary with Windows NT login.
     ShowLabelsBoxes(False)

End Sub

Private Sub RadioButton2_CheckedChanged _
    (ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles RadioButton2.CheckedChanged

     ’Show login and password controls because they
     ’are necessary for a SQL Server login.
     ShowLabelsBoxes(True)

End Sub

Sub ShowLabelsBoxes(ByVal bolShowEm As Boolean)

     ’Set the visibility of the second and third text
     ’boxes and their labels according to the value
     ’of bolShowEm.
     Label2.Visible = bolShowEm
     TextBox2.Visible = bolShowEm
     Label3.Visible = bolShowEm
     TextBox3.Visible = bolShowEm

End Sub

The follow ing excerpt fr om t he Form 3 m odule shows t he code devot ed t o m ak ing
t he connect ion based on t he radio but t on select ion and t ext box ent r ies. The
excerpt st art s wit h a m odule- lev el declarat ion of t he cnn1 obj ect refer ence as a
SqlConnect ion obj ect . A m odule- level declarat ion isn’t st rict ly necessary in t he
cont ext of t his sam ple, but t his t ype of declarat ion m ak es t he SqlConnect ion
obj ect available t o ot her procedures t hat could use it . I n any ev ent , not ice t hat
t he declarat ion specifies t he full nam e for t he nam espace cont aining t he
SqlConnect ion obj ect r eference. This is because t he m odule doesn’t include an
I m port s st at em ent for t he Syst em .Dat a.SqlClient nam espace. By not using t he
I m port s st at em ent at t he t op of t he Form 3 m odule, t he Cat ch clause in t he
excerpt m ust reference a Syst em except ion inst ead of t he m ore specific SqlClient
except ion. I n spit e of t his dev iat ion from t he sam ple in t he “Cat ching
SqlConnect ion Except ions” sect ion, SqlClient ex cept ions st ill percolat e up t hr ough
t he m ore general Syst em except ion specificat ion.
Aside from t he declarat ion issues for cnn1, t he balance of t he code excerpt is a
st raight forward m ixt ur e of t he code sam ples developed prev iously in t his chapt er.
Based on w het her RadioBut t on1 is checked, t he But t on1_Click ev ent procedure
com poses a connect ion st ring for eit her a Windows or a SQL Serv er login. Then
t he procedure inst ant iat es a connect ion based on t he connect ion st r ing. Wit hin a
Try…Cat ch…Finally st at em ent , t he procedure at t em pt s t o open t he connect ion. I f
t he at t em pt succeeds, t he pr ocedur e displays a m essage confirm ing t he at t em pt
was successful and nam ing t he dat abase. Ot her wise, cont rol flows t o t he Cat ch
clause, and t he procedure displays t he error m essage associat ed wit h t he
except ion. Because SqlClient except ions percolat e up t hrough t he Syst em
except ion, t he m essage is lik ely t o be specific and helpful for diagnosing any
problem s.
‘Using the full namespace name removes the need to
‘start module with Imports System.Data.SqlClient.
Dim cnn1 As System.Data.SqlClient.SqlConnection

Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

     ’Make local variable declarations.
     Dim strDBName As String = TextBox1.Text
     Dim strConnect As String

     ’Compose a connection string for either a Windows
     ’or a SQL Server login.
     If RadioButton1.Checked = True Then
          strConnect = “Data Source=(local);” & _
                      “Initial Catalog=“ & strDBName & _
                      “;Integrated Security=SSPI"
     Else
          Dim strLogin As String = TextBox2.Text
          Dim strPassword As String = TextBox3.Text
          strConnect = “Data Source=(local);” & _
              “Initial Catalog=“ & strDBName & “;” & _
              “user id=“ & strLogin & _
              “; password=“ & strPassword
     End If

     ’Instantiate a SqlConnection object based on the
     ’connection string.
     cnn1 = _
         New System.Data.SqlClient.SqlConnection(strConnect)

     ’Embed the attempt to open the cnn1 object inside a
     ’Try...Catch...Finally statement, and display a
     ’message for the exception if there is one.
     Try
         cnn1.Open()
         MsgBox(“Successfully connected to “ & cnn1.Database & _
             “ database on local server.”)
     Catch er As System.Exception
         MsgBox(er.Message)
     End Try

End Sub




W or k in g w it h Com m a nd a n d Da t a Rea der Obj ect s
One of t he m ost com m on uses for Com m and obj ect s is t o cont ain t he SQL st r ing
t hat defines t he v alues cont ained in a Dat aReader obj ect . Therefore, t his sect ion
drills down on t hat use for Com m and obj ect s. I n t his sect ion, you learn how t o
for m at t he display of values in a Dat aReader obj ect as well as how t o populat e a
Dat aReader w it h eit her a SQL st ring or a st ored procedure. Bey ond t hese t ypical
applicat ions for Com m and obj ect s wit h Dat aReader obj ect s, t he sect ion also
includes a sam ple t hat dem onst rat es how t o use t he Com m and obj ect for dat a
definit ion t asks, such as creat ing a user- defined funct ion. The present at ion of t he
t opic cov ers a special m et hod for Com m and obj ect s t hat is appropriat e when t he
Com m andText propert y for a Com m and obj ect doesn’t r et ur n any values.

D ispla ying Re su lt s in a M e ssa ge Box or t h e Ou t put W indow

I t ’s easy t o put SqlCom m and and SqlDat aReader obj ect s t o use for report ing
result s from a SQL Ser v er dat abase. St art by connect ing t o t he r em ot e dat a
source from which y ou want t o display result s. Nex t declar e a Com m and obj ect as
a SqlCom m and t ype. The Com m and obj ect r equir es t wo input s: a dat abase
connect ion and a source of SQL st at em ent s t o ex ecut e. You can link a Com m and
obj ect t o a Connect ion obj ect when y ou inst ant iat e t he Com m and obj ect . Specify
a dat a source for t he Com m and obj ect t o r et urn wit h eit her a SQL st ring or a
st ored procedure. This capabilit y of com m ands t o t ak e SQL st at em ent s and
st ored procedures allows you t o draw on all dat a access t opics cover ed in
Chapt ers 3 t hr ough 5.
Dat aReader obj ect s read t he result set r et urned by Com m and obj ect s. Use t he
Ex ecut eReader m et hod on a Com m and obj ect t o conv ey it s r esult set t o a
Dat aReader obj ect . Aft er t he inv ocat ion of t he Execut eReader m et hod, you can
ext ract sequent ial rows from a result set w it h t he Read m et hod for t he Dat a-
Reader obj ect . Use one of t he Dat aReader Get m et hods t o ext ract t he value for a
specific colum n int o a dat a t ype designat ed by t he Get m et hod. Colum ns ar e
designat ed w it h index num bers of 0 t hr ough 1 less t han t he num ber of colum ns
in a result set .
The Enum erat eCat egories procedure, w hich appears next , dem onst rat es t he
applicat ion of t hese guidelines for using Com m and and Dat aReader obj ect s. You
can inv ok e t his pr ocedure fr om Module1 in t he MyADODOTNETSam ples solut ion
by adapt ing t he inst r uct ions for running ot her procedur es from Module1. The
procedur e enum erat es Cat egoryI D and Cat egor yNam e v alues from t he Cat egories
t able in t he Nort hw ind dat abase. A com piler const ant , bolOut put Window , perm it s
you t o dir ect t he cont ent s of a Dat aReader obj ect t o eit her a m essage box or t he
Out put window in t he Visual St udio .NET design env ir onm ent . The default value
for bolOut put Window direct s t he Dat aReader cont ent s t o a m essage box.
Aft er assigning a v alue t o t he com piler const ant , t he Enum erat eCat egories list ing
begins by declaring and inst ant iat ing cnn1 as a Connect ion obj ect befor e invok ing
t he obj ect ’s Open m et hod. Next t he procedur e declares cm d1 as a Com m and
obj ect and specifies cnn1 as it s Connect ion propert y w it h t he Creat eCom m and
m et hod for cnn1. The list ing proceeds t o assign a SQL st ring t o t he Com m andText
propert y for cm d1. Wit h an Ex ecut eReader m et hod in a declarat ion for t he drd1
Dat aReader, t he pr ocedur e generat es a r esult set for drd1 based on t he SQL
st ring used t o define cm d1.

                                     N ot e
Throughout t his chapt er , and elsewhere in t he book , I use
generic t er m s int erchangeably when r eferencing specific
classes in t he Syst em .Dat a.SqlClient nam espace. For
exam ple, I use t he t erm Dat aReader t o reference t he m ore
specific class nam e SqlDat aReader . Using t he gener ic t erm
rem inds y ou t hat SqlClient classes hav e par allel classes in
ot her .NET dat a provider s, nam ely t he OLE DB .NET dat a
provider and t he ODBC .NET dat a pr ovider .
Aft er t he conclusion of t he Execut eReader m et hod, t he Dat aReader obj ect is
ready t o expose it s cont ent s t o a Visual Basic .NET applicat ion. The balance of t he
procedur e int r oduces you t o t wo differ ent st rat egies for achiev ing t his. A com piler
I f…Then…Else st at em ent based on a com piler const ant adds one of t wo
st at em ent s t o t he com piled v ersion of t he pr ocedur e. Eit her st at em ent r et urns a
row from t he Dat aReader obj ect , but t hey display t he row in different ways.
Alt hough t he list ing shows bot h t he Then and Else clauses, t he com piled
procedur e cont ains only one or t he ot her clause based on t he com piler const ant
value for bolOut put Window. Before encount er ing t he com piler I f…Then…Else
st at em ent , t he procedur e declares a st r ing const ant t hat can serv e as a t it le for
t he enum erat ed values in a m essage box. The const ant ends w it h a St r Dup
funct ion t hat can duplicat e a st r ing const ant any num ber of t im es. I n t his case,
t he funct ion appends t w o carr iage ret urns t o t he end of t he t ext for t he t it le. The
int r insic const ant , vbCr, denot es t he st ring equivalent of a car r iage r et urn.
Next t he pr ocedur e st ar t s a Do…While st at em ent wit h t he condit ion drd1.Read()
. This condit ion w ill ret urn t he value Tr ue as long as t here ar e r em aining rows in
t he Dat aReader. Aft er t he Read m et hod passes t hr ough all t he rows from t he
drd1 obj ect , t he condit ion r et urns t he value False, w hich causes cont r ol t o pass t o
t he first st at em ent aft er t he Loop st at em ent for t he Do…While st at em ent . The
com piler I f…Then…Else st at em ent com piles one of t wo possible st at em ent s
depending on t he value of bolOut put Window. When bolOut put Window equals it s
default v alue ( False) , t he st at em ent appends Cat egor yI D and Cat egoryNam e
values for t he cur r ent r ow t o a st r ing value. The values for each row end wit h a
carriage r et urn ( vbCr) . I f bolOut put Window equals True, Visual Basic .NET
com piles a differ ent st at em ent t hat sim ply echoes t he r ow values t o t he Out put
window w it h t he Wr it eLine m et hod for a Console obj ect . Not ice t hat t he t wo
com piled st at em ent s use slight ly different t echniques for capt ur ing t he first
colum n value for Cat egoryI D. Bot h st at em ent s use a Get I nt 32 m et hod because
t he SQL Serv er dat a t ype of int for Cat egor yI D is consist ent w it h t he .NET value
t ype of I nt 32, a 32- bit signed int eger. However, t he pat h for adding t he v alues t o
a st ring for display in a m essage box invok es t he ToSt ring m et hod t o conv ert
explicit ly t he I nt 32 num ber t o a st ring. This k ind of conv ersion is prefer red
because it sav es t he t im e for a run- t im e det erm inat ion of how t o finally represent
a r et urned value.
Sub EnumerateCategories()
        ’Compiler constant directing output to Output window
        ’or a message box. Default value is False.
        #Const bolOutputWindow = False

     ’Declare and open connection to Northwind.
     Dim cnn1 As SqlConnection = New _
         SqlConnection(“Data Source=(local);” & _
         “Integrated Security=SSPI;Initial Catalog=northwind”)
     cnn1.Open()

     ’Declare a command and assign a SQL string to it.
     Dim cmd1 As SqlCommand = cnn1.CreateCommand()
     cmd1.CommandText = _
         “SELECT CategoryID, CategoryName FROM Categories"

     ’Declare a data reader and copy result set from SQL string
     ’for cmd1 to drd1.
     Dim drd1 As SqlDataReader = cmd1.ExecuteReader()

     ’Loop through data reader and display in Output
     ’window or message box.
     Dim str1 As String = _
          “Summary of CategoryID and Category Names” _
              & StrDup(2, vbCr)
     Do While drd1.Read()
     #If bolOutputWindow = True Then
          Console.WriteLine(“Category “ & drd1.GetInt32(0) & _
              “ is “ & drd1.GetString(1))
     #Else
          str1 = str1 & “Category “ & _
              drd1.GetInt32(0).ToString & _
              “ is “ & drd1.GetString(1) & vbCr
     #End If
     Loop

     ’Conditionally display results in a message box.
     #If bolOutputWindow = False Then
     MsgBox(str1)
     #End If

     ’Close data reader and connection object references.
     drd1.Close()
     cnn1.Close()

End Sub

Aft er cont rol passes from t he Do…While st at em ent , cont r ol can flow opt ionally t o
a MsgBox funct ion st at em ent for display ing t he st ring com put ed in t he loop. A
com piler I f…Then st at em ent insert s t he MsgBox funct ion int o t he com piled
procedur e if bolOut put Window equals False. Figur e 10- 5 shows t he out com e from
t he procedure w hen t he value of bolOut put Window is False, and Figur e 10- 6 is an
excerpt from t he Out put window generat ed when bolOut put Window is True. No
m at t er which pat h t he procedur e t akes t o generat e r esult s, it ends by closing t he
drd1 and cnn1 obj ect r eferences. You should always per form t hese t asks when
you no longer need a Dat aReader obj ect so t hat SQL Serv er can m ak e t he
connect ion available for ot her requir em ent s.

    Figu r e 1 0 - 5 . Re t u r n for t h e En u m e ra t eCat e gories pr oce du re w h e n
                             b olOu t p u t W ind ow equ a ls Fa lse .
  Figu re 1 0 - 6 . An ex ce r p t from t h e re t u r n for t h e En u m e ra t e Cat e gories
                pr oced u r e w h e n bolOu t pu t W in dow e qu als Tru e.




D ispla ying Row s in Block s fr om a D a t a Re a de r

The preceding sam ple dem onst rat es how conv enient a m essage box can be for
display ing t he cont ent s of a Dat aReader obj ect . However, a single m essage box
can be filled t o it s charact er lim it before it com plet es display ing r esult s from a
Dat aReader obj ect . A w ork ar ound t o t his sit uat ion is t o display y our result s fr om
t he Dat aReader obj ect s in blocks of x rows at a t im e. When y our applicat ion
displays rows in blocks, users can sequent ially page t hr ough a result set t o find
an it em , or it em s, of int erest . Because t he Dat aReader prov ides forward- only
dat a access, you cannot page back , but you can prov ide your users a forward-
only look at som e dat a.
The Enum erat eCust om erI DNam es procedure allows a user t o specify t he num ber
of rows t o show in a m essage box. The procedure r et ur ns t he Cust om er I D and
Com panyNam e colum n values fr om t he Cust om ers t able in t he Nort hw ind
dat abase. You can invoke t he Enum erat eCust om erI DNam es procedur e fr om t he
m ain procedur e in Module1. Launching t his procedur e is slight ly differ ent t han
wit h pr eceding sam ples from Module1. I n t his case, y ou m ust pass along an
argum ent value as you inv ok e t he pr ocedure. The argum ent is for t he m axim um
num ber of rows t o show in a t ext box . The result set fr om t he Com m and obj ect
for a Dat aReader obj ect m ay ext end ov er sev er al blocks and requir e m ult iple
m essage box es. Each m essage box , except t he final one, m ust hold t he m ax im um
num ber of rows per block passed as an argum ent t o t he
Enum er at eCust om erI DNam es pr ocedur e. The final m essage box w ill display fr om
one row up t o t he m axim um num ber of rows.
The Enum erat eCust om erI DNam es procedure st art s in t he sam e general fashion
as t he preceding one in t hat it m ak es a connect ion t o t he Nort hw ind dat abase and
t hen populat es a Dat aReader, drd1, w it h t he result s of a Com m and obj ect , cm d1.
The sole dist inct ion in how t he t wo pr ocedur es st art is t hat t his one has a
different SQL st r ing for t he Com m and obj ect t hat ret urns m or e rows t han t he one
in t he ear lier sam ple. This larger num ber of r ows in t he Dat aReader for t his
sam ple calls for special t reat m ent because a single m essage box cannot display
all it s r ows.
The balance of t he pr ocedur e dem onst rat es one solut ion for t he problem of t oo
m any r ows t o display in a m essage box. Tw o code blocks facilit at e t he solut ion.
The first block it erat es t hr ough t he rows in drd1 in blocks of int Size. The
procedur e obt ains a value for int Size as a passed argum ent from t he procedur e
t hat calls t he Enum erat eCust om erI DNam es pr ocedur e. A user can specify a block
size t hat does fit w it hin a single m essage box no m at t er how m any r ows are in
t he Dat aReader. By click ing OK on each m essage box , t he user can v iew
successive blocks of r ows from t he Dat aReader . The second code block capt ures
any r em aining rows at t he end of a Dat aReader obj ect t hat don’t fill a com plet e
block .
The first code block uses int 1 as a variable t o count t he cum ulat iv e num ber of
rows read fr om t he drd1 Dat aReader. A st ring var iable, st r1, accum ulat es rows in
successive blocks of size int Size. The first code block uses a Do…While st at em ent
wit h a condit ion of drd1.Read() t o pass successively t hrough all t he r ows in t he
drd1 Dat aReader . As t he code block reads each new row, it recom put es st r1 so
t hat t he new row appears at t he bot t om of t he st ring variable. When t he
rem ainder of int 1 div ided by int Size equals 0, t he pr ocedur e accum ulat es a new
block of r ows ( of size int Size) t o display in a m essage box. The expression int1
mod intSize ret urns t he rem ainder of int 1 div ided by int Size. When t he first
code block det ect s t he end of a block of rows, t he st r ing variable st oring row
values is passed t o a MsgBox funct ion as t he m essage argum ent . Aft er print ing
t he m essage, t he pr ocedur e reset s t he st ring v ariable st r1 t o st art a new block of
rows. Then t he w hole process st art s over again.
When no m ore r ows r em ain in t he Dat aReader , t he procedure passes cont r ol t o
t he second code block. This second block st art s by t est ing t o see w het her any
rows rem ain t hat didn’t appear since t he display of t he last m essage box. Any
rem ainder of int 1 div ided by int Size signals undisplayed r ows. I f t her e are any of
t hese r ows, t he second code block passes t he v alue of st r1 t o a MsgBox funct ion
as t he m essage argum ent t o show t hem . The pr ocedur e concludes in t he
st andard way by closing t he Dat aReader obj ect and it s Connect ion obj ect .
Sub EnumerateCustomerIDNames(ByVal intSize As Integer)
      ’Declare and open connection to Northwind.
      Dim cnn1 As SqlConnection = _
            New SqlConnection(“Data Source=(local);” & _
                 “Integrated Security=SSPI;Initial Catalog=northwind”)
      cnn1.Open()

     ’Declare command and assign a SQL string to it, and then
     ’declare a data reader and copy result set from cmd1 to drd1.
     Dim cmd1 As SqlCommand = cnn1.CreateCommand()
     cmd1.CommandText = _
         “SELECT CustomerID, CompanyName FROM Customers"
     Dim drd1 As SqlDataReader = cmd1.ExecuteReader()

     ’Loop through data reader in blocks of intSize and sequentially
     ’display the contents of successive blocks.
     Dim int1 As New Integer()
     Dim str1 As String = _
         “CustomerID and matching CompanyName column values” _
             & StrDup(2, vbCr)
     Do While drd1.Read()
         str1 = str1 & drd1.GetString(0) & vbTab & _
             drd1.GetString(1) & vbCrLf
         int1 += 1
         If (int1 Mod intSize) = 0 Then
             str1 = str1 & StrDup(2, vbCr) & _
                 “Click OK for next “ & _
                 intSize.ToString & “ customers."
             MsgBox(str1, , “CustomerID and Customer Name”)
             str1 = _
                 “CustomerID and matching CompanyName “ & _
                 “column values” & StrDup(2, vbCr)
         End If
     Loop

     ’If a partial block remains at end of data reader contents,
     ’display partial block.
     If (int1 Mod intSize) > 0 Then
         str1 = str1 & StrDup(2, vbCr) _
             & “Click OK to close message box."
         MsgBox(str1, , “CustomerID and Customer Name”)
     End If

     ’Close data reader and connection object references.
     drd1.Close()
     cnn1.Close()

End Sub

Figur e 10- 7 shows t he first and last m essage boxes t hat r esult from r unning t he
Enum er at eCust om erI DNam es pr ocedur e w it h an int Size argum ent value of 25.
The first m essage box cont ains 25 r ows, as do all t he int er vening m essage boxes
up unt il t he last one. The last m essage box shows t he r ows r em aining at t he end
t hat don’t fill an ent ir e block of 25 rows.

      Figu re 1 0 - 7 . Th e first a n d last m e ssa ge box es displa yed b y t h e
                    En u m er a t e Cu st om e r I D N a m e s p roce du r e .




I n vok in g a St or e d Pr oce du r e w it h a Pa r a m e t e r by a SQL
St r in g

I n addit ion t o using SQL st rings t o designat e t he dat a for t he Com m and obj ect s
t hat populat e Dat aReader obj ect s, y ou can also specify a st ored procedur e as t he
source for a Com m and obj ect . Ther e are t wo m ain advant ages t o using st ored
procedur es. First , st ored procedures are com piled. This saves t he ser ver t he t im e
of com piling a SQL st r ing before it can st art t o r et urn dat a for y our Dat aReader
obj ect . Second, st or ed procedur es accept param et ers. This allows t he users of
your applicat ions t o change t he result set r et ur ned at r un t im e.
Ther e ar e t wo approaches t o set t ing param et er values for st or ed procedur es.
Many developers pr efer t o specify a SQL st ring t hat invokes t he st or ed procedure
and passes t he value. Chapt er 4 illust rat es t he synt ax for accom plishing t his, and
we dem onst rat e t he use of t he t echnique in a .NET Fram ework applicat ion w it h
t he sam ple for t his sect ion. A second approach is t o add param et ers w it h t he
.NET Fr am ew ork sy nt ax . This approach allows y ou t o explicit ly specify t he dat a
t ype as y ou pass a param et er. I w ill dem onst rat e t his second approach in t he
next sect ion.
The sam ple for t his sect ion and t he next one depends on t he Cust Order Hist
st ored procedure in t he Nort hw ind dat abase. This pr ocedur e r et urns t he quant it y
of each product order ed by a cust om er. The procedur e t ak es a five- char act er
st ring param et er t o designat e t he Cust om erI D v alue. The result set cont ains a
single r ow for each product ev er order ed by a cust om er. Each r ow cont ains t he
product nam e and quant it y order ed by t he cust om er specified in t he param et er
when y ou inv ok e t he st or ed procedur e. For y our conv enience in underst anding
t he logic of t he Cust OrderHist st ored pr ocedur e, her e’s t he T- SQL code for t he
st ored procedure:
CREATE PROCEDURE CustOrderHist @CustomerID nchar(5)
AS
SELECT ProductName, Total=SUM(Quantity)
FROM Products P, [Order Details] OD, Orders O, Customers C
WHERE C.CustomerID = @CustomerID
AND C.CustomerID = O.CustomerID AND
O.OrderID = OD.OrderID AND OD.ProductID = P.ProductID
GROUP BY ProductName

Two sub pr ocedur es m ake up t he solut ion for displaying t he result s from r unning
t he Cust OrderHist st ored procedure w it h a SQL st ring. The first sub pr ocedur e,
RunCust OrderHist Wit hSt ring, inv ok es t he SQL st ring for t he st or ed pr ocedur e and
creat es a Dat aReader obj ect based on it s result set . RunCust OrderHist Wit hSt r ing
t akes t wo argum ent s— one for t he Cust om erI D v alue and a second for specify ing
t he m ax im um num ber of r ows t o display as a block in a m essage box. This init ial
Visual Basic .NET procedur e:

    •   Creat es a Connect ion obj ect .
    •   I nst ant iat es a Com m and obj ect t hat ex ecut es t he Cust OrderHist st ored
        procedur e while passing a Cust om erI D value as a param et er.
    •   Populat es a Dat aReader based on t he r esult set fr om Cust OrderHist .

Because t he sam ple uses a SQL st r ing t o invoke t he st or ed procedur e and pass a
param et er, t he pr ocess of running a st ored procedur e w it h a param et er is sim ilar
t o j ust specifying a SQL st ring as t he source for t he Com m and obj ect . This
sim ilar it y is t he chief advant age of using t he SQL st ring t o inv ok e t he st or ed
procedur e. One disadvant age of t he approach is t hat t he ser ver has t o com pile
t he T- SQL st at em ent in t he st ring t o invoke t he st ored procedure. Anot her
disadvant age is t hat you don’t get t he benefit of explicit dat a t yping for t he
param et er value at t he client end of t he solut ion. This explicit t yping can allow
you t o cat ch inappropriat e param et er values ear lier in t he solut ion and save
serv er t im e dev ot ed t o det ect ing er r oneous par am et er values as well as passing
back feedback on t he er ror t o t he client .
The solut ion’s second sub pr ocedur e, drdToMessageBox, displays t he r ows in t he
Dat aReader creat ed by RunCust OrderHist Wit hSt ring. The drdToMessageBox
procedur e requires four argum ent s. The first t w o ar e passed by refer ence inst ead
of in t he nor m al Visual Basic .NET way of by value. These argum ent s are for t he
Dat aReader obj ect and it s associat ed Connect ion obj ect . The second t w o
argum ent s ar e passed by value. These are t he Cust om erI D param et er value and
t he value for t he m ax im um num ber of rows t o display in a m essage box . The
design of t his second sub procedure is a direct ext ension of pr ior sam ples wit h
specific adj ust m ent s, such as for t he t it le w it hin a m essage box. A specific benefit
of div iding t he solut ion across t wo sub procedures is t hat w e w ill be able t o r euse
t his second sub pr ocedure in t he nex t sect ion’s sam ple.
Sub RunCustOrderHistWithString(ByVal CustomerID As String, _
      ByVal intSize As Integer)

     ’Declare and open connection to Northwind.
     Dim cnn1 As SqlConnection = _
         New SqlConnection(“Data Source=(local);” & _
             “Integrated Security=SSPI;Initial Catalog=northwind”)
     cnn1.Open()

     ’Declare command with T-SQL for a stored proc with a parameter.
     Dim cmd1 As SqlCommand = _
         New SqlCommand(“EXEC CustOrderHist “ & CustomerID, cnn1)

     ’Declare data reader and populate with result set
     ’from stored procedure.
     Dim drd1 As SqlDataReader = cmd1.ExecuteReader()

     ’Display result set.
     drdToMessageBox(drd1, cnn1, CustomerID, intSize)

End Sub

Sub drdToMessageBox(ByRef drd1 As SqlClient.SqlDataReader, _
    ByRef cnn1 As SqlClient.SqlConnection, _
    ByVal CustomerID As String, _
    ByVal intSize As Integer)

     ’Declare header for report in message box and counter for rows
     ’showing within a message box.
     Dim str1 As String = _
         “Quantities for Products Ordered by “ & _
             CustomerID & StrDup(2, vbCr)
     Dim int1 As Integer

     ’Loop through data reader in blocks of intSize and
     ’sequentially display the contents of successive blocks.
     Do While drd1.Read()
          str1 = str1 & drd1.GetInt32(1) & vbTab _
              & drd1.GetString(0).ToString & vbCrLf
          int1 += 1
          If (int1 Mod intSize) = 0 Then
              str1 = str1 & StrDup(2, vbCr) _
                  & “Click OK for next “ & _
                  intSize.ToString & “ customers."
              MsgBox(str1, , “From CustOrderHist Stored Proc”)
              str1 = _
                  “Quantities for Products Ordered by “ & _
          CustomerID & StrDup(2, vbCr)
          End If
     Loop

     ’If a partial block remains at end of data reader contents,
     ’display partial block.
     If (int1 Mod intSize) <> 0 Then
         str1 = str1 & StrDup(2, vbCr) _
             & “Click OK to close message box."
         MsgBox(str1, , “From CustOrderHist Stored Proc”)
     End If

     ’Close data reader and connection object references.
     drd1.Close()
     cnn1.Close()

End Sub

You can r un t he sam ple defined by t he pr eceding t wo sub pr ocedur es fr om
Module1 in t he My ADODOTNETSam ples solut ion. The sam ple pr ocedur e call in t he
m ain procedur e for inv oking t he first pr ocedur e follows. I t passes t wo ar gum ent s
t o t he RunCust OrderHist Wit hSt r ing pr ocedur e. The first argum ent is a
Cust om erI D value, and t he second argum ent designat es t he m ax im um num ber of
rows t o display in a m essage box. You can obt ain a r esult set t o display for any
Cust om erI D in t he Cust om ers t able t hat has or ders associat ed wit h it . ( Tw o
Cust om erI D values don’t hav e any orders.) The solut ion aut om at ically populat es
t he argum ent list for t he second sub procedure t hat print s t he rows in t he
Dat aReader creat ed by t he RunCust OrderHist Wit hSt r ing pr ocedur e.
RunCustOrderHistWithString(“TORTU", 10)



I n vok in g a St or e d Pr oce du r e w it h a Pa r a m e t e r by I t s N a m e

I t is possible t o inv ok e a st ored procedure and pass it param et er values wit hout
using a SQL st ring. Som e developers w ould count t his as an advant age. The
approach has t he ext ra advant age of st rong dat a t yping for param et er values on
t he client side of a dat abase solut ion. Ther efor e, illegit im at e values can be
det ect ed befor e encount er ing t im e for a r ound- t rip t o t he serv er and wit hout
div ert ing any valuable ser ver t im e t o error pr ocessing. As t he scale of an
applicat ion grows r elat ive t o serv er pr ocessing power and net work t hroughput ,
t hese considerat ions gain significance.
The solut ion t o invoke a st ored procedure w it hout a SQL st r ing requir es you t o
assign t he nam e of t he st ored procedure as t he Com m andText propert y for a
Com m and obj ect . You m ust also designat e Com m andType.St or edProcedur e as
t he Com m andType pr opert y set t ing for t he Com m and obj ect . I f t he st or ed
procedur e requires param et ers, y ou can inv ok e t he Add m et hod for t he
Param et ers collect ion of t he Com m and obj ect t o declare t he param et ers. As wit h
m any Visual Basic . NET m et hods, t he specificat ion for t he Add m et hod of t he
Param et ers collect ion has m ult iple over loaded specificat ions. The one used in t he
sam ple for t his sect ion uses @Cust om erI D t o designat e t he param et er ’s nam e.
The second and t hird ar gum ent s for t he Add m et hod designat e t he @Cust om erI D
param et er as a Unicode fixed lengt h t ext field of 5 charact ers. The sam ple follows
t he param et er declarat ion w it h t he sy nt ax for assigning an act ual value t o t he
param et er. As y ou can see, you use t he param et er’s Value propert y t o per form
t his t ask.
Aside from t he except ions not ed pr ev iously, t he solut ion for running t he
Cust OrderHist st or ed pr ocedur e w it h or w it hout a SQL st r ing is t he sam e. You
creat e t he Connect ion obj ect ident ically , and y ou pass t he ret ur n set fr om t he
Com m and obj ect t o t he Dat aReader obj ect in t he sam e way . Furt herm ore, t his
second- solut ion appr oach uses exact ly t he sam e second sub procedure,
drdToMessageBox, t o display t he result set from t he Cust OrderHist st ored
procedur e in a ser ies of m essage box es.
Sub RunCustOrderHistWithParameter(ByVal CustomerID As String, _
       ByVal intSize As Integer)
     ’Declare and open connection to Northwind.
     Dim cnn1 As SqlConnection = _
         New SqlConnection(“Data Source=(local);” & _
             “Integrated Security=SSPI;Initial Catalog=northwind”)
     cnn1.Open()

     ’Instantiate a command reference pointing at the
     ’CustOrderHist stored proc.
     Dim cmd1 As SqlCommand = _
         New SqlCommand(“CustOrderHist", cnn1)
     cmd1.CommandType = CommandType.StoredProcedure

     ’Declare the parameter with a SqlDbType to eliminate
     ’the need for conversion, then assign the parameter a value.
     Dim prm1 As SqlParameter = _
         cmd1.Parameters.Add(“@CustomerID", SqlDbType.NChar, 5)
     prm1.Value = CustomerID

     ’Declare data reader and populate with its result
     ’set from the stored proc.
     Dim drd1 As SqlDataReader = cmd1.ExecuteReader()

     ’Display result set.
     drdToMessageBox(drd1, cnn1, CustomerID, intSize)

End Sub

You can inv ok e t he RunCust OrderHist Wit hParam et er procedur e fr om t he m ain
procedur e in Module1 for t he My ADODOTNETSam ples solut ion. Sim ply r em ov e it s
com m ent m ar ker and ensure t hat all ot her pr ocedur e calls hav e a com m ent
m ark er preceding t hem .

Cr e a t in g a D a t a ba se Obj e ct w it h a Com m a n d Obj e ct

The Com m and obj ect pr ov ides m or e flex ibilit y t han j ust ret ur ning r esult set s. For
exam ple, y ou can use a Com m and obj ect t o adm inist er a dat abase obj ect on a
SQL Ser ver inst ance. This sect ion dem onst rat es t he capabilit y by adding a new
user - defined funct ion t o t he Nort hw ind dat abase, using it , and t hen r em ov ing t he
user - defined funct ion. For t his dem onst rat ion t o work , your connect ion m ust be
based on a login w it h perm ission t o cr eat e w hat ever user - defined obj ect s you
at t em pt t o creat e or drop. See Chapt er 5 for t he T- SQL synt ax on adding and
rem ov ing user - defined funct ions and Chapt er 7 for a discussion of t he secur it y
associat ed wit h logins t o a SQL Serv er inst ance. I f your login is t he adm inist rat or
for y our local inst ance of SQL Serv er, you hav e appropriat e perm ission t o r un t he
sam ple.
The user - defined funct ion udfDaysDiffLessx in t his sam ple com put es t he
difference bet w een t w o dat es m inus an offset . You can use t he funct ion t o r eport
how m any days lat e an ev ent occur red. For exam ple, if t he st andard for shipping
an order is wit hin 3 day s of t he order dat e, y ou can use t his user - defined funct ion
t o r eport how m any day s aft er t he st andard an order ships.
The Creat eAndI nvok eUDF procedur e in Module1 illust rat es t he Visual Basic .NET
synt ax for creat ing, using, and finally dropping a user - defined funct ion lik e t he
one described. The Creat eAndI nv okeUDF procedur e connect s t o t he Nor t hw ind
dat abase. The pr ocedur e t ak es t wo opt ional argum ent s. ( I f t he user doesn’t
supply v alues for t he ar gum ent s w hen calling t he pr ocedur e, t he pr ocedur e
assigns default values t o t he argum ent s.) The int OrderNo argum ent denot es t he
OrderI D value for t he or der about which y ou seek shipping inform at ion, and t he
st rx argum ent is a st r ing repr esent ing t he offset in days bet ween t w o dat et im e
values.
While som ewhat lengt hy, t he Cr eat eAndI nv okeUDF procedur e design is
st raight forward. I n act ual pract ice, you ar e lik ely t o ext ract t he code for creat ing
a user - defined funct ion int o a separat e sub pr ocedur e. The procedure begins by
m aking a connect ion t o t he Nort hw ind dat abase. Next t he pr ocedur e defines a
SQL st r ing for dr opping any pr ior version of t he udfDaysDiffLessx user- defined
funct ion. The pr ocedure r uns t his st ring from a Com m and obj ect wit h t he
Ex ecut eNonQuery m et hod. I n t he next code block, t he pr ocedur e runs wit h t he
Ex ecut eNonQuery m et hod a second SQL st ring t o creat e a new version of t he
udfDaysDiffLessx user- defined funct ion. Not ice t hat t he user- defined funct ion
includes a param et er t o specify t he offset for t he difference bet w een t w o dat es.
Aft er ensuring t hat t he code for t he user- defined funct ion is t he second SQL
st ring, t he procedure r uns a t hird SQL st r ing t hat inv ok es t he user - defined
funct ion wit hin a quer y st at em ent . The design of t he SQL st r ing for t he query
uses t he st rx argum ent as a var iable so t hat a procedur e calling t he
Creat eAndI nvok eUDF pr ocedur e can dynam ically set t he offset bet w een t wo
dat es. I n addit ion, t he int OrderNo argum ent is a var iable in t he SQL st ring so t hat
a calling procedure can specify t he order via an OrderI D value on w hich t o r eport .
The procedur e uses t he Ex ecut eReader m et hod t o r un t he SQL st r ing in a
Com m and obj ect and passes t he result t o a Dat aReader. Aft er ex ecut ing t he Read
m et hod for t he Dat aReader, a m essage box displays t he shipping inform at ion for
t he order. The procedure concludes by perform ing var ious cleanup chor es,
including r est oring t he Nort hw ind dat abase so t hat t he dat abase no longer has a
user - defined funct ion nam ed udfDaysDiffLessx. I n pract ice, y ou m ay v er y w ell
decide t o keep a user- defined funct ion aft er creat ing it , but t he sam ple runs t his
st ep t o r est or e your init ial copy of t he Nort hw ind dat abase.
Sub CreateAndInvokeUDF( _s
      Optional ByVal intOrderNo As Integer = 10248, _
      Optional ByVal strx As String = “1”)

     ’Declare and open connection to Northwind.
     Dim cnn1 As SqlConnection = _
         New SqlConnection(“Data Source=(local);” & _
             “Integrated Security=SSPI;Initial Catalog=northwind”)
     cnn1.Open()

     ’Define SQL string to drop prior version of user-defined
     ’function, then run the T-SQL batch with ExecuteNonQuery
     ’method for a command.
     Dim str1 As String = _
         “IF EXISTS “ & _
         “(SELECT * “ & _
         “FROM INFORMATION_SCHEMA.ROUTINES “ & _
         “WHERE ROUTINE_NAME = ’udfDaysDiffLessx’) “ & _
         “DROP FUNCTION udfDaysDiffLessx"
     Dim cmd1 As SqlCommand = New SqlCommand(str1, cnn1)
     cmd1.ExecuteNonQuery()

     ’Define SQL string to create a new user-defined function,
     ’then run the T-SQL batch with ExecuteNonQuery method
     ’for a command.
     str1 = “CREATE FUNCTION udfDaysDiffLessx” & _
         “(@date1 as datetime, @date2 as datetime, “ & _
         “@x as Integer) “ & _
         “RETURNS int “ & _
         “AS “ & _
         “BEGIN “ & _
         “Return(DATEDIFF(day,@date1,@date2)-@x) “ & _
         “END"
     cmd1.CommandText = str1
     cmd1.ExecuteNonQuery()

     ’Define a SQL string to use the preceding user-defined
     ’function and accept variables for SQL string
     ’(strx and intOrderNo), then assign SQL string to
     ’CommandText property of command(cmd1).
     Dim strSQL As String
     strSQL = “SELECT LEFT(OrderDate,11) AS ’Order Date’, “ & _
         “LEFT(ShippedDate,11) AS ’Shipped Date’, “ & _
         “dbo.udfDaysDiffLessx(OrderDate, ShippedDate, “ & _
         strx & “) AS ’Days Late’ “ & _
         “FROM Orders “ & _
         “WHERE OrderID = “ & intOrderNo.ToString
     cmd1.CommandText = strSQL

     ’Store result set from SQL string in a data reader and
     ’format its contents for display via a MsgBox function.
     Dim drd1 As SqlDataReader = cmd1.ExecuteReader()
     drd1.Read()
     str1 = “For Order “ & intOrderNo.ToString & vbCr & _
         “OrderDate is “ & drd1.GetString(0) & vbCr & _
         “ShippedDate is “ & drd1.GetString(1) & vbCr & _
         “Days to ship after “ & strx & “ days is “ _
             & drd1.GetInt32(2).ToString
     MsgBox(str1, , _
         “SQL string with a scalar user-defined function”)

     ’Restore the Northwind database by removing the udf.
     str1 = _
         “IF EXISTS “ & _
         “(SELECT * “ & _
         “FROM INFORMATION_SCHEMA.ROUTINES “ & _
         “WHERE ROUTINE_NAME = ’udfDaysDiffLessx’) “ & _
         “DROP FUNCTION udfDaysDiffLessx"
     cmd1.CommandText = str1

     ’Close the data reader so the command can use it.
     drd1.Close()

     ’Execute the SQL string to drop the user-defined function.
     cmd1.Connection = cnn1
     cmd1.ExecuteNonQuery()

     ’Finally, close the connection to the Northwind database.
     cnn1.Close()

End Sub

The line in t he m ain pr ocedur e of Module1 invoking t he Cr eat eAndI nv okeUDF
procedur e specifies an OrderI D of 10249 w it h int OrderNo and an offset of 3 days
wit h st rx . I n r esponse t o invok ing t he Creat eAndI nv ok eUDF procedur e wit h t his
line, t he procedure pr esent s a m essage box lik e t he one in Figur e 10- 8. I f you
were int er est ed in t rack ing perform ance on a next - day deliv er y prom ise, y ou
could replace t he value 3 in t he calling pr ocedur e wit h 1.

           Figu r e 1 0 - 8 . Th e m e ssa ge box displaye d for ru nn in g t h e
  Cre at e An d I n vok e UD F pr ocedu r e w it h t h e ar gu m en t s spe cifie d for it in
                             t h e m a in pr ocedu r e of M od ule1 .
D a t a Ada pt er s, D a t a Se t s, For m s, a n d For m Cont r ols
This sect ion covers how t o place a dat a set behind a Windows form and allow
users t o int er act wit h t he dat a set t hr ough form cont r ols. You will lear n how t o
bind SQL Ser ver dat a t o t he cont r ols on a Windows form . This sect ion cov ers
several t ypical design applicat ions such as at t aching dat a t o t ext boxes, com bo
boxes, and dat a gr ids. The code sam ples and form designs illust rat e how t o
m anage parent - child relat ionships pr ogram m at ically in t he dat a set behind a form
as well as int eract ively for a user t hrough form cont r ols. The sect ion closes wit h a
sam ple t hat dem onst rat es how t o dy nam ically configure a Windows for m based
on t he dat a t hat it has t o show.

Addin g a D a t a Se t t o a For m

A t y pical way of int eract ing w it h dat a from Visual Basic .NET will be fr om
Windows Form s. While you can r eadily present m essage box es t hat show t he
Dat aReader cont ent s, m any applicat ions will r equir e a richer form of dat a int e-
ract iv it y t han t he forwar d- only , r ead- only m odel support ed by t he Dat aReader.
The k ey t o get t ing t o a richer m odel of dat a int eract iv it y is t o place one or m ore
dat a set s in t he m odule behind a form . The dat a set obj ect let s users navigat e
backward and forward in a dat a set . I n addit ion, users can updat e t he dat a for
local use only or at a rem ot e dat a source. Any one dat a set can cont ain m ult iple
t ables, and t he dat a set obj ect perm it s t he ex ist ence of hierarchical r elat ionships
bet ween t he t ables w it hin it .
The k ey t o populat ing a dat a set behind a form wit h dat a fr om a SQL Ser ver
inst ance is t o cr eat e a Dat aAdapt er obj ect t hat point s t o a dat a source on a SQL
Ser ver inst ance. You can represent t he dat a source on t he ser ver w it h a SQL
st ring, a t able nam e, a view, or a st or ed pr ocedur e. As wit h t he Dat aReader
obj ect , y ou can repr esent a SQL st r ing for t he Dat aAdapt er obj ect wit h a
Com m and obj ect . The Dat aAdapt er obj ect has t wo m ain roles. First , it can fill a
dat a set behind a form . That ’s t he focus of t his sect ion. Second, y ou can use a
Dat aAdapt er t o updat e a rem ot e dat a source fr om t he dat a set behind a form .
That ’s t he focus of t he last m aj or sect ion in t his chapt er .
Use t he Dat aAdapt er obj ect ’s Select Com m and propert y t o r efer ence t he
Com m and obj ect specifying t he r em ot e dat a source for a Dat aAdapt er . Recall t hat
one im port ant role for a Dat aAdapt er is t o copy t o t he dat a set behind a form .
Make t he rem ot e dat a source available t hr ough t he Dat aAdapt er by opening t he
connect ion for t he Com m and obj ect . Copy t he dat a fr om t he r em ot e dat a source
t o t he dat a set by inv ok ing t he Fill m et hod of t he Dat aAdapt er. I n t his t ype of
applicat ion, t he Dat aAdapt er r equires t w o argum ent s— one refer encing t he nam e
of t he dat a set behind t he form and t he ot her nam ing t he t able in t he dat a set .
You can designat e t he t ables w it hin a dat a set eit her by an index num ber
indicat ing t he order in which you added t hem t o t he dat a set or by t he nam e t hat
you specify as an argum ent t o t he Fill m et hod.
The Populat e procedure t hat follows illust rat es t he sy nt ax for copy ing a rem ot e
dat a source t o t he dat a set behind a form . This procedur e is in t he m odule behind
Form 4, w hich I will discuss in m or e det ail in t he next sam ple discussion. For now,
j ust underst and t hat t he Populat e pr ocedur e is in a m odule behind a Windows
for m . I ’ll be using sev er al sam ples t hr oughout t he balance of t his chapt er t hat are
variat ions of t his procedure, so I decided t o give t he pr ocedure a sect ion of it s
own t o help y ou focus on it .

                                     N ot e
The code for t he Populat e procedure assum es t he exist ence
of an I m por t s st at em ent at t he t op of t he m odule for t he
Sy st em .Dat a.SqlClient nam espace.
I t ’s com m on t o describe t he Dat aAdapt er as a bridge bet ween a r em ot e dat a
source and t he dat a set behind a form . Ther efor e, t he Populat e pr ocedure st art s
by declaring a Connect ion obj ect , cnn1. The cnn1 obj ect r efer ence point s t o t he
Nort hwind dat abase on t he local inst ance of SQL Serv er . Next t he pr ocedur e
declares and inst ant iat es a Com m and obj ect , cm d1. A SQL st r ing specifies t he
Cat egoryI D, Cat egory Nam e, and Descript ion colum ns fr om t he Cat egor ies t ables
t o designat e t he r esult set from cm d1. The Com m and obj ect cm d1 links t o t he
Cat egor ies t able t hrough t he Connect ion obj ect cnn1. Aft er indir ect ly specify ing
t he Com m andText pr opert y for a Com m and obj ect , t he procedur e inst ant iat es a
Dat aAdapt er obj ect and uses t he dap1 obj ect r eference t o point t o it .
I n order for t he dap1 Dat aAdapt er t o fill t he dat a set behind t he form , t wo
condit ions m ust hold. First , t he Dat aAdapt er needs a Com m and obj ect assigned
t o it s Select Com m and propert y . Assigning cm d1 t o t he Select Com m and propert y
of dap1 sat isfies t his condit ion. Second, t he Dat aAdapt er requires an open
connect ion t o t he Cat egor ies t able in t he Nort hwind dat abase. I nvoking t he Open
m et hod for t he cnn1 obj ect m eet s t his requirem ent . Aft er m eet ing t hese t w o
condit ions, t he procedure invokes t he Fill m et hod for dap1. The argum ent s for t he
m et hod in t he pr ocedur e designat e Cat egor ies as t he nam e of t he Dat aTable
obj ect t hat holds t he result set from cm d1 in t he das1 dat a set . The m odule
behind Form 4 declar es and inst ant iat es das1 as a dat a set at t he m odule level.
This m ak es t he das1 dat a set available for use in all t he pr ocedur es behind a
for m . Of course, it also m eans t hat y ou cannot see t he declarat ion in t he list ing
for t he Populat e pr ocedur e. For y our easy refer ence, I include t he st at em ent
declaring and inst ant iat ing das1 j ust before t he list ing for t he Populat e procedure.
Not ice t hat t he Populat e procedure concludes by closing t he Connect ion obj ect
cnn1. I n cont rast t o t he Dat aReader obj ect , t he dat a set obj ect operat es while
disconnect ed fr om a r em ot e dat a source. Recall t hat t his abilit y t o oper at e w hile
disconnect ed adds t o t he scalabilit y of Visual Basic .NET applicat ions for SQL
Ser ver.
        ’Module-level declaration of data set object.
        Dim das1 As DataSet = New DataSet()

     Sub Populate()
         ’Specify a connection for a data adapter that
         ’fills the data set used on the form.
         Dim cnn1 As SqlConnection = _
             New SqlConnection _
             (“Data Source=(local);” & _
             “Integrated Security=SSPI;” & _
             “Initial Catalog=northwind”)

           ’Specify the command and data adapter that serves
           ’as the source for the data set on the form.
           Dim cmd1 As SqlCommand = _
               New SqlCommand _
               (“SELECT CategoryID, CategoryName, Description “ & _
               “FROM Categories", _
               cnn1)
           Dim dap1 As SqlDataAdapter = New SqlDataAdapter()
           dap1.SelectCommand = cmd1
           cnn1.Open()

           ’Fill the data set (das1) with the data adapter dap1;
           ’the Fill method populates the data set with a table
           ’named Categories.
           dap1.Fill(das1, “Categories”)

           ’Close the connection because a data set is a
           ’disconnected data source.
           cnn1.Close()

     End Sub



Bin din g Con t r ols on a For m t o D a t a

Aft er populat ing t he dat a set behind a for m , y ou’ll want t o reference t he dat a set
wit h t he cont rols on t he form . One way t o accom plish t his is t o bind t he cont r ols
t o t he dat a set . Ther e are t wo st y les of dat a binding for cont rols. Sim ple dat a
binding m aps a colum n in a local dat a source, such as a Dat aTable in a dat a set ,
t o a propert y of a cont r ol, such as t he Text pr opert y of a t ext box. Use t he
Dat aBindings collect ion of a cont rol t o bind cont rol propert ies t o a colum n of
values in a local dat a source. Com plex dat a binding is a second way of binding a
cont r ol t o dat a. For t his st yle of dat a binding, a cont r ol— such as a com bo box, list
box, or dat a grid— binds t o a collect ion of colum ns, such as a Dat aTable in a dat a
set . The sam ple in t his sect ion dem onst rat es bot h approaches for binding cont r ols
t o t he Cat egor ies Dat aTable. The preceding sect ion described t he code t hat
creat ed t he Cat egories Dat aTable in t he das1 dat a set for Form 4.

                                     N ot e
One int erest ing new dev elopm ent w it h Visual Basic .NET is
t he abilit y t o bind any propert y of a visible cont rol, such as
it s BackColor or ForeColor propert y, t o a colum n of dat a. This
feat ur e opens t he possibilit y for a local dat a sour ce
dynam ically cont rolling t he for m at t ing of a form as well as
t he dat a t he form shows.
Figur e 10- 9 shows Form 4. At t he left is t he form in Design v iew . At t he t op r ight
of t he figur e is t he form aft er it init ially opens. The bot t om r ight of t he figur e
shows t he form aft er I select ed Confect ions from t he com bo box. Open Form 4 in
Design v iew by double- click ing Form 4.vb in Solut ion Explor er for t he
MyADODOTNETSam ples solut ion. Right - click t he solut ion’s nam e in Solut ion
Explor er, choose Pr opert ies, and select Form 4 as t he st art up obj ect t o m ake t he
for m easy t o launch ( for exam ple, by pr essing t he F5 k ey ) .
The Design v iew of For m 4 r ev eals t hat t he for m cont ains a com bo box w it h a
label, t w o t ext box es w it h labels, and a but t on. As shown in Chapt er 1, you can
graphically bind cont rols at design t im e. How ev er , Form 4 program m at ically set s
t he dat a binding for t he com bo box and t he t wo t ext box es. On t he ot her hand, I
set several cont r ol feat ures at design t im e. For exam ple, t he Mult iline propert y of
Text Box2 is set t o Tr ue, while t he sam e propert y for Text Box1 has t he default
set t ing, False. The Mult iline propert y set t ing facilit at es Text Box2 show ing
Descript ion colum n values t hat ext end ov er m or e t han one line.

 Figu r e 1 0 - 9 . A de sign- t im e view an d t w o r u n - t im e vie w s of For m 4 . Th e
 t w o t e x t boxe s a r e p rogr a m m e d t o u pd at e t h e ir con t en t s ba se d on t h e
                             se le ct ion fr om t h e com bo b ox .




The init ial v iew of Form 4 shows t hat when it opens it displays t he first cat egory .
Bev erages appears in t he com bo box, and t he t wo t ext boxes show 1 as t he
Cat egoryI D and t he descript ion for t he bev er ages product cat egory. Ther e is
not hing m andat ory about opening t he form for t he first cat egory — any ot her
cat egory w ill w ork equally well. The form synchr onizes t he t wo t ext box es wit h
t he com bo box . For exam ple, select ing Confect ions from t he com bo box r ev ises
t he cont ent display ed in t he t wo t ext boxes t o 3 and t he descript ion for t he
confect ions cat egory .
To bind t he form cont r ols t o dat a set colum ns and m ak e t he t ext boxes
dependent on t he com bo box select ion t akes j ust a few lines of code. I used five
lines of code t o bind t he cont r ols t o dat a set colum n values and set t he cat egory
t hat appears w hen t he form opens. This code appears in a form Load event
procedur e for Form 4 t hat st art s by calling Populat e t o cr eat e t he das1 dat a set
described in t he preceding sect ion.
The ev ent procedure put s das1 t o use by binding t he Text propert y of Text Box1
t o t he Cat egoryI D colum n in t he Cat egor ies Dat aTable. You bind a colum n of
values t o a t ext box propert y by inv ok ing t he Add m et hod for t he Dat aBindings
collect ion of a cont rol. The Add m et hod t ak es a Binding obj ect as an argum ent .
The argum ent s for t he Binding obj ect specify t he Tex t Box propert y t o bind ( Text )
and t he colum n of values t o bind t o t he pr opert y. This sam ple r equir es t wo
argum ent s t o specify t he dat a source t hat binds t o t he t ext box propert y. First
designat e t he dat a set nam e— das1. Second indicat e t he t able nam e and colum n
nam e w it hin t he dat a set t hat y ou want t o bind t o t he propert y. Use a per iod
delim it er t o separat e t he t wo nam es, as in Cat egor ies.Cat egoryI D. The Load
ev ent procedure uses t he sam e sy nt ax t o bind t he Descript ion colum n in t he
Cat egor ies Dat aTable t o t he Text propert y of Text Box 2. Bot h dat a bindings
dem onst rat e t he approach for sim ple dat a binding.
I t t akes a couple of lines t o bind t he com bo box t o t he Cat egor ies Dat aTable.
Act ually, one line does t he binding, but a second line specifies t he v alues t hat t he
com bo box displays for t he user t o m ak e a select ion. Assign a Dat aTable t o t he
Dat aSource propert y of a com bo box t o bind t he com bo box t o t he Dat aTable.
The sy nt ax for specify ing t he Cat egor ies t able used a nam ed argum ent for
denot ing t he t able in t he dat a set . I could also hav e indicat ed t he Cat egor ies t able
by indicat ing it s t able index value, such as das1.Tables(0) . This sy nt ax
depends on t he t able index values not changing. Aft er set t ing t he Dat aSource
propert y for t he com bo box, t he pr ocedur e assigns t he Cat egoryNam e colum n
from t he Cat egories Dat aTable as t he value for t he com bo box t o display w hen
t he user clicks t he cont r ol t o m ak e a select ion.
The final line of t he for m Load event procedur e designat es t he posit ion in a
colum n t hat t he cont r ols on Form 4 bound t o t he first t able in t he das1 dat a set
are t o show when t he form init ially opens. Posit ion 0 point s t o t he first r ow in a
Dat aTable ( for ex am ple, t he Cat egories Dat aTable in t his sam ple) . The Posit ion
propert y belongs t o t he BindingCont ext obj ect associat ed w it h a form . The
keyw ord Me denot es Form 4 in t he last line of t he form Load ev ent pr ocedur e.
Private Sub Form4_Load(ByVal sender As Object, _
       ByVal e As System.EventArgs) Handles MyBase.Load

     ’Call the routine for creating the data set
     ’for the form.
     Populate()

     ’Bind each text box to a different column in the
     ’Categories table of the data set (das1)on the form.
     TextBox1.DataBindings.Add _
        (New Binding(“Text", das1, “Categories.CategoryID”))
     TextBox2.DataBindings.Add _
        (New Binding(“Text", das1, “Categories.Description”))

     ’Bind combo box to Categories table in the
     ’data set (das1) on the form. Because the data set
     ’includes just one table, its index is 0.
     ComboBox1.DataSource = das1.Tables(“Categories”)
     ComboBox1.DisplayMember = “CategoryName"
     Me.BindingContext(das1.Tables(0)).Position = 0

End Sub

The Select edI ndex Changed event procedure for t he com bo box t ak es j ust one line
t o synchr onize t he cont ent s of t he t ext box es wit h t he cat egory nam e a user
select s from t he com bo box. The index values for a com bo box st art at 0 for t he
first it em in t he list for a com bo box. By set t ing t he com bo box’s Select edI ndex
propert y t o t he Posit ion propert y of t he form ’s BindingCont ext obj ect , t he line
posit ions all cont rols on t he form t o t he sam e row a user select ed indir ect ly when
pick ing a cat egory nam e from t he com bo box.
Private Sub ComboBox1_SelectedIndexChanged _
      (ByVal sender As System.Object, _
      ByVal e As System.EventArgs) _
      Handles ComboBox1.SelectedIndexChanged
     ’Use selected combo item as basis for text boxes.
     Me.BindingContext(das1, “Categories”).Position _
         = Me.ComboBox1.SelectedIndex

End Sub



Re por t ing D a t a Bin din gs

When work ing wit h a com plex form wit h m any cont rols w it h sim ple dat a bindings
or a form t hat y ou didn’t dev elop, y ou m ay find it conv enient t o pr int a report on
t he Dat aBindings collect ions for t he cont rols on a form . A but t on on For m 4
inv okes a pr ocedur e t hat generat es such a r eport . The Click event for t his but t on
inv okes a pr ocedur e nam ed Pr int BindingMem berI nfo in Module1. You can also r un
t his procedure fr om out side a form t o report on t he Dat aBindings collect ions for
t he cont rols on a form .
As y ou can see fr om t he follow ing list ing, t he Click event for t he but t on m er ely
calls t he Pr int BindingMem berI nfo procedure. Howev er , t he call also passes a
reference t o Form 4 by using t he k eyw ord Me as an argum ent . The
Print BindingMem ber I nfo procedure in t his sam ple is adapt ed from an ex am ple in
t he Visual Basic .NET Help file. While t he adapt at ion is subt le, it subst ant ially
enhances t he applicabilit y of t he procedure. First , t he adapt at ion works for any
for m r eference passed t o it . The sam ple in t he Help file had t o be copied int o t he
m odule for any form on which you sought a report . Second, you can run t he
adapt ed pr ocedur e ev en if y ou ar en’t in t he form for w hich you seek a report . The
sam ple in t he Help file wor ks only fr om a form t hat a user has open w it h t he
focus.
The Print BindingMem berI nfo pr ocedur e accept s a form r efer ence as an argum ent .
For t he r eferenced form , t he procedure st art s a loop t o pass t hr ough all t he
cont r ols on t he form . Wit hin t he loop for t he cont rols on a form , t he procedur e
runs a second loop t o report any dat a binding for t he cur rent ly select ed cont rol in
t he loop t hr ough t he cont r ols. I f t her e are no dat a bindings for a cont r ol, t he
inner loop m er ely ret ur ns cont rol t o t he out er loop for t he cont rols. When all t he
cont r ols on a form are looped t hr ough, t he Pr int BindingMem berI nfo procedur e
ret ur ns cont r ol t o it s calling pr ocedur e, which is t he Click ev ent for But t on1 on
Form 4 in t he follow ing list ing.
’From module for Form4.
Private Sub Button1_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button1.Click

     ’Display run-time binding settings specified in this module.
     Module1.PrintBindingMemberInfo(Me)

End Sub

‘From Module1.
‘Adapted from Visual Basic .NET Help; the adaptation accommodates
‘any form as a passed argument and facilitates displaying run-time
‘bindings from outside a form.
Sub PrintBindingMemberInfo(ByRef MyForm As Form)
    Dim thisControl As Control
    For Each thisControl In MyForm.Controls
        Dim thisBinding As Binding
        For Each thisBinding In thisControl.DataBindings
            ’Print the control’s name and Binding information.
            Console.WriteLine(ControlChars.Cr + thisControl.ToString(
))
                Dim bInfo As BindingMemberInfo = thisBinding.BindingMembe
rInfo
             Console.WriteLine(“Binding Path “ + ControlChars.Tab _
                              + bInfo.BindingPath)
             Console.WriteLine(“Binding Field “ + ControlChars.Tab _
                              + bInfo.BindingField)
             Console.WriteLine(“Binding Member “ + ControlChars.Tab _
                              + bInfo.BindingMember)
         Next thisBinding
     Next thisControl

End Sub

Figur e 10- 10 shows an excerpt from t he Out put window show ing t he out com e
generat ed by click ing t he Show Bindings but t on in Form 4 j ust aft er t he for m
opens. The out put show s feedback for t he t wo t ext box es. The t ext box report ing
descript ions appears abov e t he one t hat display s t he Cat egoryI D value. Recall
t hat t he form init ially shows dat a for Cat egoryI D 1 when it opens. The cont ent s
for each t ext box reflect t he v alue for t his cat egory . You can also see t hat t he
procedur e ret urns infor m at ion about t he Dat aTable nam e and t he colum n w it hin a
t able t o which each t ext box on t he form binds.

 Figu r e 1 0 - 1 0 . A r ep or t gen e r at e d b y clicking t h e Sh ow Bin din gs bu t t on
                                            on For m 4 .




The Print BindingMem berI nfo pr ocedur e also w orks for form s t hat don’t hav e t he
focus. For exam ple, you can inst ant iat e an inst ance of a form and t hen pass t he
reference for t hat form inst ance t o t he Pr int BindingMem berI nfo pr ocedure. I f t he
referenced form has dat a bindings set at design t im e, t he pr ocedur e w ill generat e
a r eport for t hem . However, t he pr ocedur e w on’t generat e a r eport for a form
t hat set s it s dat a bindings at run t im e, such as in a form Load ev ent pr ocedur e.
Chapt er 1 cont ains a sam ple w it h dat a bindings set at design t im e. I reproduced
t hat form in t he My ADODOTNETSam ples solut ion as Form 2. Figure 10- 11 shows
on it s left Form 2 in Design v iew wit h Tex t Box1 select ed. On t he r ight of Figur e
10- 11 is t he Pr opert ies window for t he select ed t ext box cont rol on t he left . You
can see t hat t he Text pr opert y for t he t ex t box binds t o t he Cat egory I D colum n in
t he Cat egor ies Dat aTable of a dat a set nam ed DsCat egor ies1. The Text propert y
for Text Box2 binds t o t he Cat egory Nam e colum n of t he Cat egor ies Dat aTable in
t he dat a set .

     Figu r e 1 0 - 1 1 . For m 2 de pict in g a d at a b in din g se t a t de sig n t im e .
The follow ing list ing is a short pr ocedur e nam ed ShowForm 2Bindings t hat
dem onst rat es t he synt ax for generat ing a report on t he dat a bindings in Form 2
wit h t he Pr int BindingMem berI nfo procedure. As you can see, t he procedure
declares and inst ant iat es an inst ance of Form 2 wit h t he r efer ence var iable
MyForm . Then t he pr ocedur e passes t hat r efer ence nam e t o t he
Print BindingMem ber I nfo procedure w hen inv ok ing t he r eport ing pr ocedur e. The
report generat ed by t he Print BindingMem berI nfo pr ocedur e in t he Out put w indow
corr ect ly r eflect s t he dat a bindings for t he t w o t ext box es on Form 2.
Sub ShowForm2Bindings()
      Dim MyForm As New Form2()
      PrintBindingMemberInfo(MyForm)

End Sub



Usin g a D a t a Se t w it h Ta ble s in a Pa r e n t - Child Re la t ion ship

I n addit ion t o w or king wit h one dat abase obj ect , such as a t able, y ou can
populat e a dat a set w it h rows fr om t w o or m ore dat abase obj ect s. Each r em ot e
dat abase obj ect cont r ibut es rows t o a dist inct Dat aTable w it hin t he dat a set .
I nst ead of forcing y ou t o j oin one Dat aTable t o anot her t o represent r elat ionships
as wit h ADO r ecordset obj ect s, dat a set s let y ou hierarchically r epr esent t he
relat ionship bet w een t wo t ables. We com m only refer t o hierarchical relat ionships
as parent - child r elat ionships. The sam ple in t his sect ion illust rat es t echniques for
wor k ing w it h t w o Dat aTable obj ect s in a dat a set . I n addit ion, it shows how t o use
a com bo box t o cont r ol t he r ecords t hat are display ed in a dat a gr id cont r ol. This
operat ion depends on filt er ing t he r ows for a Dat aView obj ect on t he select ed
it em in a com bo box. The Dat aView obj ect , in t urn, serv es as t he dat a source for
t he dat a gr id.
The sam ple for t his sect ion r elies on For m 5 in t he My ADODOTNETSam ples
solut ion. Set up t o use it in t he nor m al way . Fir st m ake Form 5 t he st art up obj ect
for t he solut ion. Second double- click Form 5 in Solut ion Explor er t o open Form 5 in
Design v iew. Third r ight - click Form 5 and choose View Code t o expose t he m odule
behind t he form in t he Code Edit or on a t ab labeled Form 5.vb.
Figur e 10- 12 shows t wo views of Form 5. At t he t op is t he form w hen it init ially
opens, show ing t he Bev erages Cat egory Nam e v alue in t he com bo box and
select ed colum ns of inform at ion for product s in t he bev erages cat egory in t he
dat a grid. When a user select s a new it em fr om t he com bo box, t he pr oduct s
appear ing in t he dat a gr id change t o r eflect t he m ost recent ly select ed it em . For
exam ple, t he bot t om of Figur e 10- 12 shows how t he dat a gr id cont ent s changed
when I changed t he com bo box from Bev erages t o Pr oduce.

Figu re 1 0 - 1 2 . Th e com bo box filt e rs t h e row s fr om t h e Produ ce t ab le t h a t
                               a ppe a r in t h e da t a gr id.
The dat a set for Form 5 defines a relat ionship bet ween t he Cat egor ies and
Product s Dat aTable obj ect s. This relat ionship facilit at es expressing t he product
it em s t hat belong t o each cat egory . I nst ead of hav ing t o filt er rows for a
Dat aView , y ou can explicit ly r efer t o r ows in a child t able t hat refer t o t he
curr ent ly select ed r ow in a par ent t able. The but t on labeled Pr int Par ent - Child
Report generat es a t able based on a hierarchical relat ionship bet w een t he
Cat egor ies and Product s Dat aTable obj ect s. Figure 10- 13 shows an excerpt fr om
t he r eport t hat a click of t he but t on generat es in t he Out put w indow . The excerpt
reveals t he Cat egoryI D and Cat egoryNam e v alues for cat egor ies 6 t hrough 8.
Wit hin each cat egory , t he r eport list s t he Pr oduct I D and Product Nam e values t hat
belong t o t he cat egor y.

  Figu re 1 0 - 1 3 . A r e port b ase d on t h e p ar e n t - ch ild r elat ion sh ip be t w e en
                 t h e Ca t e gor ie s a n d Prod u ct s D a t a Tab le obj e ct s.
The Form 5_Load ev ent procedur e populat es t he t wo Dat aTable obj ect s, creat es a
relat ionship bet w een t hem , and binds t he com bo box and dat a grid t o local dat a
sources. However, in or der t o k eep t he logic easy t o follow, I div ided t he logic for
populat ing t he dat a set and cr eat ing a r elat ionship bet w een t he t wo Dat aTable
obj ect s int o t wo separat e pr ocedur es t hat t he form Load ev ent procedur e calls.
The list ing for all t hree of t hese procedures appears next .
The list ing st art s wit h t hree m odule- level declar at ions for a Dat aSet obj ect , a
Dat aView obj ect , and a Relat ion obj ect . I declar e t hese obj ect s at t he m odule
level because t wo or m ore separat e pr ocedur es in t he m odule need t o r efer t o
t hem .
The Populat e procedure fills t he dat a set w it h excerpt s fr om t he Cat egories and
Product s t ables in t he Nort hw ind dat abase. The code for filling t he dat a set wit h
t he excerpt fr om t he Cat egor ies t able exact ly follows t he sam ple code in Form 4.
Howev er, w hen t he Pr oduct s t able is added t o t he dat a set , t he code is short er
because Connect ion and Dat aAdapt er obj ect s ar e alr eady inst ant iat ed and
suit able for reuse. I n addit ion, t he code for t he Product s Dat aTable obj ect follows
t he sam e general logic for specify ing t he Com m and obj ect t hat defines t he
Select Com m and propert y and invok ing t he Fill m et hod t hat was used for t he
Cat egor ies Dat aTable obj ect .
The Relat eProduct sToCat egor ies pr ocedur e relat es t he Product s Dat aTable t o t he
Cat egor ies Dat aTable in a par ent - child hierarchy. The pr ocedur e achiev es t his by
adding a new Dat aRelat ion obj ect t o t he collect ion of all r elat ionships in t he dat a
set . The code for t he pr ocedur e st art s by declar ing t he m at ching colum ns in t he
parent and child t ables. Next t he pr ocedur e inst ant iat es a new relat ionship obj ect
based on t he m at ching colum ns. Figur e 10- 1 shows t hat t he
Dat aRelat ionCollect ion is dir ect ly dependent on t he dat a set obj ect . The
procedur e uses t he Add m et hod for t he Relat ions collect ion of t he das1 dat a set
t o insert t he new r elat ionship inst ant iat ed in t he preceding line int o t he
Dat aRelat ionCollect ion obj ect wit hin t he das1 dat a set .
The Form 5_Load ev ent procedur e st art s by inv ok ing t he Populat e and
Relat eProduct sToCat egories pr ocedur es. These st eps proper ly populat e and
configur e t he dat a set for For m 5. The ev ent pr ocedur e next binds t he com bo box
t o t he Cat egor ies t able and set s t he posit ion t o t he first r ow in t he Cat egor ies
t able. The pr ocedur e uses a Dat aView obj ect w it h a filt er based on t he index for
t he com bo box . To im plem ent t his, t he procedure declares and inst ant iat es t he
dav1 Dat aView obj ect based on t he Product s Dat aTable obj ect . Next it defines a
st ring w it h t he filt er expression. The expr ession designat es all rows from t he
Product s Dat aTable t hat corr espond t o t he index for t he curr ent ly select ed it em in
t he com bo box . Ther e is an offset of 1 bet ween t he index for a com bo box and
t he Cat egory I D values for which t he filt er expr ession account s. By assigning t he
expression in t he st r ing variable ( st rFilt er ) t o t he RowFilt er pr opert y of dav1, t he
procedur e populat es t he dav1 Dat aView obj ect wit h t he r ows m at ching t he
cat egory nam e show ing in t he com bo box . The ev ent pr ocedur e concludes by
assigning t he dav1 Dat aView obj ect t o t he Dat aSource propert y of t he dat a grid.
‘Module-
level declaration of data set,dataview, and datarelation objects.
Dim das1 As DataSet
Dim dav1 As DataView
Dim rel1 As DataRelation

Sub Populate()

     ’Specify a connection for a data adapter that
     ’fills the data set used on the form.
     Dim cnn1 As SqlConnection = _
         New SqlConnection _
         (“Data Source=(local);” & _
         “Integrated Security=SSPI;” & _
         “Initial Catalog=northwind”)

     ’Specify an extract from the Categories table as the source
     ’for a command that supplies a data adapter which serves
     ’as the source for the data set on the form.
     Dim cmd1 As SqlCommand = _
         New SqlCommand _
         (“SELECT CategoryID, CategoryName, Description “ & _
             “FROM Categories", _
             cnn1)
     Dim dap1 As SqlDataAdapter = New SqlDataAdapter()
     dap1.SelectCommand = cmd1
     cnn1.Open()

     ’Fill the data set (das1) with the data adapter dap1;
     ’the Fill method populates the data set with a datatable
     ’named Categories -- notice that the datatable Categories
     ’isn’t the same as the Categories table in the
     ’Northwind database.
     das1 = New DataSet()
     dap1.Fill(das1, “Categories”)

     ’Re-specify the SQL string for the command and the data
     ’adapter to extract columns from the Products table.
     cmd1.CommandText = “SELECT CategoryID, ProductID, “ & _
         “ProductName, UnitsInStock, Discontinued “ & _
         “FROM Products"
     dap1.SelectCommand = cmd1
    ’Create a datatable named Products in the das1 data set
    ’based on an extract from the Products table in the
    ’Northwind database.
    dap1.Fill(das1, “Products”)

    ’Close the connection because a data set only requires
    ’a connection while it is being populated from or
    ’writing updates to a SQL Server data source.
    cnn1.Close()

End Sub

Sub RelateProductsToCategories()

    ’Declare and assign parent and child columns for
    ’relating the Products datatable to the Categories
    ’datatable in the das1 data set.
    Dim parentcol As DataColumn
    Dim childcol As DataColumn
    parentcol = das1.Tables(“Categories”).Columns(“CategoryID”)
    childcol = das1.Tables(“Products”).Columns(“CategoryID”)

    ’Instantiate a datarelation between the
    ’Products and Categories datatables.
    rel1 = New DataRelation _
        (“CategoriesProducts", parentcol, childcol)
    das1.Relations.Add(rel1)

End Sub

Private Sub Form5_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
    ’Run the Populate procedure to download extracts from
    ’the Categories and Products table to a data set for
    ’this form instance.
    Populate()

    ’Form a datarelation between the Categories and Products
    ’datatables in the das1 data set on this form.
    RelateProductsToCategories()

    ’Bind combobox to table 0 (the Categories datatable)
    ’in the das1 data set.
    ComboBox1.DataSource = das1.Tables(0)
    ComboBox1.DisplayMember = “CategoryName"
    Me.BindingContext(das1.Tables(0)).Position = 0

    ’Instantiate a dataview based on the Products datatable
    ’in the das1 data set and filter the view on the basis of
    ’selectedindex value for a combo box.
    dav1 = New DataView(das1.Tables(“Products”))
    Dim strFilter = “CategoryID = “ & _
        (ComboBox1.SelectedIndex + 1).ToString
    dav1.RowFilter = strFilter

    ’Assign the view as the data source for a data grid control.
    DataGrid1.DataSource = dav1

End Sub
The Select edI ndex Changed event procedure for t he com bo box k eeps t he dat a
grid synchronized w henev er a user changes t he cat egor y nam e display ed in t he
com bo box. To accom plish t his, t he ev ent procedure recom put es t he st r ing filt er
for t he new com bo box select ion. Then it assigns t he new st r ing filt er t o t he
RowFilt er pr opert y of t he dav1 Dat aView. This st ep updat es t he dat a grid t o show
new rows t hat m at ch t he m ost recent select ion from t he com bo box.
Private Sub ComboBox1_SelectedIndexChanged _
      (ByVal sender As System.Object, _
      ByVal e As System.EventArgs) _
      Handles ComboBox1.SelectedIndexChanged

     ’Assign filter based on selected item, and
     ’apply the filter to the dataview for the data grid control.
     Dim strFilter = “CategoryID = “ & _
         (ComboBox1.SelectedIndex + 1).ToString
     dav1.RowFilter = strFilter

End Sub

The final unit of code for t his sam ple generat es t he par ent - child report bet ween
cat egor ies and product s in Figure 10- 13. The code t o generat e t he r eport fir es
when a user clicks t he sole but t on on t he form . The Click event procedure for t he
but t on begins by declar ing Dat aRow obj ect s for t he par ent ( pRow ) and child
( cRow ) Dat aTable obj ect s as well as t w o st r ings for lines from t he parent and r ow
dat a sources. Next t he procedure opens a loop t o pass t hr ough successiv e rows in
t he parent dat a source, t he Cat egor ies Dat aTable obj ect . Aft er pr int ing t he
Cat egoryI D and Cat egoryNam e for t he par ent row, t he procedure st art s a loop
t hr ough t he child rows of t he parent t hat m at ch t he cur rent par ent r ow. The
Get ChildRows m et hod r et ur ns t he appr opr iat e r ows. Wit h t he loop for child r ows,
t he procedure print s t he Product I D and Product Nam e v alues for all pr oduct s
m at ching t he cur rent parent row.
Private Sub Button1_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button1.Click

     Dim pRow, cRow As DataRow
     Dim strParentLine, strChildLIne As String

     ’Loop through rows in parent DataTable.
     For Each pRow In das1.Tables(“Categories”).Rows
         strParentLine = pRow(“CategoryID”) & “, “ & _
             pRow(“CategoryName”)
         Console.WriteLine(strParentLine)

            ’Loop through matching rows in child DataTable.
            For Each cRow In pRow.GetChildRows(rel1)
                 strChildLIne = vbTab & cRow(“ProductID”) & _
                     “, “ & cRow(“ProductName”)
                 Console.WriteLine(strChildLIne)
            Next

     Next

End Sub


Cr e a t in g D a t a - Aw a r e For m s

All for m s t hat display dat a are dat a- awar e at one level or anot her . How ev er, t he
m or e a form aut om at ically configur es it self t o t he dat a set behind it , t he m ore
awar e of dat a t hat form is. A form can even change t he dat a behind it in response
t o t he form ’s envir onm ent . I r efer t o t his k ind of int eract ion bet w een a form and
it s associat ed dat a as t he dat a awar eness of a form . This sect ion present s a
sam ple t hat dem onst rat es a higher degree of dat a awar eness t han t he prev ious
ones. I n addit ion, t he sam ple illust rat es how t o use a st or ed procedur e t hat
accept s a param et er t o dynam ically cont r ol t he dat a t hat a form display s.
The sam ple has t wo for m s— Form 1 and Form 6 in t he My ADODOTNETSam ples
solut ions. Form 1 collect s a value designat ing a count ry and passes t he value on
t o Form 6 w hile opening it . When Form 6 opens, it populat es t wo Dat aTable obj ect s
in a dat a set behind it . Bot h Dat aTable obj ect s v ary based on t he value passed t o
t he form . I n t he first Dat aTable obj ect , t he code behind t he form uses t he passed
value as t he param et er value for a st or ed procedur e. This code behind Form 6
assigns t his Dat aTable obj ect t o t he Dat aSource propert y of a com bo box . A
second Dat aTable obj ect relies on a SQL st ring expr ession t hat relies on t he
passed value. This t able doesn’t dir ect ly populat e t hr ee dat a- bound t ext box es on
Form 6. I nst ead, t he t ex t box es bind t o a Dat aView obj ect based on t he second
Dat aTable but filt ered based on t he value in t he com bo box.
As I said, t his sam ple act ually configures Form 6 based on t he dat a. The com bo
box list s t he cit ies in a count ry, which is based on a value passed t o Form 6 from
Form 1. The t hr ee t ext box es display t he Cust om erI D, Cont act Nam e, and Phone
for one or m ore cust om ers wit hin t he cit y display ed in t he com bo box . Form 6
condit ionally shows nav igat ion but t ons for m ov ing am ong t he rows of cont act
dat a wit hin a count ry . I f t her e aren’t at least t w o cust om ers in a cit y , t he form
hides t he navigat ion but t ons. I ncident ally, t his sam ple also dem onst rat es how t o
const ruct nav igat ion but t ons for m oving t hrough t he r ows behind a set of dat a-
bound t ext box es.
Because t he sam ple for t his sect ion uses t wo form s, y ou’ll probably want t o open
bot h Form 1 and Form 6 in Design v iew . You’ll also lik ely want t o v iew t he code
behind each form . The sam ple begins w it h a user r esponding t o Form 1, so m ake
t hat form your st art up obj ect in t he My ADODOTNETSam ples solut ion. However,
befor e launching t he applicat ion successfully, y ou m ust add t he
udpCit iesI nCust om ersCount r y st or ed procedure t o t he Nort hw ind dat abase. The
procedur e ret urns fr om t he Cust om ers t able all t he cit ies w it hin a count ry
specified by a param et er supplied at r un t im e. As is st andard pract ice, t he
follow ing T- SQL script for Query Analyzer drops any pr ior v ersion of t he st ored
procedur e befor e cr eat ing a new version of it . You can run t he script m ost easily
from Quer y Analyzer.
--Work with Northwind database.
USE Northwind
GO

--Remove any prior version of
--udpCitiesInCustomersCountry.
IF EXISTS (SELECT ROUTINE_NAME
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_TYPE = ’PROCEDURE’ AND
    ROUTINE_NAME = ’udpCitiesInCustomersCountry’)
    DROP PROCEDURE udpCitiesInCustomersCountry
GO

--Create new version of udpCitiesInCustomersCountry.
CREATE PROC udpCitiesInCustomersCountry
@country nvarchar (15) = ’USA’
AS
SELECT DISTINCT City
FROM Customers
WHERE Country = @country
GO
Aft er running t he sam ple in t his sect ion, y ou can rer un t he port ion of t he
preceding script t o drop t he udpCit iesI nCust om ersCount r y st or ed procedur e from
t he Nort hw ind dat abase. This act ion w ill allow y ou t o preserv e t he init ial design of
t he Nort hw ind dat abase.
Figur e 10- 14 shows For m 1 on t he left wit h Brazil ent ered as t he count r y. Clicking
t he Open Form 6 but t on opens Form 6 as shown in t he upper right of t he figur e.
I nit ially, t he cit y Cam pinas appears in t he com bo box. Not ice t hat no navigat ional
but t ons appear below t he t ex t boxes. This is because t her e is j ust one cust om er
locat ed in Cam pinas. The com bo box in Form 6 is open t o m ak e São Paulo t he
select ed cit y. The v iew of Form 6 in t he lower right of Figur e 10- 14 shows São
Paulo select ed in t he com bo box, wit h nav igat ional but t ons below t he t ext box es
because t he Cust om ers t able has four cust om er s sit uat ed in São Paulo.

 Figu r e 1 0 - 1 4 . Th is e x am p le of a d a t a - aw a r e for m displa ys n a viga t ion a l
  bu t t on s only w h e n t h e re is m or e t h an on e cu st om e r in a cit y t o view .
  Com bo b ox se le ct ion s ch an ge t h e se t of cit ie s t h a t t h e t e xt b ox e s ca n
                                             sh ow .




Not ice also t he form bor ders in Figure 10- 14. Form 1 appears w it h no border.
Form 6 appears wit h a capt ion, but it has no built - in Minim ize, Max im ize, or Close
but t on. Bot h form s requir e users t o close a form t hrough t he cust om cont rol on
t he form t hat enables t he form close funct ion. This feat ur e is especially
appropriat e in t his design because using t he st andard but t ons can fail t o close t he
applicat ion proper ly. I w ill descr ibe br iefly t he t wo t echniques for m anaging t he
look of t he form s in rev iew ing t he code behind each form .

Th e Code Be h ind For m 1

The code behind Form 1 consist s of t hr ee short event pr ocedur es. The form Load
ev ent set s t he Form Border St y le pr opert y t o None. This r em ov es any sign of a
st andard w indow border . I n t he process, it r em oves t he built - in Close but t on,
which w as t he m ain obj ect iv e of t he pr opert y assignm ent for t his applicat ion.
Users can st ill close t he for m w it h t he cust om but t on labeled Close. This rem ov es
t he form in a way t hat clears any t race of t he applicat ion.
But t on1 is labeled Open Form 6. Click ing t his but t on act ually does a lit t le m or e.
First it inst ant iat es an inst ance of Form 6 so t hat it can assign a value t o a public
variable nam ed Count ry in t he Form 6 class inst ance. The ev ent pr ocedur e copies
t he cont ent s of t he Text propert y for Text Box1 t o t he Count ry variable in t he
Form 6 inst ance. Aft er assigning a value t o t he Count ry var iable, t he ev ent
procedur e opens t he applicat ion’s second form by inv ok ing t he Show m et hod for
t he frm 6 inst ance. Just befor e t he ev ent pr ocedur e concludes, it hides t he cur r ent
for m .
The ev ent procedure for t he Close but t on ex it s t he ent ir e applicat ion w it h t he Exit
m et hod for t he Applicat ion obj ect . An Applicat ion obj ect ’s Ex it m et hod closes all
windows for an applicat ion, but it doesn’t invok e any special code associat ed w it h
t he Close ev ent or t he Closing event for a form inst ance. Therefore, if y ou have
explicit t erm inat ion code associat ed w it h t hose ev ent s, run t he Close m et hod for
any form t hat requires t he code t o r un before invok ing t he Exit m et hod for t he
Applicat ion obj ect .
Private Sub Form1_Load(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles MyBase.Load

     ’Reset border to remove Close button.
     Me.FormBorderStyle = FormBorderStyle.None

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

    Dim frm6 As New Form6()

      ’Open Form6 and hide Form1.
     frm6.Country = TextBox1.Text
     frm6.Show()
     Me.Hide()

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button2.Click

     ’Exit application.
     Application.Exit()

End Sub


Th e Code Be h ind For m 6
The code behind Form 6 st art s wit h som e m odule- lev el declarat ions and an
adapt at ion of t he Populat e pr ocedur e for adding Dat aTable obj ect s t o t he dat a set
behind t he form . The m odule- lev el declarat ions, wit h one except ion, ar e for
obj ect s and values used in m or e t han one procedur e in t he m odule behind Form 6.
The except ion is for t he Count ry var iable. Not ice t hat a Public k eyw ord declares
t his v ar iable so t hat it is available for reference out side t he m odule. Recall t hat
t he Click ev ent for But t on1 in Form 1 assigns a value t o t his im port ant variable.

                                    N ot e
I t ’s necessary t o bot h declar e and inst ant iat e t he dav 1
Dat aView obj ect at t he m odule level t o m ak e it available
across m ult iple pr ocedures. This requir em ent doesn’t exist
for t he das1 dat a set obj ect .
The Populat e procedure for t he Form 6 m odule uses t he
udpCit iesI nCust om ersCount r y st or ed procedure as t he r em ot e dat a source for t he
Cit iesI nCount r ies Dat aTable obj ect . This st ored procedur e r equires an input
param et er. Therefor e, t he synt ax for t he sam ple confirm s t he synt ax for using a
st ored procedure w it h a param et er as t he source for a Dat aTable obj ect . The
Populat e procedure generat es anot her Dat aTable obj ect nam ed Cust om ers-
I nCount r y. This Dat aTable obj ect relies on a SQL st r ing expression t hat com bines
a st ring const ant w it h t he Count r y v ar iable. Because t he code for t he second
Dat aTable r euses elem ent s used t o creat e t he first Dat aTable obj ect , som e
m odificat ions are necessary. I n part icular, t he procedure r especifies t he
Com m andType as t ext and drops t he prm 1 par am et er.
‘Module-level declaration of data set and ‘dataview objects.
Dim das1 As DataSet
Dim dav1 As DataView = New DataView()

‘Boolean for tracking manipulation ComboBox1
‘in form load event.
Dim bolViewSetInFormLoad As Boolean

‘Declare Country publicly so that the variable
‘is available for assignment from another module.
Public Country As String

Sub Populate()

     ’Connect to Northwind database on local server.
     Dim cnn1 As SqlConnection = _
         New SqlConnection(“Data Source=(local);” & _
             “Integrated Security=SSPI;” & _
             “Initial Catalog=northwind”)

     ’Instantiate a command reference pointing at the
     ’udpCitiesInCustomersCountry stored proc; the stored
     ’proc enumerates the cities in countries from the
     ’Customers table.
     Dim cmd1 As SqlCommand = _
         New SqlCommand(“udpCitiesInCustomersCountry", cnn1)
     cmd1.CommandType = CommandType.StoredProcedure

     ’Declare the parameter with a SqlDbType, then assign
     ’the parameter a value based on a public variable
     ’whose value is passed from another form.
     Dim prm1 As SqlParameter = _
         cmd1.Parameters.Add(“@country", SqlDbType.NVarChar, 15)
     prm1.Value() = Country

     ’Assign cmd1 to the SelectCommand property of dap1, then
     ’open dap1.
     Dim dap1 As SqlDataAdapter = New SqlDataAdapter()
     dap1.SelectCommand = cmd1
     cnn1.Open()

     ’Fill the data set das1 with the data adapter dap1;
     ’the Fill method populates the data set with the
     ’udpCitiesInCustomersCountry result set and names
     ’the resulting datatable CitiesInCountry.
     das1 As DataSet = New DataSet()
     dap1.Fill(das1, “CitiesInCountry”)

     ’Specify a second cmd1 CommandText property and
     ’reset cmd1 properties for use with a SQL string
     ’instead of a stored proc with a parameter.
     cmd1.CommandText = “SELECT CustomerID, “ & _
         “ContactName, Phone, City “ & _
         “FROM Customers “ & _
         “WHERE Country = ’” & Country & “‘"
     cmd1.Parameters.Remove(prm1)
     cmd1.CommandType = CommandType.Text
     dap1.SelectCommand = cmd1

     ’Fill a datatable with the SQL string’s
     ’result set.
     dap1.Fill(das1, “CustomersInCountry”)

     ’Close the connection because a data set is a
     ’disconnected data source.
     cnn1.Close()

End Sub

The for m Load ev ent pr ocedur e along w it h t w o ot her sub procedur es t hat it calls
perform s basic set up for Form 6. One of t hese sub procedures is t he Populat e
procedur e, w hich cr eat es a dat a set for t he for m t o use. The ot her called sub
procedur e is t he ShowNav But t ons pr ocedur e, which cont r ols t he v isibilit y of t he
nav igat ion but t ons t hat can appear below t he t ext box es. The
Select edI ndex Changed ev ent pr ocedur e for t he com bo box also calls t he
Show Nav But t ons pr ocedur e w henev er a user m akes a select ion fr om t he com bo
box.
Aft er calling Populat e t o creat e t he das1 dat a set , t he form Load ev ent procedure
st art s t o put t he dat a set t o use by binding t he com bo box t o t he first t able in t he
dat a set wit h an index of 0. This is t he Cit iesI nCount r ies Dat aTable obj ect . Not ice
also t hat t he code explicit ly assigns bot h t he DisplayMem ber and ValueMem ber
propert ies of t he com bo box t o t he only colum n in t he Cit iesI nCount r ies
Dat aTable obj ect . By set t ing t he ValueMem ber propert y , t he m odule can
subsequent ly use t he Select edValue pr opert y for t he com bo box as an indicat or of
t he m ost r ecent select ion from t he com bo box.
The for m Load ev ent pr ocedur e next m oves it s focus t o creat ing t he dav1
Dat aView obj ect t hat t he t hr ee t ext box es bind t o. The dav1 obj ect relies on t he
Cust om ersI nCount ry Dat aTable obj ect . The r eason t he code binds t he t ext box es
t o t he Dat aView obj ect ( inst ead of t he Dat aTable obj ect ) is t hat you can readily
filt er a Dat aView. I n t his case, t he filt er is for t he cit y appearing in t he com bo
box. The st at em ent s binding t he Text pr opert y of each t ext box t o t he Dat aView
colum ns don’t use a t w o- part nam ing conv ent ion ( t ablenam e.colum nnam e) , as is
t he case when y ou bind a t ex t box t o a Dat aTable obj ect in a dat a set . Because a
Dat aView holds j ust one source of rows, a Dat aView obj ect nam e uniquely
ident ifies a source of rows. Recall, howev er , t hat dat a set obj ect s can cont ain
m ult iple Dat aTable obj ect s.
The last t wo blocks of code in t he form Load ev ent pr ocedur e addr ess form at t ing
issues. The first of t hese blocks calls t he Show Nav But t ons procedure wit h t he
count of r ows in dav1 as an argum ent . I f t her e is only one row in dav1, t her e is
no need for nav igat or but t ons ( because t her e is only one r ow t o display ) . Any
count value great er t han 1 will cause t he Show Nav But t ons procedure t o set t he
Visible pr opert y of t he navigat or but t ons t o True so t hat users can brow se t he
dat a for t he differ ent cust om ers in a cit y. The final block of code shows a second
t echnique ( from t he one used in t he m odule for Form 1) t o m ak e t he built - in Close
but t on unavailable. This approach leaves t he capt ion ar ea at t he t op of t he form
so t hat y ou can show t he form ’s Text propert y assignm ent . Set t ing t he form ’s
Cont rolBox pr opert y t o False hides t he built - in Close but t on. However, I found
t hr ough t r ial and er ror t hat I also needed t o have eit her t he Minim izeBox or
Maxim izeBox propert y set t o False. The sam ple clears all t hree built - in cont rols
from t he form .
Private Sub Form6_Load(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles MyBase.Load

     ’Call the routine for creating the data set
     ’for the form.
     Populate()

     ’Bind combo box to the first datatable in das1
     ’on the form. Assign both the displaymember and
     ’valuemember combobox properties to the sole
     ’column in the first datatable.
     ComboBox1.DataSource = das1.Tables(0)
     ComboBox1.DisplayMember = _
         das1.Tables(0).Columns(0).ColumnName
     ComboBox1.ValueMember = _
         das1.Tables(0).Columns(0).ColumnName

     ’Specify a dataview (dav1) based on the
     ’CustomersInCountry dataTable that filters
     ’the datatable based on the selected value
     ’in the combobox when the form opens.
     dav1 = New DataView(das1.Tables(“CustomersInCountry”))
     Dim strFilter = “City = ’” & ComboBox1.SelectedValue & “‘"
     dav1.RowFilter = strFilter

     ’After the form load event sets the dataview’s
     ’filter, reset the Boolean from its default
     ’value of False.
     bolViewSetInFormLoad = True

    ’Bind each text box to a different column in dav1.
     TextBox1.DataBindings.Add _
        (New Binding(“Text", dav1, “CustomerID”))
     TextBox2.DataBindings.Add _
        (New Binding(“Text", dav1, “ContactName”))
     TextBox3.DataBindings.Add _
        (New Binding(“Text", dav1, “Phone”))

     ’Control visibility of navigation buttons.
     ShowNavButtons(dav1.Count)

     ’Reset the form’s ControlBox property
     ’to False (should also set either MinimizeBox
     ’or MaximizeBox to False).
     Me.MinimizeBox = False
     Me.MaximizeBox = False
     Me.ControlBox = False

End Sub

Sub ShowNavButtons(ByVal NavNum As Integer)

     ’Sub procedure to make nav buttons visible
     ’if there is more than one customer in the
     ’selected city.
     If NavNum > 1 Then
          cmdFirst.Visible = True
          cmdPrevious.Visible = True
          cmdNext.Visible = True
          cmdLast.Visible = True
     Else
          cmdFirst.Visible = False
          cmdPrevious.Visible = False
          cmdNext.Visible = False
          cmdLast.Visible = False
     End If

End Sub

Six ev ent pr ocedur es com plet e t he applicat ion. One procedure is for a select ion
from t he com bo box, four m ore ar e for clicks of t he nav igat ion but t ons, and t he
last one is for t he but t on labeled Close. The Select edI ndex Changed event
procedur e for t he com bo box revises t he r ow filt er for t he dav1 Dat aView obj ect if
t he value of bolViewSet I nForm Load is True. This updat es t he dat a bindings for
t he t ext box es so t hey m at ch t he last cit y select ed in t he com bo box. The
condit ional execut ion of t he r ow filt er r ev ision avoids perform ing t he calculat ion
when t he Form 6_Load event procedure is init ially populat ing t he com bo box w it h
values. The event procedur e also calls t he Show Nav But t ons procedure t o show or
hide t he nav igat ion but t ons depending on t he num ber of r ows in t he dav1 obj ect .
The Click event procedures for t he four nav igat ion but t ons assign a differ ent
value t o t he Posit ion pr opert y of t he BindingCont ext obj ect for each t ext box
cont r ol rely ing on a sim ple dat a binding in Form 6. The Click ev ent pr ocedur es for
t he Pr ev ious ( < ) and Next ( > ) but t ons m er ely subt ract 1 from , or add 1 t o, t he
curr ent posit ion. This m ov es t he r ow displayed in t he t ext box es backw ard or
for ward one row. Visual Basic .NET is sm art enough not t o raise an except ion if a
user clicks t he Next but t on when t he Posit ion propert y is already at it s m axim um
set t ing. I n t his case, t he Posit ion propert y value st ays unchanged. The sam e
principle applies t o click s of t he Pr ev ious but t on when t he Posit ion pr opert y is
alr eady at it s m inim um set t ing. Clicks of t he Fir st ( | < ) and Last ( > | ) but t ons
assign t he m inim um and m ax im um values, r espect iv ely, t o t he Posit ion propert y
for t he BindingCont ext obj ect of t he t ext box cont rols.
The Click event procedure for t he Close but t on ( But t on1) ev ent ually closes For m 6
by apply ing t he Close m et hod t o t he Me keyw or d. Howev er, before doing t his, t he
ev ent procedure for But t on1 opens an inst ance of Form 1. Recall t hat Form 1
includes a but t on t hat exit s t he applicat ion. I n addit ion, it is com m on in a
hierarchy of form s t o r et urn t o t he t op- lev el for m before ex it ing an applicat ion.
Private Sub ComboBox1_SelectedIndexChanged _
       (ByVal sender As System.Object, _
       ByVal e As System.EventArgs) _
       Handles ComboBox1.SelectedIndexChanged
    ’Update dataview filter for combobox selection.
    If bolViewSetInFormLoad = True Then
        Dim strFilter = “City = ’” & _
        ComboBox1.SelectedValue & “‘"
        dav1.RowFilter = strFilter
    End If

    ’Control visibility of navigation buttons based
    ’on the outcome of the filter.
    ShowNavButtons(dav1.Count)

End Sub

Private Sub cmdFirst_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles cmdFirst.Click

    ’Move to first record.
    Me.BindingContext(dav1).Position _
        = Me.BindingContext(dav1).Position.MinValue

End Sub

Private Sub cmdPrevious_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles cmdPrevious.Click

    ’Move to previous record.
    Me.BindingContext(dav1).Position -= 1

End Sub

Private Sub cmdNext_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles cmdNext.Click

    ’Move to next record.
    Me.BindingContext(dav1).Position += 1

End Sub

Private Sub cmdLast_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles cmdLast.Click