You are on page 1of 49

2/7/2014 SQL Server 2000 Survival Guide

http://www.akadia.com/services/sqlsrv_programming.html 1/49

SQLServerSurvivalGuide
Content
SQLServerArchitecture
PhysicalDatabaseFilesandFilegroups
RecoveryModel
TransactionLogArchitecture
TruncatingtheTransactionLog
Logtruncationoccursatthesepoints
Thesizeofatransactionlogisthereforecontrolledinoneoftheseways
ShrinkingtheTransactionLog
ExampleTruncating/ShrinkingtheTransactionLog
DatabaseisinFULLRecoveryMode
DatabaseisinSIMPLERecoveryMode
SQLServerOverview
SystemandUserDatabases(=OracleSchema)
SQLServerServices
ReferringObjects
Metadata(DataDictionary)
SQLServerLogonandDatabaseAccess
SQLServerQueryDesigner
SQLServerBatchUtility(osql)
SQLServerProgrammingOverview
LocalVariables
DistributedQueries
FormattingDates
CASEfunction(similartoOracleDECODE)
DynamicallyconstructingSQLStatements
Transactions
TOPnQueries
ShowUserTablesforspecifiedDatabase
ShowPrimaryandForeignKeyofaTable
CreatingandManagingDatabases
DatabaseProperties
Changeaproperty
CreateaDatabase
InformationonDatabases
DataStructures
DatabaseRecoveryModel
CheckExtents,Pages
Traceflags
BackupaDatabase
RestoreaDatabase
CreatingTables
UserdefinedDataTypes
BLOBS
ComputedColumns
GenerateColumnValuewithIdentityProperty
GenerateColumnValuewithNEWIDFunction
CreateTableinspecifiedFileGroup
GeneratingTransactSQLScripts
LoggedandNonloggedBulkCopies
DataIntegrity
DEFAULTConstraint
CHECKConstraint
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 2/49
PRIMARYKEYConstraint
FOREIGNKEYConstraint
DEFAULTObject
RULEObject
DisablingandEnablingConstraints
TableStructure
PagesandExtents
HeapsandtheIndexAllocationMap(IAM)
IndexStructure
NonclusteredIndexes
ClusteredIndexes
SysindexesTable
VerifythesysindexesTable
FullTableScan
NonClusteredIndexRead
ClusteredIndexRead
ClusteredIndexwithNonClusteredIndexRead
PageSplitsinanIndex
PageSplitsdonotoccurinaHeap
DeterminingSelectitivity
DetermineTableStructures
OptimizerStatistics
ManuallyCreatingStatistics
CreateStatisticsforwholeDatabase
ViewIndexStatisticsandevaluatingIndexSelectivity
Views
CreatingViews
Encrypt/DecryptViews
UpdateableViews
IndexedViews
StoredProcedures
PopulateTablewithaStoredProcedure
CheckStoredProcedureProperties
RecompileallStoredProcedures,TriggerthatreferenceaTable
UsingInputParameters
ReturningValuesUsingOutputParameters
ProcessOUTPUTValueandRETURNParameter
Usinglastinsert@@identityforForeignKeyValue
CustomMessagesfromStoredProceduresaddedtoEventlog
EMailInterface
ExtendedStoredProcedures
UserDefinedFunctions
ScalarUserDefinedFunction
MultiStatementTablevaluedFunction
Triggers
INSERTTriggers
DELETETriggers
UPDATETriggers
TransactSQLExamples
ShrinkingtheLogfile
HandlingNULLs
COUNT(*)
NULLValuesinForeignKeys
SQLServerArchitecture
MicrosoftSQLServerdataisstoredindatabases.Thedatainadatabaseisorganizedintothe
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 3/49
logicalcomponentsvisibletousers.Adatabaseisalsophysicallyimplementedastwoormorefiles
ondisk.
Whenusingadatabase,youworkprimarilywiththelogicalcomponentssuchastables,views,
procedures,andusers.Thephysicalimplementationoffilesislargelytransparent.Typically,only
thedatabaseadministratorneedstoworkwiththephysicalimplementation.
EachinstanceofSQLServerhasfoursystemdatabases(master,model,tempdb,andmsdb)and
oneormoreuserdatabases.Someorganizationshaveonlyoneuserdatabase,containingallthe
datafortheirorganization.Someorganizationshavedifferentdatabasesforeachgroupintheir
organization,andsometimesadatabaseusedbyasingleapplication.Forexample,anorganization
couldhaveonedatabaseforsales,oneforpayroll,oneforadocumentmanagementapplication,
andsoon.Sometimesanapplicationusesonlyonedatabaseotherapplicationsmayaccessseveral
databases.
ItisnotnecessarytorunmultiplecopiesoftheSQLServerdatabaseenginetoallowmultipleusers
toaccessthedatabasesonaserver.AninstanceoftheSQLServeriscapableofhandlingthousands
ofusersworkinginmultipledatabasesatthesametime.EachinstanceofSQLServermakesall
databasesintheinstanceavailabletoallusersthatconnecttotheinstance,subjecttothedefined
securitypermissions.
WhenconnectingtoaninstanceofSQLServer,yourconnectionisassociatedwithaparticular
databaseontheserver.Thisdatabaseiscalledthecurrentdatabase.Youareusuallyconnectedto
adatabasedefinedasyourdefaultdatabasebythesystemadministrator.
SQLServerallowsyoutodetachdatabasesfromaninstanceofSQLServer,thenreattachthemto
anotherinstance,orevenattachthedatabasebacktothesameinstance.IfyouhaveaSQLServer
databasefile,youcantellSQLServerwhenyouconnecttoattachthatdatabasefilewithaspecific
databasename.
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 4/49
PhysicalDatabaseFilesandFilegroups
MicrosoftSQLServermapsadatabaseoverasetofoperatingsystemfiles.Dataandlog
informationarenevermixedonthesamefile,andindividualfilesareusedonlybyonedatabase.
SQLServerdatabaseshavethreetypesoffiles:
Primarydatafiles
Theprimarydatafileisthestartingpointofthedatabaseandpointstothe
otherfilesinthedatabase.Everydatabasehasoneprimarydatafile.The
recommendedfilenameextensionforprimary
datafilesis.mdf.
Secondarydatafiles
Secondarydatafilescompriseallofthedatafilesotherthantheprimarydata
file.Somedatabasesmaynothaveanysecondarydatafiles,whileothers
havemultiplesecondarydatafiles.Therecommendedfilenameextensionfor
secondarydatafilesis.ndf.
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 5/49
Logfiles
Logfilesholdalloftheloginformationusedtorecoverthedatabase.There
mustbeatleastonelogfileforeachdatabase,althoughtherecanbemore
thanone.Therecommendedfilenameextensionforlogfilesis.ldf.
SQLServerdoesnotenforcethe.mdf,.ndf,and.ldffilenameextensions,buttheseextensionsare
recommendedtohelpidentifytheuseofthefile.
InSQLServer,thelocationsofallthefilesinadatabasearerecordedinboththemasterdatabase
andtheprimaryfileforthedatabase.Mostofthetimethedatabaseengineusesthefilelocation
informationfromthemasterdatabase.Forsomeoperations,however,thedatabaseengineuses
thefilelocationinformationfromtheprimaryfiletoinitializethefilelocationentriesinthemaster
database.
SQLServerfileshavetwonames:
logical_file_nameisanameusedtorefertothefileinallTransactSQL
statements.
ThelogicalfilenamemustconformtotherulesforSQLServeridentifiersand
mustbeuniquetothedatabase.
os_file_nameisthenameofthephysicalfile.
ItmustfollowtherulesforMicrosoftWindowsNTorMicrosoftWindows
Me,andMicrosoftWindows98filenames.
Theseareexamplesofthelogicalfilenamesandphysicalfilenamesofadatabasecreatedona
defaultinstanceofSQLServer:
SQLServerdataandlogfilescanbeplacedoneitherFATorNTFSfilesystems,butcannotbe
placedoncompressedfilesystems.
UsethefollowingSQLStatementtolistthelogicalandphysicalfilenames:
USEMyDb
SELECTSUBSTRING(name,1,20)Name,
SUBSTRING(filename,1,50)Filename
FROMdbo.sysfiles
NameFilename

MyDb_SystemE:\MsSQLServer\Data\MyDb_System.MDF
MyDb_Log_1E:\MsSQLServer\Data\MyDb_Log_1.LDF
MyDb_Data_1E:\MsSQLServer\Data\MyDb_Data_1.NDF
MyDb_Index_1E:\MsSQLServer\Data\MyDb_Index_1.NDF
IfyouhaveaBackupandyouwouldknow,thelogicalandphysicalfilenameswithinthisBackup,
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 6/49
thenyoucanuseRESTOREFILELISTONLY
RESTOREFILELISTONLYFROM
DISK=N'E:\MsSQLServer\Backup\MyDb.bak'
WITHFILE=7
LogicalName PhysicalName
----------------------------------------------------------------
MyDb D:\sql2005\MSSQL.1\MSSQL\Data\MyDb.mdf
MyDb_log C:\DATA\MyDb_log.ldf
RecoveryModel
SQLServeroffersthreerecoverymodelsforeachdatabase:fullrecovery,simplerecoveryand
bulkloggedrecovery.Therecoverymodelsdeterminehowmuchdatalossisacceptableincaseofa
failureandwhattypesofbackupandrestorefunctionsareallowed.
Mostpeopleeitherselectfullorsimpleforalloftheirdatabasesandjuststickwiththesameoption
acrosstheboard.Inmostcases,selectingthefullrecoverymodelisthesmartestoption,
becauseitgivesyouthegreatestflexibilityandminimizesdatalossintheeventarestorehasto
takeplace.
Althoughusingthefullrecoverymodelmakeslogicalsense,therearereasonswhytheothertwo
optionsareavailable.Wewillfurtherdefinewhytherearethreeoptionsandwhenyoumightwant
tousethedifferentoptionstoprotectyourdatabases.First,let'stakeacloserlookateachmodel.
Simple
Thesimplerecoverymodelallowsyoutorecoverdataonlytothemostrecentfulldatabaseor
differentialbackup.Transactionlogbackupsarenotavailablebecausethecontentsofthe
transactionlogaretruncatedeachtimeacheckpointisissuedforthedatabase.
Full
Thefullrecoverymodelusesdatabasebackupsandtransactionlogbackupstoprovidecomplete
protectionagainstfailure.Alongwithbeingabletorestoreafullordifferentialbackup,youcan
recoverthedatabasetothepointoffailureortoaspecificpointintime.Alloperations,including
bulkoperationssuchasSELECTINTO,CREATEINDEXandbulkloadingdata,arefullyloggedand
recoverable.
BulkLogged
Thebulkloggedrecoverymodelprovidesprotectionagainstfailurecombinedwiththebest
performance.Inordertogetbetterperformance,thefollowingoperationsareminimallyloggedand
notfullyrecoverable:SELECTINTO,bulkloadoperations,CREATEINDEXaswellastextandimage
operations.Underthebulkloggedrecoverymodel,adamageddatafilecanresultinhavingtoredo
workmanuallybasedontheoperationsthatarenotfullylogged.Inaddition,thebulklogged
recoverymodelonlyallowsthedatabasetoberecoveredtotheendofatransactionlogbackup
whenthelogbackupcontainsbulkchanges.
Soonceagain,basedontheinformationaboveitlooksliketheFullRecoverymodelisthewayto
go.Giventheflexibilityofthefullrecoverymodel,whywouldyoueverselectanyothermodel?The
followingfactorswillhelpyoudeterminewhenanothermodelcouldworkforyou:
SelectSimpleif:
Yourdataisnotcritical.
Losingalltransactionssincethelastfullordifferentialbackupisnotanissue.
Dataisderivedfromotherdatasourcesandiseasilyrecreated.
Dataisstaticanddoesnotchangeoften.
SelectBulkLoggedif:
Dataiscritical,butlogginglargedataloadsbogsdownthesystem.
Mostbulkoperationsaredoneoffhoursanddonotinterfere
withnormaltransactionprocessing.
Youneedtobeabletorecovertoapointintime.
SelectFullif:
Dataiscriticalandnodatacanbelost.
Youalwaysneedtheabilitytodoapointintimerecovery.
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 7/49
Bulkloggedactivitiesareintermixedwithnormaltransactionprocessing.
Youareusingreplicationandneedtheabilitytoresynchronizeall
databasesinvolvedinreplicationtoaspecificpointintime.
Switchingrecoverymodels
Forsomedatabases,youmayneedtouseacombinationoftheserecoverymodels.Let'ssayyou
haveacriticalsystemandyoucannotaffordtoloseanydataduringdailyoperationsbutduringoff
hourstherearemaintenancetasksanddataloadsthatusewaytoomuchtransactionlogspaceto
logeverytransaction.Inacaselikethis,youmaywanttoswitchrecoverymodelspriortoyour
maintenancetasks.ThiscanbeautomatedusingTSQLinthejobthatrunsyourmaintenanceor
dataloadtasks.Afterthemaintenancetaskiscompleted,therecoverymodelcanbeswitchedback
again.
Switchingbetweenfullandbulkloggedmodelsisprobablythebestscenarioforchangingrecovery
modelsandalsothesafestandeasiest.Youcanswitchfromanyrecoverymodeltoanother
recoverymodel,butpriortooraftertheswitch,youmayneedtoissueadditionaltransactionlogor
fullbackupstoensureyouhaveacompletebackupset.
ALTERDATABASENorthwindSETRECOVERYFULL
GO
TransactionLogArchitecture
EveryMicrosoftSQLServer2000databasehasatransactionlogthatrecordsalltransactions
andthedatabasemodificationsmadebyeachtransaction.Thisrecordoftransactionsandtheir
modificationssupportsthreeoperations:
Recoveryofindividualtransactions
IfanapplicationissuesaROLLBACKstatement,orifSQLServerdetectsan
errorsuchasthelossofcommunicationwithaclient,thelogrecordsareused
torollbackthemodificationsmadebyanincompletetransaction.
RecoveryofallincompletetransactionswhenSQLServerisstarted.
IfaserverrunningSQLServerfails,thedatabasesmaybeleftinastate
wheresomemodificationswereneverwrittenfromthebuffercachetothe
datafiles,andtheremaybesomemodificationsfromincompletetransactions
inthedatafiles.WhenacopyofSQLServerisstarted,itrunsarecoveryof
eachdatabase.Everymodificationrecordedinthelogwhichmaynothave
beenwrittentothedatafilesisrolledforward.Everyincompletetransaction
foundinthetransactionlogisthenrolledbacktoensuretheintegrityofthe
databaseispreserved.
Rollingarestoreddatabaseforwardtothepointoffailure
Afterthelossofadatabase,asispossibleifaharddrivefailsonaserver
thatdoesnothaveRAIDdrives,youcanrestorethedatabasetothepointof
failure.Youfirstrestorethelastfullordifferentialdatabasebackup,andthen
restorethesequenceoftransactionlogbackupstothepointoffailure.Asyou
restoreeachlogbackup,SQLServerreappliesallthemodificationsrecorded
inthelogtorollforwardallthetransactions.Whenthelastlogbackupis
restored,SQLServerthenusestheloginformationtorollbackall
transactionsthatwerenotcompleteatthatpoint.
TruncatingtheTransactionLog
Iflogrecordswereneverdeletedfromthetransactionlog,thelogicallogwouldgrowuntilitfilled
alltheavailablespaceonthedisksholdingthephysicallogfiles.Atsomepointintime,oldlog
recordsnolongernecessaryforrecoveringorrestoringadatabasemustbedeletedtomakeway
fornewlogrecords.Theprocessofdeletingtheselogrecordstoreducethesizeofthelogicallogis
calledtruncatingthelog.
Theactiveportionofthetransactionlogcanneverbetruncated.Theactiveportionofthelogisthe
partofthelogneededtorecoverthedatabaseatanytime,somusthavethelogimagesneededto
rollbackallincompletetransactions.Itmustalwaysbepresentinthedatabaseincasetheserver
failsbecauseitwillberequiredtorecoverthedatabasewhentheserverisrestarted.Therecordat
thestartoftheactiveportionofthelogisidentifiedbytheminimumrecoverylogsequencenumber
(MinLSN).
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 8/49
Therecoverymodelchosenforadatabasedetermineshowmuchofthetransactionloginfrontof
theactiveportionmustberetainedinthedatabase.AlthoughthelogrecordsinfrontoftheMinLSN
playnoroleinrecoveringactivetransactions,theyarerequiredtorollforwardmodificationswhen
usinglogbackupstorestoreadatabasetothepointoffailure.Ifyouloseadatabaseforsome
reason,youcanrecoverthedatabyrestoringthelastdatabasebackup,andthenrestoringevery
logbackupsincethedatabasebackup.Thismeansthatthesequenceoflogbackupsmustcontain
everylogrecordthatwaswrittensincethedatabasebackup.Whenyouaremaintainingasequence
oftransactionlogbackups,nologrecordcanbetruncateduntilafterithasbeenwrittentoalog
backup.
ThelogrecordsbeforetheMinLSNareonlyneededtomaintainasequenceoftransactionlog
backups.
Inthesimplerecoverymodel,asequenceoftransactionlogsisnotbeingmaintained.Alllog
recordsbeforetheMinLSNcanbetruncatedatanytime,exceptwhileaBACKUPstatementisbeing
processed.NO_LOGandTRUNCATE_ONLYaretheonlyBACKUPLOGoptionsthatarevalidfora
databasethatisusingthesimplerecoverymodel.
Inthefullandbulkloggedrecoverymodels,asequenceoftransactionlogbackupsisbeing
maintained.ThepartofthelogicallogbeforetheMinLSNcannotbetruncateduntilthoselogrecords
havebeencopiedtoalogbackup.
Logtruncationoccursatthesepoints
AtthecompletionofanyBACKUPLOGstatement.
Everytimeacheckpointisprocessed,providedthedatabaseisusingthesimple
recoverymodel.Thisincludesbothexplicitcheckpointsresultingfroma
CHECKPOINTstatementandimplicitcheckpointsgeneratedbythesystem.The
exceptionisthatthelogisnottruncatedifthecheckpointoccurswhenaBACKUP
statementisstillactive
Transactionlogsaredividedinternallyintosectionscalledvirtuallogfiles.Virtuallogfilesarethe
unitoftruncation.Whenatransactionlogistruncated,alllogrecordsbeforethestartofthe
virtuallogfilecontainingtheMinLSNaredeleted
Thesizeofatransactionlogisthereforecontrolledinoneoftheseways
Whenalogbackupsequenceisbeingmaintained,scheduleBACKUPLOGstatements
tooccuratintervalsthatwillkeepthetransactionlogfromgrowingpastthedesired
size.
Whenalogbackupsequenceisnotmaintained,specifythesimplerecoverymodel.
Thisillustrationshowsatransactionlogthathasfourvirtuallogs.Theloghasnotbeentruncated
afterthedatabasewascreated.Thelogicallogstartsatthebeginningofthefirstvirtuallogandthe
partofvirtuallog4beyondtheendofthelogicalfilehasneverbeenused.
Thisillustrationshowshowtheloglooksaftertruncation.Therowsbeforethestartofthevirtuallog
containingtheMinLSNrecordhavebeentruncated.
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 9/49
Truncationdoesnotreducethesizeofaphysicallogfile,itreducesthesizeofthelogicallogfile.
ShrinkingtheTransactionLog
Thesizeofthelogfilesarephysicallyreducedwhen:
ADBCCSHRINKDATABASEstatementisexecuted.
ADBCCSHRINKFILEstatementreferencingalogfileisexecuted.
Anautoshrinkoperationoccurs
Shrinkingalogisdependentonfirsttruncatingthelog.Logtruncationdoesnotreducethesizeofa
physicallogfile,itreducesthesizeofthelogicallogandmarksasinactivethevirtuallogsthatdo
notholdanypartofthelogicallog.Alogshrinkoperationremovesenoughinactivevirtuallogsto
reducethelogfiletotherequestedsize.
Theunitofsizereductionisavirtuallog.Forexample,ifyouhavea600MBlogfilethathasbeen
dividedintosix100MBvirtuallogs,thesizeofthelogfilecanonlybereducedin100MB
increments.Thefilesizecanbereducedtosizessuchas500MBor400MB,butitcannotbe
reducedtosizessuchas433MBor525MB.
Virtuallogsthatholdpartofthelogicallogcannotbefreed.Ifallthevirtuallogsinalogfilehold
partsofthelogicallog,thefilecannotbeshrinkuntilatruncationmarksoneormoreofthevirtual
logsattheendofthephysicallogasinactive.
Whenanyfileisshrunk,thespacefreedmustcomefromtheendofthefile.Whenatransactionlog
fileisshrunk,enoughvirtuallogsfromtheendofthefilearefreedtoreducethelogtothesize
requestedbytheuser.Thetarget_sizespecifiedbytheuserisroundedtothenexthighestvirtual
logboundary.Forexample,ifauserspecifiesatarget_sizeof325MBforoursample600MBfile
with100MBvirtuallogfiles,thelasttwovirtuallogfilesareremovedandthenewfilesizeis400
MB.
InSQLServer,aDBCCSHRINKDATABASEorDBCCSHRINKFILEoperationattemptstoshrinkthe
physicallogfiletotherequestedsize(subjecttorounding)immediately:
Ifnopartofthelogicallogisinthevirtuallogsbeyondthetarget_sizemark,the
virtuallogsafterthetarget_sizemarkarefreedandthesuccessfulDBCCstatement
completeswithnomessages.
Ifpartofthelogicallogisinthevirtuallogsbeyondthetarget_sizemark,SQL
Serverfreesasmuchspaceaspossibleandissuesaninformationalmessage.The
messagetellsyouwhatactionsyouneedtoperformtogetthelogicallogoutofthe
virtuallogsattheendofthefile.Afteryouperformthisaction,youcanthen
reissuetheDBCCstatementtofreetheremainingspace.
Forexample,assumethata600MBlogfilewithsixvirtuallogshasalogicallogstartinginvirtual
log3andendinginvirtuallog4,whenyouexecuteaDBCCSHRINKFILEstatementwitha
target_sizeof275MB:
Virtuallogs5and6arefreedimmediatelybecausetheyholdnoportionofthelogicallog.Tomeet
thespecifiedtarget_size,however,virtuallog4shouldalsobefreed,butcannotbecauseitholds
theendportionofthelogicallog.Afterfreeingvirtuallogs5and6,SQLServerfillstheremaining
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 10/49
partofvirtuallog4withdummyrecords.Thisforcestheendofthelogfiletovirtuallog1.Inmost
systems,alltransactionsstartinginvirtuallog4willbecommittedwithinseconds,meaningthatall
oftheactiveportionofthelogmovestovirtuallog1,andthelogfilenowlookslikethis:
TheDBCCSHRINKFILEstatementalsoissuesaninformationalmessagethatitcouldnotfreeallthe
spacerequested,andindicatethatyoucanexecuteaBACKUPLOGstatementtomakeitpossibleto
freetheremainingspace.Oncetheactiveportionofthelogmovestovirtuallog1,aBACKUPLOG
statementwilltruncatetheentirelogicallogthatisinvirtuallog4:
Becausevirtuallog4nolongerholdsanyportionofthelogicallog,ifyounowexecutethesame
DBCCSHRINKFILEstatementwithatarget_sizeof275MB,virtuallog4willbefreedandthesizeof
thephysicallogfilereducedtothesizerequested.
ExampleShrinkingtheTransactionLog
Hereisanexamplehowbothsstepscanbeperformed:
DatabaseisinFULLRecoveryMode
#ForthisexampleweswitchtoFULLMode
USEmaster
ALTERDATABASEMyDbSETRECOVERYFULL
GO
Thecommand(s)completedsuccessfully.
#AddlogicalDevicesfortheBackup(Thedirectoriesmustexist!)
EXECsp_addumpdevice'disk','MyDb_dat',
'C:\ProgramFiles\MicrosoftSQLServer\MSSQL\BACKUP\MyDb_dat.dat'
GO
(1row(s)affected)
'Disk'deviceadded.
EXECsp_addumpdevice'disk','MyDb_log',
'C:\ProgramFiles\MicrosoftSQLServer\MSSQL\BACKUP\MyDb_log.dat'
GO
(1row(s)affected)
'Disk'deviceadded.
#CreateaBackupbeforeTruncating/Shrinking
BACKUPDATABASEMyDbTOMyDb_dat
GO
Processed26392pagesfordatabase'MyDb',file'MigrationBasisplus_Data'onfile9.
Processed1pagesfordatabase'MyDb',file'MigrationBasisplus_Log'onfile9.
BACKUPDATABASEsuccessfullyprocessed26393pagesin9.756seconds(22.161MB/sec).
BACKUPLOGMyDbTOMyDb_log
GO
Processed1pagesfordatabase'MyDb',file'MigrationBasisplus_Log'onfile5.
BACKUPLOGsuccessfullyprocessed1pagesin0.065seconds(0.039MB/sec).
#TruncatetheTransactionLog
BACKUPLOGMyDbWITHTRUNCATE_ONLY
GO
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 11/49
Thecommand(s)completedsuccessfully.
#DroplogicalDevices
sp_dropdevice'MyDb_dat'
GO
Devicedropped.
sp_dropdevice'MyDb_log'
GO
Devicedropped.
#GettheNameoftheTransactionLog
USEMyDb
SELECTnameFROMdbo.sysfiles
GO
#ShrinkthephysicalSizeoftheTransactionLogto20MB
USEMyDb
DBCCSHRINKFILE(MigrationBasisplus_Log,20)
GO
#Avoidatransactionloggrowsunexpectedly
USE[master]
GO
ALTERDATABASE[MyDb]MODIFYFILE
(NAME=N'MyDb_Log_1',SIZE=772096KB,
MAXSIZE=921600KB,FILEGROWTH=10240KB)
GO
DatabaseisinSIMPLERecoveryMode
#ForthisexampleweswitchtoSIMPLEMode
USEmaster
ALTERDATABASEMyDbSETRECOVERYSIMPLE
GO
Thecommand(s)completedsuccessfully.
#AddlogicalDevicefortheBackup(Thedirectoriesmustexist!)
EXECsp_addumpdevice'disk','MyDb_dat',
'C:\ProgramFiles\MicrosoftSQLServer\MSSQL\BACKUP\MyDb_dat.dat'
GO
(1row(s)affected)
'Disk'deviceadded.
#CreateaBackupbeforeTruncating/Shrinking
BACKUPDATABASEMyDbTOMyDb_dat
GO
Processed26392pagesfordatabase'MyDb',file'MigrationBasisplus_Data'onfile9.
Processed1pagesfordatabase'MyDb',file'MigrationBasisplus_Log'onfile9.
BACKUPDATABASEsuccessfullyprocessed26393pagesin9.756seconds(22.161MB/sec).
#TruncatetheTransactionLog
BACKUPLOGMyDbWITHTRUNCATE_ONLY
GO
Thecommand(s)completedsuccessfully.
#DroplogicalDevice
sp_dropdevice'MyDb_dat'
GO
Devicedropped.
#GettheNameoftheTransactionLog
USEMyDb
SELECTnameFROMdbo.sysfiles
GO
Thecommand(s)completedsuccessfully.
#ShrinkthephysicalSizeoftheTransactionLogto20MB
USEMyDb
DBCCSHRINKFILE(MigrationBasisplus_Log,20)
GO
SQLServerOverview
SystemandUserDatabases(=OracleSchema)
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 12/49
Master(ControlsotherDatabases)
Model(TemplatefornewDatabases)
Tempdb(TemporaryStorage)
Msdb(SchedulingandJobInformation)
Distribution(ReplicationInformation)
SQLServerServices
SQLServerincludesfourservices
MSSQLServer(DatabaseEngine)
SQLServerAgent(JobScheduling)
MSDTC,DistributedTransactionCoordinater(DistributedQueries,2PCommit)
MicrosoftSearch(FullTextEngine)
ReferringObjects
select*from<server>.<database>.<owner>.object
select*fromNorthwind..customer(Ownerismissing)
Metadata(DataDictionary)
SystemStoredProcedures(sp_)
sp_helpdb[db_name]
InfosforDatabase
sp_help[anyobject]
InfosanTables,Procedures,etc
sp_helpindex[table_name]
ShowIndexesfortable_name
sp_who
ShowSystemActivity
SELECT@@spid
WhichismyServerProcessID?
selectuser_name(),db_name(),@@servername
DatabaseUserName,Database,
Server?
sp_helpdbNorthwind
sp_helpEmployees
SystemTables(sys...)
master..syslogins
AvailableloginAccounts
master..sysmessages
AvailableSystemError/Warnings
master..sysdatabases
AvailableDatabasesonSQLServer
sysusers
AvailableWin2000Users,SQLServerUsers
sysobjects
AvailableObjectsintheDatabase
usemaster
select*fromsysdatabases
usenorthwind
select*fromsysobjects
wherextype='U'
SystemFunctions(seeQA:CommonObjects)
DB_ID(DbName)
GetDatabaseID
USER_NAME(id)
GetUserName
GETDATE()
GetSystemDate
usemaster
select*fromsysdatabases
usenorthwind
select*fromsysobjects
wherextype='U'
SchemaViews(SystemTableIndependentViews)
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 13/49
select*frominformation_schema.tables
TablesinaDatabase
select*frominformation_schema.columns
ColumnsinaDatabase
select*frominformation_schema.table_privileges
PrivilegesonTables
SQLServerLogonandDatabaseAccess
1. LoginAuthentication(WindowsAuthenticationorMixedMode)
2. MappingofOSUsertoDatabaseUserAccountsandRoles
AllW2KAdministratorsareautomaticallyallowedtologon.Thiscanbedisabledbydeleting
the\BUILTIN\AdministratorsintheSecurityTabonSQLServerLevel.
WindowsAuthenticationistheDefault(TrustedConnection)
DatabaseUsers
SpecifictoSQLServer,notthesameastheWindowsUserorLoginAccount!
Normallydboisused,mappingisdoneonDatabaseLevel(EM:Users)
Roles
FixedServerRoles(e.g.SystemAdministrators=DBA)onSQLServerLevel
FixedDatabaseRole(e.g.db_owner=Hasallpermissionsinthedatabase)
Fixedserverrole Description
sysadmin CanperformanyactivityinSQLServer.
serveradmin Cansetserverwideconfigurationoptions,shutdownthe
server.
setupadmin Canmanagelinkedserversandstartupprocedures.
securityadmin CanmanageloginsandCREATEDATABASEpermissions,
alsoreaderrorlogsandchangepasswords.
processadmin CanmanageprocessesrunninginSQLServer.
dbcreator Cancreate,alter,anddropdatabases.
diskadmin Canmanagediskfiles.
bulkadmin CanexecuteBULKINSERTstatements.
Youcangetalistofthefixedserverrolesfromsp_helpsrvrole,andgetthespecificpermissionsfor
eachrolefromsp_srvrolepermission.
Fixeddatabaserole Description
db_owner Hasallpermissionsinthedatabase.
db_accessadmin CanaddorremoveuserIDs.
db_securityadmin Canmanageallpermissions,objectownerships,rolesand
rolememberships.
db_ddladmin CanissueALLDDL,butcannotissueGRANT,REVOKE,or
DENYstatements.
db_backupoperator CanissueDBCC,CHECKPOINT,andBACKUPstatements.
db_datareader Canselectalldatafromanyusertableinthedatabase.
db_datawriter Canmodifyanydatainanyusertableinthedatabase.
db_denydatareader Cannotselectanydatafromanyusertableinthe
database.
db_denydatawriter Cannotmodifyanydatainanyusertableinthedatabase.
Example
USENorthwind
GO
sp_addlogin@loginame='Akadia',@passwd='Akadia',@defdb='Northwind'
GO
sp_grantdbaccess'Akadia'
GO
sp_addrole'Masters'
GO
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 14/49
sp_addrolemember'Masters','Akadia'
GO
GRANTSELECTONEmployeesTOMasters
GO
SQLServerQueryDesigner
QueryDesignercanbeusedtographicalybuildaSQLstatement,forexamplethesyntaxforan
ANSIOUTERJoinSyntax.Followthefollowingsteps:
1. OpenEnterpriseManager
2. SelectatableinthedesiredDatabase/Tables
3. RightClickanselect"OpenTable/Query",theQueryDesigneropens.
4. RightClickanemptyareaonthediagramoane,andthenclick"AddTable"
5. Chooseanothertable,intheSQLPaneyoucannowseethegeneratedSQLstatement
6. ForanOUTERJoin,rightclicktheRelationandchoose"Allrowsfrom<table>"
SQLServerBatchUtility(osql)
Theutilityosqlisacommandlinetooltorunbatches.ForexampleyoucancreatetheCREDIT
databaseasfollows:
osql/E/S<ServerName>/n/icreabase.sql>>credit.log
/*
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 15/49
** CREABASE.SQL
**
** Drop and Recreate the credit database.
*/
PRINT 'Begin CREABASE.SQL'
GO
USE master
SET nocount ON
GO
IF db_id('credit') IS NOT NULL
DROP DATABASE credit
GO
CREATE DATABASE [credit]
ON PRIMARY (NAME = N'credit_Data',
FILENAME = N'E:\MSSQL\Data\credit_Data.MDF',
SIZE = 50,
FILEGROWTH = 10%)
LOG ON (NAME = N'credit_Log',
FILENAME = N'E:\MSSQL\Data\credit_Log.LDF',
SIZE = 1,
FILEGROWTH = 10%)
GO
ALTER DATABASE credit
ADD FILEGROUP CreditTablesFG
GO
ALTER DATABASE credit
ADD FILEGROUP CreditIndexesFG
GO
ALTER DATABASE credit
ADD FILE (
NAME = CreditTables,
FILENAME = 'E:\MSSQL\Data\CreditTables.ndf',
SIZE = 8MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 50MB )
TO FILEGROUP CreditTablesFG
ALTER DATABASE credit
ADD FILE (
NAME = CreditIndexes,
FILENAME = 'E:\MSSQL\Data\CreditIndexes.ndf',
SIZE = 8MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 50MB )
TO FILEGROUP CreditIndexesFG
GO
PRINT ' '
IF db_id('credit') IS NOT NULL
PRINT 'CREATED DATABASE "credit"'
ELSE
PRINT 'CREATE DATABASE "credit" FAILED'
PRINT ' '
GO
osql -S localhost -U zahn -P soladur -n -i Sample_Script2.sql
USE Northwind
IF EXISTS (SELECT * FROM sysobjects WHERE type = 'U' AND name = 'Sample1')
DROP TABLE sample1
IF EXISTS (SELECT * FROM sysobjects WHERE type = 'V' AND name = 'Sample_View')
DROP VIEW Sample_View
GO
CREATE TABLE Sample1
(
cust_no int NOT NULL,
fname char(10) NOT NULL,
lname char(15) NOT NULL
)
GO
CREATE VIEW Sample_View
AS
SELECT cust_no, lname FROM Sample1
GO
INSERT Sample1 VALUES ( 100, 'Adam' , 'Barr' )
INSERT Sample1 VALUES ( 200, 'John' , 'Chen' )
INSERT Sample1 VALUES ( 300, 'Cindy' , 'Durkin' )
INSERT Sample1 VALUES ( 400, 'Roger' , 'Harui' )
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 16/49
INSERT Sample1 VALUES ( 500, 'Ryan' , 'LaBrie' )
SELECT * FROM Sample_View
SQLServerProgrammingOverview
LocalVariables
usenorthwind
go
declare@lastnamevarchar(20)
declare@firstnamevarchar(20)
set@lastname='Dodsworth'
select@firstname=FirstName
fromemployees
wherelastname=@lastname
print@firstname+''+@lastname
go
DistributedQueries
PerformadistributedquerytoretrieveinformationfromtheEMPtableonOracle9.2.0usindMAG1
astheTNSNAMES.ORAconnectionstring.
1.CreatethelinkedServer
SpecifyRemoteLogin/Password(system/manager)inLinkedServerProperties.
EXECsp_addlinkedserver
@server='MAG1',
@srvproduct='Oracle9.2.0',
@provider='MSDAORA',
@datasrc='MAG1'
GO
2.StartDistributedQueryusingtheSQLPassTroughFunctionOPENQUERY
SELECT*FROMOPENQUERY
(MAG1,'SELECT*FROMscott.emp')
GO
FormattingDates
UseCONVERT()withdateformatnumber,seeCONVERT()
selectconvert(varchar(30),getdate,104)
>19.10.2002
SETDATEFORMAT
Setstheorderofthedateparts(month/day/year)forenteringdatetimeorsmalldatetimedata.
SETDATEFORMATmdy
GO
DECLARE@datevarsmalldatetime
SET@datevar='12/31/0212:30:00'
SELECT@datevar
GO
>2002123112:30:00
CASEfunction(similartoOracleDECODE)
WithinaSELECTstatement,asimpleCASEfunctionallowsonlyanequalitychecknoother
comparisonsaremade.ThisexampleusestheCASEfunctiontoalterthedisplayofbookcategories
tomakethemmoreunderstandable.
USE pubs
GO
SELECT Category =
CASE type
WHEN 'popular_comp' THEN 'Popular Computing'
WHEN 'mod_cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad_cook' THEN 'Traditional Cooking'
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 17/49
ELSE 'Not yet categorized'
END,
CAST(title AS varchar(25)) AS 'Shortened Title',
price AS Price
FROM titles
WHERE price IS NOT NULL
ORDER BY type, price
COMPUTE AVG(price) BY type
GO
Category Shortened Title Price
------------------- ------------------------- ---------------------
Business You Can Combat Computer S 2.9900
Business Cooking with Computers: S 11.9500
Business The Busy Executive's Data 19.9900
Business Straight Talk About Compu 19.9900
avg
=====================
13.7300
SELECTau_fname,au_lname,
CASEstate
WHEN'CA'THEN'California'
WHEN'KS'THEN'Kansas'
WHEN'TN'THEN'Tennessee'
WHEN'OR'THEN'Oregon'
WHEN'MI'THEN'Michigan'
WHEN'IN'THEN'Indiana'
WHEN'MD'THEN'Maryland'
WHEN'UT'THEN'Utah'
ENDASStateName
FROMpubs.dbo.authors
ORDERBYau_lname
SELECTstatementwithsimpleandsearchedCASEfunction
WithinaSELECTstatement,thesearchedCASEfunctionallowsvaluestobereplacedintheresult
setbasedoncomparisonvalues.Thisexampledisplaystheprice(amoneycolumn)asatext
commentbasedonthepricerangeforabook.
USE pubs
GO
SELECT 'Price Category' =
CASE
WHEN price IS NULL THEN 'Not yet priced'
WHEN price < 10 THEN 'Very Reasonable Title'
WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
ELSE 'Expensive book!'
END,
CAST(title AS varchar(20)) AS 'Shortened Title'
FROM titles
ORDER BY price
GO
PriceCategoryShortenedTitle

NotyetpricedThePsychologyofCo
NotyetpricedNetEtiquette
VeryReasonableTitleTheGourmetMicrowav
VeryReasonableTitleYouCanCombatCompu
DynamicallyconstructingSQLStatements
UseEXECUTEwithLiteralsandVariables
ChangeOwnershipofTablesinDatabaseNorthwindtodbo:
useNorthwind
select'EXECUTEsp_changeobjectowner'''+name+''',''dbo'''fromsysobjects
wheretype='U'
DynamicallyconstructandrunaSELECTstatement
declare@dbnamevarchar(30)
declare@tblnamevarchar(30)
set@dbname='Northwind'
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 18/49
set@tblname='Products'
EXECUTE
('USE'+@dbname+'SELECT*FROM'+@tblname)
Transactions
TransactionsmustbeincludedinaBEGINTRAN,COMMITTRANBlock.UpdatedRowsintheblock
arelockedforothersessionsaslongasthetransactionisnotcommited.OpenanotherQAandtry
toselect,theselectwaits!
USENorthwind
BEGINTRAN
LockRows
UPDATECustomersSETContactName='HowardSnyder_Updated'
WHERECustomerID='GREAL'
IF(@@ERROR<>0)
BEGIN
RAISERROR('Transactionfailed',16,1)
ROLLBACKTRANSACTION
END
COMMITTRANSACTION
SELECTContactNameFROMCustomersWHERECustomerID='GREAL'
TOPnQueries
TheTOPkeywordspecifiesthatthefirstnrowsoftheresultsetarereturned.IfORDERBYis
specified,therowsareselectedaftertheresultsetisordered.nisthenumberofrowsto
return,unlessthePERCENTkeywordisspecified.PERCENTspecifiesthatnisthepercentageofrows
intheresultsetthatarereturned.Forexample,thisSELECTstatementreturnsthefirst10cities,in
alphabeticsequence,fromtheOrderstable:
SELECTDISTINCTTOP10ShipCity,ShipRegion
FROMOrders
ORDERBYShipCity
ShowUserTablesforspecifiedDatabase
usenorthwind
select*frominformation_schema.tables
wheretable_type='BASETABLE'
ShowPrimaryandForeignKeyofaTable
select * from information_schema.key_column_usage
where table_name = 'Orders'
CreatingandManagingDatabases
DatabaseProperties
SELECTDATABASEPROPERTYEX('Northwind','IsAutoShrink')
Value Description Valuereturned
Collation
Defaultcollationnameforthe
database.
Collationname
IsAnsiNullDefault
DatabasefollowsSQL92rules
forallowingnullvalues.
1=TRUE
0=FALSE
NULL=Invalidinput
IsAnsiNullsEnabled
Allcomparisonstoanull
evaluatetounknown.
1=TRUE
0=FALSE
NULL=Invalidinput
IsAnsiPaddingEnabled
Stringsarepaddedtothesame
lengthbeforecomparisonor
insert.
1=TRUE
0=FALSE
NULL=Invalidinput
IsAnsiWarningsEnabled
Errororwarningmessagesare
issuedwhenstandarderror
conditionsoccur.
1=TRUE
0=FALSE
NULL=Invalidinput
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 19/49
IsArithmeticAbortEnabled
Queriesareterminatedwhenan
overflowordividebyzeroerror
occursduringqueryexecution.
1=TRUE
0=FALSE
NULL=Invalidinput
IsAutoClose
Databaseshutsdowncleanly
andfreesresourcesafterthe
lastuserexits.
1=TRUE
0=FALSE
NULL=Invalidinput
IsAutoCreateStatistics
Existingstatisticsare
automaticallyupdatedwhenthe
statisticsbecomeoutofdate
becausethedatainthetables
haschanged.
1=TRUE
0=FALSE
NULL=Invalidinput
IsAutoShrink
Databasefilesarecandidates
forautomaticperiodicshrinking.
1=TRUE
0=FALSE
NULL=Invalidinput
IsAutoUpdateStatistics
Autoupdatestatisticsdatabase
optionisenabled.
1=TRUE
0=FALSE
NULL=Invalidinput
IsCloseCursorsOnCommitEnabled
Cursorsthatareopenwhena
transactioniscommittedare
closed.
1=TRUE
0=FALSE
NULL=Invalidinput
IsFulltextEnabled
Databaseisfulltextenabled. 1=TRUE
0=FALSE
NULL=Invalidinput
IsInStandBy
Databaseisonlineasreadonly,
withrestorelogallowed.
1=TRUE
0=FALSE
NULL=Invalidinput
IsLocalCursorsDefault
Cursordeclarationsdefaultto
LOCAL.
1=TRUE
0=FALSE
NULL=Invalidinput
IsMergePublished
Thetablesofadatabasecanbe
publishedforreplication,if
replicationisinstalled.
1=TRUE
0=FALSE
NULL=Invalidinput
IsNullConcat
Nullconcatenationoperand
yieldsNULL.
1=TRUE
0=FALSE
NULL=Invalidinput
IsNumericRoundAbortEnabled
Errorsaregeneratedwhenloss
ofprecisionoccursin
expressions.
1=TRUE
0=FALSE
NULL=Invalidinput
IsQuotedIdentifiersEnabled
Doublequotationmarkscanbe
usedonidentifiers.
1=TRUE
0=FALSE
NULL=Invalidinput
IsRecursiveTriggersEnabled
Recursivefiringoftriggersis
enabled.
1=TRUE
0=FALSE
NULL=Invalidinput
IsSubscribed
Databasecanbesubscribedfor
publication.
1=TRUE
0=FALSE
NULL=Invalidinput
IsTornPageDetectionEnabled
MicrosoftSQLServer
detectsincompleteI/O
operationscausedbypower
failuresorothersystem
outages.
1=TRUE
0=FALSE
NULL=Invalidinput
Recovery
Recoverymodelforthe
database.
FULL=fullrecovery
model
BULK_LOGGED=bulk
loggedmodel
SIMPLE=simple
recoverymodel
SQLSortOrder
SQLServersortorderID
supportedinpreviousversions
ofSQLServer.
0=Databaseisusing
Windowscollation
>0=SQLServersort
orderID
Status
Databasestatus. ONLINE=databaseis
availableforquery
OFFLINE=database
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 20/49
wasexplicitlytaken
offline
RESTORING=
databaseisbeing
restored
RECOVERING=
databaseisrecovering
andnotyetreadyfor
queries
SUSPECT=database
cannotberecovered
Updateability
Indicateswhetherdatacanbe
modified.
READ_ONLY=data
canbereadbutnot
modified
READ_WRITE=data
canbereadand
modified
UserAccess
Indicateswhichuserscan
accessthedatabase.
SINGLE_USER=only
onedb_owner,
dbcreator,or
sysadminuserata
time
RESTRICTED_USER=
onlymembersof
db_owner,dbcreator,
andsysadminroles
MULTI_USER=all
users
Version
Internalversionnumberofthe
MicrosoftSQLServercodewith
whichthedatabasewas
created.Forinternaluseonlyby
SQLServertoolsandinupgrade
processing.
Versionnumber=
Databaseisopen
NULL=Databaseis
closed
Changeaproperty
USEmaster
EXECsp_dboption'ClassNorthwind','autocreatestatistics','TRUE'
CreateaDatabase
USEmaster
/*DroptheClassNorthwindDatabaseifitalreadyexists*/
IFDB_ID('ClassNorthwind')ISNOTNULL
BEGIN
DROPDATABASEClassNorthwind
END
/*CreatetheDatabase*/
CREATEDATABASEClassNorthwindONPRIMARY
(
NAME=ClassNorthwind_SYS,
FILENAME='C:\ClassNorthwind_SYS.mdf',
SIZE=5MB,
MAXSIZE=100MB,
FILEGROWTH=10%
)
LOGON
(
NAME=ClassNorthwind_LOG,
FILENAME='C:\ClassNorthwind_LOG.ldf',
SIZE=15MB,
MAXSIZE=40MB,
FILEGROWTH=10%
)
/*CreateadditionalFilegroups*/
ALTERDATABASEClassNorthwind
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 21/49
ADDFILEGROUPTAB
ALTERDATABASEClassNorthwind
ADDFILEGROUPIDX
ALTERDATABASEClassNorthwind
ADDFILE(
NAME=ClassNorthwind_TAB01,
FILENAME='C:\ClassNorthwind_TAB01.ndf',
SIZE=1MB,
MAXSIZE=UNLIMITED,
FILEGROWTH=50MB)
TOFILEGROUPTAB
ALTERDATABASEClassNorthwind
ADDFILE(
NAME=ClassNorthwind_IDX01,
FILENAME='C:\ClassNorthwind_IDX01.ndf',
SIZE=1MB,
MAXSIZE=UNLIMITED,
FILEGROWTH=50MB)
TOFILEGROUPIDX
/*AlterDefaultFilegroup*/
ALTERDATABASEClassNorthwind
MODIFYFILEGROUP[TAB]DEFAULT
GO
InformationonDatabases
USEClassNorthwind
dbccsqlperf(logspace)
sp_helpfilegroup[TAB]
EXECsp_spaceused'<table_name>'
DataStructures
AllDatabaseshaveaprimarydatafile(.MDF)andoneormoreTransactionlogfiles(.LDF)
ADatabasecanhavesecondarydatafiles(.NDF)
Dataisstoredin8KBblocks=Pages
RowscannotspanPages,thusthemaximumamountofdatainasinglerowis8KB
Extentsare8contiguousPages=8x8=64KB
Extents
MixedExtents=containsdataoftwoormoretables
UniformExtents=containsdataofonesingletable
SecialPages(infirstextentofeachfileasmixedextent)
FileHeaderPage:FileAttributs
PageFreeSpace(PFS):FreeSpaceinPage
GlobalAllocationMap(GAM):LocationoffreePages
SecondaryGlobalAllocationMap(SGAM)
IndexAllcationMap(IAM):InformationaboutExtentsthataTableorIndexuses.
DataPage:NormalRowDataotherthantext,ntext,image
Text/ImagePage:BLOBs
IndexPage:IndexStructures
DatabaseRecoveryModel
SIMPLE:TransactionLogisoverwrittenwhenfull
FULL:TransactionLogmustbebackedup
alterdatabaseClassNorthwindsetrecoverysimple
alterdatabaseClassNorthwindsetrecoveryfull
CheckExtents,Pages
dbcctraceon(3604)/*OutputtoScreen*/
dbccextentinfo(ClassNorthwind)
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 22/49
dbccpage(ClassNorthwind,1,75)/*1=FileId,75=PageId*/
Traceflags
TraceflagsareusedtocustomizecertaincharacteristicscontrollinghowMicrosoftSQLServer
operates.TraceflagsremainenabledintheserveruntildisabledbyexecutingaDBCCTRACEOFF
statement.NewconnectionsintotheserverdonotseeanytraceflagsuntilaDBCCTRACEON
statementisissued.Then,theconnectionwillseealltraceflagscurrentlyenabledintheserver,
eventhoseenabledbyanotherconnection.
BackupaDatabase
osqlS<server>U<db_user>P<db_password>ibackup.sql
USEmaster
EXECsp_dropdevice'MyDb_dat'
EXECsp_dropdevice'MyDb_log'
EXECsp_addumpdevice'disk','MyDb_dat',
'C:\ProgramFiles\MicrosoftSQLServer\MSSQL\BACKUP\MyDb_dat.dat'
EXECsp_addumpdevice'disk','MyDb_log',
'C:\ProgramFiles\MicrosoftSQLServer\MSSQL\BACKUP\MyDb_log.dat'
BACKUPDATABASEMyDbTOMyDb_dat
BACKUPLOGMyDbWITHTRUNCATE_ONLY
GO
Devicedropped.
Devicedropped.
(1rowaffected)
'Disk'deviceadded.
(1rowaffected)
'Disk'deviceadded.
Processed26392pagesfordatabase'MyDb',file'MigrationBasisplus_Data'
Processed1pagesfordatabase'MyDb',file'MigrationBasisplus_Log'onfile3.
BACKUPDATABASEsuccessfullyprocessed26393pagesin9.719seconds(22.245MB/sec).
RestoreaDatabase
osqlS<server>U<db_user>P<db_password>irestore.sql
USEmaster
RESTOREDATABASECredit
FROMDISK='C:\CreditDB.BAK'
WITHREPLACE
GO
Processed112pagesfordatabase'Credit',file'credit_Data'onfile1.
Processed984pagesfordatabase'Credit',file'CreditTables'onfile1.
Processed144pagesfordatabase'Credit',file'CreditIndexes'onfile1.
Processed1pagesfordatabase'Credit',file'credit_Log'onfile1.
RESTOREDATABASEsuccessfullyprocessed1241pagesin2.408seconds(4.220MB/sec)
CreatingTables
UserdefinedDataTypes
UserdefinedDataTypesshouldnotbeused!
BLOBS
Text:CLOB(02GB)
NTEXT:UnicodeCLOB(02GB)
Image:BLOB(02GB)
BlobsarenOTstoredwithinrowdata,howeverthiscanaccomplishedwith
useNorthwind
EXECsp_tableoptionN'Employees','textinrow','ON'
EXECsp_tableoptionN'Employees','textinrow','1000'/*1000CharsinRow*/
ComputedColumns
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 23/49
VirtualColumnthatisnotphysicallystoredinthetable,itisbasedonotherColumnswithinthe
table.
CREATETABLEmylogintable(
date_indatetime,
user_idint,
remarkvarchar(20),
remark_upperASUPPER(RTRIM(remark)),
user_nameASUSER_NAME()
)
GenerateColumnValuewithIdentityProperty
Createsanidentitycolumninatable.ThispropertyisusedwiththeCREATETABLEandALTER
TABLETransactSQLstatements(similartoSequenceinOracle).
Use@@IDENTITYtodeterminemostrecentvaluejustafteranINSERT.
SCOPE_IDENTITYreturnsthelastIDENTITYvalueinsertedintoanidentitiycolumninthesame
scope.Ascopeisastoredprocedure,triggerfunctionorbatch.
IDENT_CURRENTreturnsthelastIDENTITYvalueinsertedforaspecifiedtableinanysession
andanyscope.
Example
USEClassNorthwind
GO
CREATETABLEtable1(idintIDENTITY)
CREATETABLEtable2(idintIDENTITY(100,1))
GO
CREATETRIGGERtable1insONtable1FORINSERT
AS
BEGIN
INSERTtable2DEFAULTVALUES
END
GO
endoftriggerdefinition
SELECT*FROMtable1
idisempty.
SELECT*FROMtable2
idisempty.
DothefollowinginSession1
INSERTtable1DEFAULTVALUES
SELECT@@IDENTITY
100
Returnsthevalue100,whichwasinsertedbythetrigger.
SELECTSCOPE_IDENTITY()
1
Returnsthevalue1,whichwasinsertedbythe
INSERTstmt2statementsbeforethisquery.*/
SELECTIDENT_CURRENT('table2')
100
Returnsvalueinsertedintotable2,i.e.inthetrigger.
SELECTIDENT_CURRENT('table1')
1
Returnsvalueinsertedintotable1,whichwas
theINSERTstatement4stmtsbeforethisquery.
DothefollowinginSession2
SELECT@@IDENTITY
ReturnsNULLsincetherehasbeennoINSERTaction
sofarinthissession.
SELECTSCOPE_IDENTITY()
ReturnsNULLsincetherehasbeennoINSERTaction
sofarinthisscopeinthissession.
SELECTIDENT_CURRENT('table2')
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 24/49
100
Returnsthelastvalueinsertedintotable2
SETIDENTITY_INSERT
Allowsexplicitvaluestobeinsertedintotheidentitycolumnofatable.
USEClassNorthwind
GO
Createproductstable.
CREATETABLEproducts(idintIDENTITY(1,1)PRIMARYKEY,
productvarchar(40))
GO
Insertingvaluesintoproductstable.
INSERTINTOproducts(product)VALUES('screwdriver')
INSERTINTOproducts(product)VALUES('hammer')
INSERTINTOproducts(product)VALUES('saw')
INSERTINTOproducts(product)VALUES('shovel')
GO
Getlastinsertedkey
SELECT@@identity
Createagapintheidentityvalues.
DELETEproducts
WHEREproduct='saw'
GO
SELECT*
FROMproducts
GO
AttempttoinsertanexplicitIDvalueof3
shouldreturnawarning:
Cannotinsertexplicitvalueforidentitycolumnintable'products'
whenIDENTITY_INSERTissettoOFF.
INSERTINTOproducts(id,product)VALUES(3,'gardenshovel')
GO
SETIDENTITY_INSERTtoON.
SETIDENTITY_INSERTproductsON
GO
AttempttoinsertanexplicitIDvalueof3
Successfull
INSERTINTOproducts(id,product)VALUES(3,'gardenshovel')
GO
SELECT*
FROMproducts
GO
GenerateColumnValuewithNEWIDFunction
Createsauniquevalueoftypeuniqueidentifier.
CreatingalocalvariablewithDECLARE/SETsyntax.
USEClassNorthwind
DECLARE@myiduniqueidentifier
SET@myid=NEWID()
PRINT'Valueof@myidis:'+CONVERT(varchar(255),@myid)
GO
CreateTableusingNEWID()
CREATETABLEcust
(
cust_iduniqueidentifierNOTNULLDEFAULTnewid(),
companyvarchar(30)NOTNULL,
contact_namevarchar(60)NOTNULL,
addressvarchar(30)NOTNULL,
cityvarchar(30)NOTNULL,
state_provincevarchar(10)NULL,
postal_codevarchar(10)NOTNULL,
countryvarchar(20)NOTNULL,
telephonevarchar(15)NOTNULL,
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 25/49
faxvarchar(15)NULL
)
GO
Insertingdataintocusttable.
INSERTcust
(cust_id,company,contact_name,address,city,state_province,
postal_code,country,telephone,fax)
VALUES
(newid(),'WartianHerkku','PirkkoKoskitalo','Torikatu38','Oulu',NULL,
'90110','Finland','981443655','981443655')
CreateTableinspecifiedFileGroup
USEClassNorthwind
CheckifTableexists
IFOBJECT_ID('Employees')ISNOTNULL
DROPTABLEdbo.Employees
GO
CreateTableinTABFilegroup
CREATETABLEEmployees(
EmployeeIDintIDENTITY(1,1)NOTNULL,
LastNamenvarchar(20)NOTNULL,
FirstNamenvarchar(10)NOTNULL,
)ON[TAB]
GO
GeneratingTransactSQLScripts
1. OpenEM
2. SelectaDatabase
3. RightClick,AllTasks,GenerateSQLScript
select*fromdbo.sysobjects
whereid=object_id(N'[dbo].[Region]')
andOBJECTPROPERTY(id,N'IsUserTable')=1
LoggedandNonloggedBulkCopies
Thedifferencebetweenloggedandnonloggedbulkcopyoperationsishowmuchinformationis
logged.Bothloggedandnonloggedbulkcopyoperationscanberolledback,butonlyaloggedbulk
copyoperationcanberolledforward.
Inaloggedbulkcopyallrowinsertionsarelogged,whichcangeneratemanylogrecordsinalarge
bulkcopyoperation.Theselogrecordscanbeusedtobothrollforwardandrollbackthelogged
bulkcopyoperation.Inanonloggedbulkcopy,onlytheallocationsofnewpagestoholdthebulk
copiedrowsarelogged.
USEmaster
GO
execsp_dboptionClassNorthwind,'selectinto/bulkcopy',true
GO
USEClassNorthwind
SETNOCOUNTON
GO
...DoBulkInsert
DataIntegrity
DEFAULTConstraint
USEClassNorthwind
/*Droptheconstraintifitalreadyexists*/
IFOBJECT_ID('DF_Region')ISNOTNULL
BEGIN
ALTERTABLEEmployeesDROPCONSTRAINTDF_Region
END
GO
/*Addtheconstraint*/
ALTERTABLEEmployees
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 26/49
ADDCONSTRAINTDF_RegionDEFAULT'NY'FORRegion
GO
CHECKConstraint
/*
AddsaCHECKCONTSTRAINTtoverifythattheemployee
birthdateislessthantoday'sdate.
*/
USEClassNorthwind
ALTERTABLEEmployees
ADDCONSTRAINTCK_BirthDateCHECK(BirthDate<GETDATE())
GO
PRIMARYKEYConstraint
AUNIQUEIndexisautomaticallycreated.Youcanspecifyaclusteredornonclusteredindex
(clusteredisthedefault).AclusteredindexisthesameasaIOT(indexorganizedTable)inOracle.
Tabledataisphysicallysorted.Onlyoneclusteredindexispossiblepertable.
/*
AddsaPRIMARYKEYCONTSTRAINTtotheCumtomerstable.
*/
USEClassNorthwind
ALTERTABLECustomers
ADDCONSTRAINTPK_CustomersPRIMARYKEYNONCLUSTERED(CustomerID)
GO
FOREIGNKEYConstraint
/*
AddsaforeignkeyconstrainttotheOrderstablein
theClassNorthwinddatabase.
Ifthisisarerun(andtheconstraintalreadyexists),first
droptheconstraint.
UsetheClassNorthwinddatabaseandsetNOCOUNTontoeliminate
themessageindicatingthenumberofrowsaffected.
*/
USEClassNorthwind
SETNOCOUNTON
GO
IFEXISTS
(SELECT*FROMINFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERECONSTRAINT_SCHEMA='dbo'ANDCONSTRAINT_NAME='FK_Orders_Customers'
ANDCONSTRAINT_TYPE='FOREIGNKEY')
ALTERTABLEdbo.OrdersDROPCONSTRAINTFK_Orders_Customers
GO
ALTERTABLEdbo.Orders
ADDCONSTRAINTFK_Orders_Customers
FOREIGNKEY(CustomerID)REFERENCESdbo.Customers(CustomerID)
GO
/*ResetNOCOUNT*/
SETNOCOUNTON
GO
DEFAULTObject
IndependentofaTable,canbeattachedtoanyTable
/*
CreatesadefaultfortheClassNorthwinddatabase.
*/
USEClassNorthwind
/*Ifthedefaultobjectalreadyexists,dropit*/
IFOBJECT_ID('DF_Country')ISNOTNULL
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 27/49
BEGIN
EXECsp_unbindefault'dbo.Suppliers.Country'
DROPDEFAULTDF_Country
END
GO
/*CreatetheDefaultObject*/
CREATEDEFAULTDF_CountryAS'Singapore'
GO
/*BindtheDefaultObjecttotheSuppliers.Countrycolumn*/
EXECsp_bindefaultDF_Country,'dbo.Suppliers.Country'
GO
RULEObject
IndependentofaTable,canbeattachedtoanyTable.Rulesusesvariables,becausecolumnname
isnotknownwhenyoucreatetherule.
/*
CreatesthephonenumberrulefortheClassNorthwinddatabase.
*/
USEClassNorthwind
Iftherulealreadyexists,unbindanddropit.
IFOBJECT_ID('R_PhotoPath')ISNOTNULL
BEGIN
EXECsp_unbindrule'dbo.Employees.PhotoPath'
DROPRULER_PhotoPath
END
GO
CreateandbindtheRule.
CREATERULER_PhotoPath
AS@PhotoPathLIKE'http://www.akadia.%'
GO
EXECsp_bindruleR_PhotoPath,'dbo.Employees.PhotoPath'
GO
OK
UPDATEEmployees
SETPhotoPath='http://www.akadia.com'
WHERELastName='Fuller'
GO
OK
UPDATEEmployees
SETPhotoPath='http://www.akadia.com'
WHERELastName='Fuller'
GO
NOTOK
UPDATEEmployees
SETPhotoPath='http://www.arkum.com'
WHERELastName='Fuller'
GO
DisablingandEnablingConstraints
AppliestoCHECKandFOREIGNKEYConstraintsonly.
USEClassNorthwind
GO
ALTERTABLEOrders
NOCHECKCONSTRAINTFK_Orders_Customers
GO
ALTERTABLEOrders
CHECKCONSTRAINTFK_Orders_Customers
GO
TableStructure
PagesandExtents
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 28/49
TheactualdatainyourtableisstoredinPages,exceptBLOBdata.IfacolumncontainBLOBdata
thena16bytepointerisusedtoreferencetheBLOBpage.ThePageisthesmallestunitofdata
storageinMicrosoftSQLServer.Apagecontainsthedataintherows.Arowcanonlyresidein
onepage.EachPagecancontain8KBofinformation,duetothis,themaximumsizeofaRowis
8KB.Agroupof8adjacentpagesiscalledanextent.Aheapisacollectionofdatapages.
HeapsandtheIndexAllocationMap(IAM)
Heapshaveonerowinsysindexeswithindid=0.Thecolumnsysindexes.FirstIAMpointstothe
firstIAMpageinthechainofIAMpagesthatmanagethespaceallocatedtotheheap.Microsoft
SQLServer2000usestheIAM(IndexAllocationMap)pagestonavigatethroughtheheap.The
datapagesandtherowswithinthemarenotinanyspecificorder,andarenotlinkedtogether.
TheonlylogicalconnectionbetweendatapagesisthatrecordedintheIAMpages.
IndexStructure
AllSQLServerindexesareBTrees.Thereisasinglerootpageatthetopofthetree,branching
outintoNnumberofpagesateachintermediateleveluntilitreachesthebottom,orleaflevel,of
theindex.Theindextreeistraversedbyfollowingpointersfromtheupperlevelpagesdown
throughthelowerlevelpages.Inaddition,eachindexlevelisaseparatepagechain.Theremaybe
manyintermediatelevelsinanindex.Thenumberoflevelsisdependentontheindexkeywidth,
thetypeofindex,andthenumberofrowsand/orpagesinthetable.Thenumberoflevelsis
importantinrelationtoindexperformance.
NonclusteredIndexes
Anonclusteredindexisanalogoustoanindexinatextbook.Thedataisstoredinoneplace,
theindexinanother,withpointerstothestoragelocationofthedata.Theitemsintheindexare
storedintheorderoftheindexkeyvalues,buttheinformationinthetableisstoredinadifferent
order(whichcanbedictatedbyaclusteredindex).Ifnoclusteredindexiscreatedonthetable,the
rowsarenotguaranteedtobeinanyparticularorder.
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 29/49
Similartothewayyouuseanindexinabook,MicrosoftSQLServer2000searchesforadata
valuebysearchingthenonclusteredindextofindthelocationofthedatavalueinthetableandthen
retrievesthedatadirectlyfromthatlocation.Thismakesnonclusteredindexestheoptimal
choiceforexactmatchqueriesbecausetheindexcontainsentriesdescribingtheexactlocationin
thetableofthedatavaluesbeingsearchedforinthequeries.Iftheunderlyingtableissortedusing
aclusteredindex,thelocationistheclusteringkeyvalueotherwise,thelocationistherowID
(RID)comprisedofthefilenumber,pagenumber,andslotnumberoftherow.Forexample,to
searchforanemployeeID(emp_id)inatablethathasanonclusteredindexontheemp_idcolumn,
SQLServerlooksthroughtheindextofindanentrythatliststheexactpageandrowinthetable
wherethematchingemp_idcanbefound,andthengoesdirectlytothatpageandrow.
Considerations
Considerusingnonclusteredindexesfor:
Columnsthatcontainalargenumberofdistinctvalues,suchasacombinationof
lastnameandfirstname(ifaclusteredindexisusedforothercolumns).Ifthere
areveryfewdistinctvalues,suchasonly1and0,mostquerieswillnotusethe
indexbecauseatablescanisusuallymoreefficient.
Queriesthatdonotreturnlargeresultsets.
Columnsfrequentlyinvolvedinsearchconditionsofaquery(WHEREclause)that
returnexactmatches.
Decisionsupportsystemapplicationsforwhichjoinsandgroupingarefrequently
required.Createmultiplenonclusteredindexesoncolumnsinvolvedinjoinand
groupingoperations,andaclusteredindexonanyforeignkeycolumns.
Coveringallcolumnsfromonetableinagivenquery.Thiseliminatesaccessingthe
tableorclusteredindexaltogether.
ClusteredIndexes
Aclusteredindexdeterminesthephysicalorderofdatainatable.Aclusteredindexisanalogous
toatelephonedirectory,whicharrangesdatabylastname.Becausetheclusteredindex
dictatesthephysicalstorageorderofthedatainthetable,atablecancontainonlyoneclustered
index.However,theindexcancomprisemultiplecolumns(acompositeindex),likethewaya
telephonedirectoryisorganizedbylastnameandfirstname.ClusteredIndexesareverysimilarto
Oracle'sIOT's(Index-Organized Tables).
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 30/49
Aclusteredindexisparticularlyefficientoncolumnsthatareoftensearchedforrangesof
values.Aftertherowwiththefirstvalueisfoundusingtheclusteredindex,rowswithsubsequent
indexedvaluesareguaranteedtobephysicallyadjacent.Forexample,ifanapplicationfrequently
executesaquerytoretrieverecordsbetweenarangeofdates,aclusteredindexcanquicklylocate
therowcontainingthebeginningdate,andthenretrievealladjacentrowsinthetableuntilthelast
dateisreached.Thiscanhelpincreasetheperformanceofthistypeofquery.Also,ifthereisa
column(s)thatisusedfrequentlytosortthedataretrievedfromatable,itcanbeadvantageousto
cluster(physicallysort)thetableonthatcolumn(s)tosavethecostofasorteachtimethe
column(s)isqueried.
Clusteredindexesarealsoefficientforfindingaspecificrowwhentheindexedvalueisunique.For
example,thefastestwaytofindaparticularemployeeusingtheuniqueemployeeIDcolumn
emp_idistocreateaclusteredindexorPRIMARYKEYconstraintontheemp_idcolumn.
NotePRIMARYKEYconstraintscreateclusteredindexesautomaticallyifnoclusteredindex
alreadyexistsonthetableandanonclusteredindexisnotspecifiedwhenyoucreatethePRIMARY
KEYconstraint.
Considerations
Itisimportanttodefinetheclusteredindexkeywithasfewcolumnsaspossible.Ifalarge
clusteredindexkeyisdefined,anynonclusteredindexesthataredefinedonthesametablewillbe
significantlylargerbecausethenonclusteredindexentriescontaintheclusteringkey.
Considerusingaclusteredindexfor:
Columnsthatcontainalargenumberofdistinctvalues.
QueriesthatreturnarangeofvaluesusingoperatorssuchasBETWEEN,>,>=,<,
and<=.
Columnsthatareaccessedsequentially.
Queriesthatreturnlargeresultsets.
ColumnsthatarefrequentlyaccessedbyqueriesinvolvingjoinorGROUPBY
clausestypicallytheseareforeignkeycolumns.Anindexonthecolumn(s)
specifiedintheORDERBYorGROUPBYclauseeliminatestheneedforSQLServer
tosortthedatabecausetherowsarealreadysorted.Thisimprovesquery
performance.
OLTPtypeapplicationswhereveryfastsinglerowlookupisrequired,typicallyby
meansoftheprimarykey.Createaclusteredindexontheprimarykey.
Clusteredindexesarenotagoodchoicefor:
Columnsthatundergofrequentchanges
Thisresultsintheentirerowmoving(becauseSQLServermustkeepthedata
valuesofarowinphysicalorder).Thisisanimportantconsiderationinhigh
volumetransactionprocessingsystemswheredatatendstobevolatile.
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 31/49
Widekeys
Thekeyvaluesfromtheclusteredindexareusedbyallnonclusteredindexes
aslookupkeysandthereforearestoredineachnonclusteredindexleafentry.
SysindexesTable
Thesysindexestableisacentrallocationforinformationabouttablesandindexes.Itcontains
statisticalinformation,suchasthenumberofrowsanddatapagesineachtable.Itdescribeshowto
findinformationstoredinadatatable.
Containsonerowforeachindexandtableinthedatabase.Thistableisstoredineachdatabase.
Columnname Datatype Description
id int
IDoftable(forindid=0or255).Otherwise,ID
oftabletowhichtheindexbelongs.
status int
Internalsystemstatusinformation.
first binary(6)
Pointertothefirstorrootpage.
indid smallint
IDofindex:
0=Heap=TableData(notIndex)
1=ClusteredIndex
2...254=NonclusteredIndex
255=Entryfortablesthathavetextorimage
data
root binary(6)
Forindid>=1and<255,rootisthepointerto
therootpage.Forindid=0orindid=255,root
isthepointertothelastpage.
minlen smallint
Minimumsizeofarow.
keycnt smallint
Numberofkeys.
groupid smallint
FilegroupIDonwhichtheobjectwascreated.
dpages int
Forindid=0orindid=1,dpagesisthecountof
datapagesused.Forindid=255,itissetto0.
Otherwise,itisthecountofindexpagesused.
reserved int
Forindid=0orindid=1,reservedisthecount
ofpagesallocatedforallindexesandtabledata.
Forindid=255,reservedisacountofthepages
allocatedfortextorimagedata.Otherwise,itis
thecountofpagesallocatedfortheindex.
used int
Forindid=0orindid=1,usedisthecountof
thetotalpagesusedforallindexandtabledata.
Forindid=255,usedisacountofthepages
usedfortextorimagedata.Otherwise,itisthe
countofpagesusedfortheindex.
rowcnt bigint
Datalevelrowcountbasedonindid=0andindid
=1.Forindid=255,rowcntissetto0.
rowmodctr int
Countsthetotalnumberofinserted,deleted,or
updatedrowssincethelasttimestatisticswere
updatedforthetable.
xmaxlen smallint
Maximumsizeofarow.
maxirow smallint
Maximumsizeofanonleafindexrow.
OrigFillFactor tinyint
Originalfillfactorvalueusedwhentheindexwas
created.Thisvalueisnotmaintainedhowever,
itcanbehelpfulifyouneedtorecreatean
indexanddonotrememberwhatfillfactorwas
used.
reserved1 tinyint
Reserved.
reserved2 int
Reserved.
FirstIAM binary(6)
Reserved.
impid smallint
Reserved.Indeximplementationflag.
lockflags smallint
Usedtoconstraintheconsideredlock
granularitiesforanindex.Forexample,alookup
tablethatisessentiallyreadonlycouldbesetup
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 32/49
todoonlytablelevellockingtominimizelocking
cost.
pgmodctr int
Reserved.
keys varbinary(816)
ListofthecolumnIDsofthecolumnsthatmake
uptheindexkey.
name sysname
Nameoftable(forindid=0or255).Otherwise,
nameofindex.
statblob image
StatisticsBLOB.
maxlen int
Reserved.
rows int
Datalevelrowcountbasedonindid=0andindid
=1,andthevalueisrepeatedforindid>1.For
indid=255,rowsissetto0.Providedfor
backwardcompatibility.
VerifythesysindexesTable
/*
**CreateanonclusteredindexontheCustomerIDcolumn
**intheOrderstableoftheClassNorthwinddatabase.
**
**Thisscriptchecksfortheexistanceofthe
**Orders_Customers_linkindex.
**Ifitexistswewilldropitfirstthencreateit.
*/
USEClassNorthwind
SETNOCOUNTON
GO
/*
**Iftheobjectsalreadyexist(i.e.ifthisisarebuild),dropthem.
*/
IFEXISTS(SELECTnameFROMsysindexesWHEREname='Orders_Customers_link')
DROPINDEXOrders.Orders_Customers_link
GO
/*CreatetheIndexwithaFILLFACTORof75*/
CREATENONCLUSTEREDINDEXOrders_Customers_linkONOrders(CustomerID)
WITHFILLFACTOR=75
GO
SETNOCOUNTOFF
GO
/*
**Thisscriptqueriesthesysindexessystemtable.
**Itjoinstothesysobjectstabletogetthetablenames.
**Itselectsonlytheuserdefinedtables(thosewith
**anidgreaterthan100.)
*/
USEClassNorthwind
GO
SELECTt.nameAS[TableName],i.nameAS[IndexName],i.*
FROMsysobjectsAStJOINsysindexesASiONt.id=i.id
WHEREt.id>100
ORDERBYt.name
SELECTt.nameAS[TableName],i.nameAS[IndexName],i.*
FROMsysobjectsAStJOINsysindexesASiONt.id=i.id
WHEREi.name='Orders_Customers_link'
TableName=Orders
IndexName=Orders_Customers_link
id=869578136
indid=3
minlen=19
keycnt=2
groupid=2
dpages=4
reserved=6
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 33/49
used=6
rowcnt=830
xmaxlen=36
maxirow=42
OrigFillFactor=75
FirstIAM=0x7E0000000300
FullTableScan
1. LookupSYSINDEXESTableforgivenTable
2. INDID=0,FirstIAMpointstoIAM
3. LookupExtentswithBitMap=1forthisTableinIAM
4. ReadallExtentsonDisk,Rowsarereturnedunsorted
NonClusteredIndexRead
1. LookupSYSINDEXESTableforgivenTable
2. INDID=2...254,readROOTcolumnforRootIndextofindNonLeafLevelofNon
ClusteredIndex
3. LookupRID(RowId)inLeafLevel(KeyValues).EachRIDconsistsofFileID,PageNo,
RowNo(4:706:02)
4. ReadonlythoseRowsfromHeapwhichareneeded.
ClusteredIndexRead
1. LookupSYSINDEXESTableforgivenTable
2. INDID=1,readROOTcolumnforRootIndextofindNonLeafLevelofClusteredIndex
3. ReadneededLeafLevelRows.Thedatarowsofaclusteredindexaresortedandstoredina
sequentialorderbasedontheirclusteredkey.
ClusteredIndexwithNonClusteredIndexRead
Whenanonclusteredindexisaddedtoatablethatalreadyhasaclusteredindex,therowlocatorof
eachnonclusteredindexcontainstheclusteredkeyindexvaluefortherow.
1. LookupSYSINDEXESTableforgivenTable
2. INDID=2...254,readROOTcolumnforRootIndextofindNonLeafLevelofNon
ClusteredIndex
3. LookupClusteredKeyValueinLeafLevelofNonclusteredIndex
4. LookupRootIndextofindNonLeafLevelofClusteredIndex
5. ReadneededLeafLevelRows.Thedatarowsofaclusteredindexaresortedandstoredina
sequentialorderbasedontheirclusteredkey.
PageSplitsinanIndex
Occursifdatapageorindexpagedoesnothaveenoughroomtoaccommodatethedata,a
newpageisaddedinaprocessknownasapagesplit.
Approximatelyhalfofthedataremainsontheoldpageandtheotherhalfismovedtothe
newpage.
PageSplitsdonotoccurinaHeap
ForwardingPointershandlesupdatestoarowinaheapwhichneedsmoreroomthanis
currentlyavailableonthatpage.Therowismovedtoanewdatapage.
Therowleavesaforwardingpointerinitsoriginallocation.
DeterminingSelectitivity
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 34/49
HighSelectivity:LowValuein%forNumberofRowsmeetingcriteria/TotalnumberofRowsin
Table(e.g.5%)
LowSelectivity:HighValuein%forNumberofRowsmeetingcriteria/TotalnumberofRowsin
Table(e.g.90%)
Densityisanotherconceptformeasuringtheselectivity:
HighSelectivity=LowDensity
LowSelectivity=HighDensity
DetermineTableStructures(e.g.tablename='member')
NumberofRows
EXECsp_spaceused'member'
10'000
Displaysfragmentationinformationforthedataandindexesofthespecifiedtable
DBCCSHOWCONTIG('member')
DBCCSHOWCONTIGscanning'member'table...
Table:'member'(2025058250)indexID:0,databaseID:9
TABLElevelscanperformed.
PagesScanned................................:145
ExtentsScanned..............................:19
ExtentSwitches..............................:18
Avg.PagesperExtent........................:7.6
ScanDensity[BestCount:ActualCount].......:100.00%[19:19]
ExtentScanFragmentation...................:0.00%
Avg.BytesFreeperPage.....................:95.6
Avg.PageDensity(full).....................:98.82%
NumberofRowsperPage
=NumberofRows/PagesScanned=10'000/145=68
NumberofExtens
ExtentSwitches=18
NumberofIndexes
SELECT*FROMsysindexesWHEREid=OBJECT_ID('member')
NumberofclusteredIndexPages(sysindexes:used)
/*createaclusteredindexonthemembertableandnotethechanges*/
CREATEUNIQUECLUSTEREDINDEXmem_no_CLONmember(member_no)
SELECT*FROMsysindexesWHEREid=OBJECT_ID('member')
used:147
Numberofdatapagesintheclusteredindex(sysindexes:dpages)
dpages=145
Numberofnondatapagesintheclusteredindex(useddpages)
useddpages=147145=2
Numberofpagesinnonclusteredindex(usedforindex:indid=2)
/*Nowcreateanonclusteredindexandnotethechanges*/
CREATENONCLUSTEREDINDEXindx_fnameONmember(firstname)
SELECT*FROMsysindexesWHEREid=OBJECT_ID('member')
used:35
Numberofpagesintheleaflevelfornonclusteredindex(dpagesforindex:indid=2)
dpages:33
Approximatenumberofrowsperleafpagefornonclusteredindex
#rowsintable/#leaflevelpages=10'000/33=303
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 35/49
OptimizerStatistics
CanbecreatedonindexesandonTableColumns
SamplingStatisticsisrandomlyselectingdatapagesfromatable
FULLSCANgathersalldata
Statisticsarestoredinthestatblobcolumnofthesysindexessystemtable
UsuallyStatisticsarecollectedautomatically(see:DatabaseOptions,Autocreatestatistics)
ManuallyCreatingStatistics
Canbeusefulwhenyouhaveacolumnthatmaynotbenefitfromanindex,butstatisticsonthat
columnmaybeusefulforcreatingmoreoptimalexecutionplans.Havingstatisticsonthosecolumns
eliminatestheoverheadofanindex.
SETClassNorthwind
GO
CREATESTATISTICSST_Company
ONCustomers(CompanyName,ContactName)
WITHSAMPLE50PERCENT
GO
CREATESTATISTICSST_Contact
ONCustomers(ContactName)
WITHFULLSCAN
GO
SELECT*FROMsysindexesWHEREid=OBJECT_ID('Customers')
GO
DROPSTATISTICSCustomers.ST_Contact
GO
DROPSTATISTICSCustomers.ST_Company
GO
CreateStatisticsforwholeDatabase
Createssinglecolumnstatisticsforalleligiblecolumnsforallusertablesinthecurrentdatabase.
TheStoredProcedureindex_cleanupisusedbecausethereisnosp_dropstats.
USEClassNorthwind
GO
/*RemoveStatisticsfromeachTableinthedatabase*/
EXECindex_cleanupCategories
EXECindex_cleanupCustomerCustomerDemo
EXECindex_cleanupCustomerDemographics
EXECindex_cleanupCustomers
EXECindex_cleanupEmployees
EXECindex_cleanupEmployeeTerritories
EXECindex_cleanup[OrderDetails]
EXECindex_cleanupOrders
EXECindex_cleanupProducts
EXECindex_cleanupRegion
EXECindex_cleanupShippers
EXECindex_cleanupSuppliers
EXECindex_cleanupTerritories
GO
/*CreateStatistics*/
sp_createstats
/*Showcreatedstatistics*/
sp_helpstatsEmployees
Thecreatedstatistichasthesamenameasthecolumnonwhichitiscreated.Computedcolumns
andcolumnsofthentext,text,orimagedatatypescannotbespecifiedasstatisticscolumns.
ViewIndexStatisticsandevaluatingIndexSelectivity
/*CleanupStatistics*/
EXECindex_cleanupmember
/*CreateUNIQUEindex*/
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 36/49
CREATEUNIQUEINDEXindx_member_noONmember(member_no)
GO
/*ViewIndexStatisticsandevaluatingIndexSelectivity*/
DBCCSHOW_STATISTICS(member,indx_member_no)
Rows=10000
Density=9.9.E5(Veryselective,duetoUNIQUEindexoncolumn)
AllDensity=9.9.E5
Density:[0...1],0=HighSelectivity,1=LowSelectivity
AllDensity:Overmorecolumns
Views
CreatingViews
CREATEVIEW[OrdersQry]AS
SELECTO.OrderID,O.CustomerID,O.EmployeeID,O.OrderDate,O.RequiredDate,
O.ShippedDate,O.ShipVia,O.Freight,O.ShipName,O.ShipAddress,O.ShipCity,
O.ShipRegion,O.ShipPostalCode,O.ShipCountry,
C.CompanyName,C.Address,C.City,C.Region,C.PostalCode,C.Country
FROMCustomersCINNERJOINOrdersOONC.CustomerID=O.CustomerID
CREATEVIEWMyTopCitiesAS
SELECTDISTINCTTOP10PERCENTShipCity,ShipRegion
FROMOrders
ORDERBYShipCity
Encrypt/DecryptViews
CREATEVIEWMyTopCities
WITHENCRYPTION
AS
SELECTDISTINCTTOP10PERCENTShipCity,ShipRegion
FROMOrders
ORDERBYShipCity
sp_helptextMyTopCities
Theobjectcommentshavebeenencrypted.
DecrypttheViewwiththePublicDomainStoredProcedureDECRYPT2K
EXECdbo.DECRYPT2KMyTopCities,'V'
UpdateableViews
CREATEVIEWFormaggiProductsView
AS
SELECTProductID,ProductName,SupplierID
FROMProducts
WHERESupplierID=14
WITHCHECKOPTION
IndexedViews
Seehere
StoredProcedures
SystemStoredProcedures,identifiedbythesp_prefix
TemporaryStoredProcedureshavenamesstartwithasinglenumbersign(#)
ExtendedStoredProceduresareimplementedasDLLs(xp_)
NameofSPisinsysobjectstable,codeinsyscommentstable
CreateStoredProcedure
USEClassNorthwind
GO
IFEXISTS(SELECT*FROMdbo.sysobjects
WHEREid=object_id(N'[dbo].[MyOrders]')
ANDOBJECTPROPERTY(id,N'IsProcedure')=1)
DROPPROCEDURE[dbo].[MyOrders]
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 37/49
GO
CREATEPROCEDUREMyOrders
AS
SELECT*FROMOrders
WHERERequiredDate<GETDATE()ANDShippedDateISNULL
GO
ExecuteStoredProcedurebyItself
EXECMyOrders
GO
PopulateTablewithaStoredProcedure
TheINSERTstatemantcanpopulatealocaltablewitharesultsetthatisreturnedfromalocalor
remotestoredprocedure.SQLServerloadsthetablewithdatathatisreturnedfromSELECT
statementsinthestoredprocedure.Thatablemusexist.
ExcecuteStoredProcedurewithinanINSERTStatement
INSERTINTOMyTableEXECMyOrders
GO
HelponStoredProcedures
sp_helpMyOrders
sp_helptextMyOrders
sp_dependsMyOrders
sp_stored_procedures
CheckStoredProcedureProperties
UseOBJECT_ID()andOBJECTPROPERTY()
DECLARE@obidINTEGER
SELECT@obid=OBJECT_ID('MyOrders')
SELECTOBJECTPROPERTY(@obid,'ExecIsAnsiNullsOn')
RecompileallStoredProcedures,TriggerthatreferenceaTable
Causesstoredproceduresandtriggerstoberecompiledthenexttimetheyarerun.
sp_recompile<TableName>
UsingInputParameters
USEClassNorthwind
GO
CREATEPROCEDUREYearSales
@Startdatetime,
@Enddatetime=NULL
AS
IF(@StartISNULLOR@EndISNULL)
BEGIN
RAISERROR('NULLValuesarenotallowed',14,1)
RETURN
END
SELECTShippedDate,
OrderID
FROMOrders
WHEREDATENAME(yyyy,ShippedDate)BETWEEN@StartAND@End
GO
EXECYearSales@Start='1997',@End='1998'
ReturningValuesUsingOutputParameters
CREATEPROCEDUREMathTutor
@m1smallint,
@m2smallint,
@resultsmallintOUTPUT
AS
SET@result=@m1*@m2
GO
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 38/49
DECLARE@answersmallint
EXECUTEMathTutor5,6,@answerOUTPUT
SELECT'Result=',@answer
ProcessOUTPUTValueandRETURNParameter
USE ClassNorthwind
GO
/* Create Procedure with OUTPUT Parameter */
CREATE PROC dbo.OrderCount
@CustomerID nchar (5),
@OrderCount int OUTPUT
AS
IF EXISTS
(SELECT * FROM Orders WHERE CustomerID = @CustomerID AND ShippedDate IS Null)
BEGIN
SELECT @OrderCount=COUNT(*)
FROM Orders
WHERE CustomerID = @CustomerID
RETURN (@@ROWCOUNT)
END
ELSE RETURN (0)
GO
/* Process Return Value and OUTPUT Parameter */
DECLARE
@CustomerID nchar (5),
@Message varchar(80),
@ReturnCode int,
@NumberOrders int
SET @CustomerID = 'LILAS'
EXEC @ReturnCode = OrderCount @CustomerID, @NumberOrders OUTPUT
IF @ReturnCode = 1
BEGIN
SELECT @Message =
'Customer ' +
RTRIM(CONVERT(char(8),@CustomerID)) +
' has ' +
RTRIM(CONVERT(char(8),@NumberOrders)) +
' unfilled order(s).'
RAISERROR (@Message, 10 ,1)
END
ELSE
BEGIN
SELECT @Message =
'Customer ' +
RTRIM(convert(char(8),@CustomerID)) +
' has NO unfilled order(s).'
RAISERROR (@Message, 10 ,1)
END
GO
Usinglastinsert@@identityforForeignKeyValue
USEClassNorthwind
GO
/*Iftheobjectalreadyexistsinthedatabase,dropit.*/
IFOBJECT_ID('SupplierProductInsert')ISNOTNULL
DROPPROCEDURESupplierProductInsert
GO
/*CreateSPtoINSERTValuesinSupplierTable*/
CREATEPROCEDURESupplierProductInsert
@CompanyNamenvarchar(40)=NULL,
@ContactNamenvarchar(40)=NULL,
@ContactTitlenvarchar(40)=NULL,
@Addressnvarchar(60)=NULL,
@Citynvarchar(15)=NULL,
@Regionnvarchar(40)=NULL,
@PostalCodenvarchar(10)=NULL,
@Countrynvarchar(15)=NULL,
@Phonenvarchar(24)=NULL,
@Faxnvarchar(24)=NULL,
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 39/49
@HomePagentext=NULL,
@ProductNamenvarchar(40)=NULL,
@CategoryIDint=NULL,
@QuantityPerUnitnvarchar(20)=NULL,
@UnitPricemoney=NULL,
@UnitsInStocksmallint=NULL,
@UnitsOnOrdersmallint=NULL,
@ReorderLevelsmallint=NULL,
@Discontinuedbit=NULL
AS
IF@CompanyNameISNULLOR
@ContactNameISNULLOR
@AddressISNULLOR
@CityISNULLOR
@RegionISNULLOR
@PostalCodeISNULLOR
@CountryISNULLOR
@PhoneISNULLOR
@ProductNameISNULLOR
@CategoryIDISNULLOR
@QuantityPerUnitISNULLOR
@DiscontinuedISNULL
BEGIN
PRINT'YoumustprovideCompanyName,ContactName,Address,City'
PRINT'Region,PostalCode,Country,Phone,ProductName,andDiscontinued.'
PRINT'(ContactTitle,Fax,HomePage,UnitPrice,UnitsinStock
UnitsonOrderandReorderLevelcanbenull.)'
RETURN
END
BEGINTRANSACTION
INSERTSuppliers(
CompanyName,
ContactName,
Address,
City,
Region,
PostalCode,
Country,
Phone)
VALUES(
@CompanyName,
@ContactName,
@Address,
@City,
@Region,
@PostalCode,
@Country,
@Phone)
IF@@error<>0
BEGIN
ROLLBACKTRAN
RETURN
END
/*GetjustinsertedIDENTITYValue*/
DECLARE@InsertSupplierIDint
SELECT@InsertSupplierID=@@identity
/*InsertValuesincludingjustinsertedIDENTITYValue*/
INSERTProducts(
ProductName,
SupplierID,
CategoryID,
QuantityPerUnit,
Discontinued)
VALUES(
@ProductName,
@InsertSupplierID,
@CategoryID,
@QuantityPerUnit,
@Discontinued)
IF@@error<>0
BEGIN
ROLLBACKTRAN
RETURN
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 40/49
END
PRINT'***NewProductandSupplieradded***'
COMMITTRANSACTION
GO
CustomMessagesfromStoredProceduresaddedtoEventlog
Thesystemstoredproceduresp_addmessageaddsanewerrormessagetothesysmessagestable
andtheWindows2000eventlogoftheSQLServerSystem(notontheSQLClient).Youcanalsouse
SQLServerAgentunderManagementinEM.
USEClassNorthwind
GO
/*Specifycustommessagefortheeventlog*/
EXECsp_addmessage@msgnum=50018,
@severity=16,
@msgtext=N'Supplier%dwasinsertedby%s',
@lang='us_english',
@with_log='true',
@replace='replace'
GO
/*Iftheobjectalreadyexistsinthedatabase,dropit.*/
IFOBJECT_ID('SupplierProductInsert')ISNOTNULL
DROPPROCEDURESupplierProductInsert
GO
/*CreateProceduretoINSERTnewRecordinSUPPLIERTable*/
CREATEPROCEDURESupplierProductInsert
@CompanyNamenvarchar(40)=NULL,
@ContactNamenvarchar(40)=NULL,
@ContactTitlenvarchar(40)=NULL,
@Addressnvarchar(60)=NULL,
@Citynvarchar(15)=NULL,
@Regionnvarchar(40)=NULL,
@PostalCodenvarchar(10)=NULL,
@Countrynvarchar(15)=NULL,
@Phonenvarchar(24)=NULL,
@Faxnvarchar(24)=NULL,
@HomePagentext=NULL,
@ProductNamenvarchar(40)=NULL,
@CategoryIDint=NULL,
@QuantityPerUnitnvarchar(20)=NULL,
@UnitPricemoney=NULL,
@UnitsInStocksmallint=NULL,
@UnitsOnOrdersmallint=NULL,
@ReorderLevelsmallint=NULL,
@Discontinuedbit=NULL
AS
IF@CompanyNameISNULLOR
@ContactNameISNULLOR
@AddressISNULLOR
@CityISNULLOR
@RegionISNULLOR
@PostalCodeISNULLOR
@CountryISNULLOR
@PhoneISNULLOR
@ProductNameISNULLOR
@CategoryIDISNULLOR
@QuantityPerUnitISNULLOR
@DiscontinuedISNULL
BEGIN
PRINT'YoumustprovideCompanyName,ContactName,Address,City'
PRINT'Region,PostalCode,Country,Phone,ProductName,andDiscontinued'
PRINT'(ContactTitle,Fax,HomePage,UnitPrice,UnitsinStock
UnitsonOrderandReorderLevelcanbenull.)'
RETURN
END
/*Storetheloginidentificationnameforuseincustommessage*/
DECLARE@UserNamenvarchar(60)
SELECT@UserName=suser_sname()
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 41/49
/*StarttheINSERT*/
BEGINTRANSACTION
INSERTSuppliers(
CompanyName,
ContactName,
Address,
City,
Region,
PostalCode,
Country,
Phone)
VALUES(
@CompanyName,
@ContactName,
@Address,
@City,
@Region,
@PostalCode,
@Country,
@Phone)
IF@@error<>0
BEGIN
ROLLBACKTRAN
RETURN
END
/*Getjustinserted@@identityvalue*/
DECLARE@InsertSupplierIDint
SELECT@InsertSupplierID=@@identity
/*InsertRecordinPRODUCTSforthisSupplierID*/
INSERTProducts(
ProductName,
SupplierID,
CategoryID,
QuantityPerUnit,
Discontinued)
VALUES(
@ProductName,
@InsertSupplierID,
@CategoryID,
@QuantityPerUnit,
@Discontinued)
IF@@error<>0
BEGIN
ROLLBACKTRAN
RETURN
END
/*Sendcustommessagetoeventlog*/
RAISERROR(50018,16,1,@InsertSupplierID,@UserName)
COMMITTRANSACTION
GO
/*ExecutetheStoredProcedure*/
EXECSupplierProductInsert
@CompanyName='Akadia',
@ContactName='MartinZahn',
@Address='Arvenweg4',
@City='Thun',
@Region='Bern',
@PostalCode='3604',
@Country='CH',
@Phone='0333358620',
@ProductName='Transtec',
@CategoryID='1',
@QuantityPerUnit='1',
@UnitPrice=1,
@Discontinued=0
Server:Msg50018,Level16,State1,ProcedureSupplierProductInsert,Line98
Supplier34wasinsertedbyzahn
EMailInterface
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 42/49
MicrosoftSQLServerprovidesasetofextendedstoredproceduresthatallowSQLServerto
operateasaworkgrouppostofficeforaMAPIenabledemailsystem.
ThecomputerrunningSQLServermustbesetupasanemailclient.SQLServerEnterprise
ManagerisusedtoassignanemailaccountandpasswordtotheSQLServerinstallation.Themail
componentofSQLServercanthenbeenabledtostartautomaticallywhentheSQLServerAgent
serviceisstarted.Alternatively,themailcomponentcanbestartedandstoppedatwillusingeither
SQLServerEnterpriseManager,orthexp_startmail,xp_stopmail,andxp_sendmailstored
procedures.
TosetupthemailinfrastructureyoumustcreateamailprofileandSQLServerServicePack2must
beinstalled.
SendMail
EXECmaster..xp_startmail
EXECmaster..xp_sendmail
@recipients='martindotzahnatakadiadotch',
@subject='SQLServerReport',
@message='HelloMartin'
EXECmaster..xp_stopmail
ExtendedStoredProcedures
ExecuteCMDShellCommands
EXECmaster..xp_cmdshell'dirc:\'
EXECmaster..xp_cmdshell'netstart'
EXECmaster..sp_helptextxp_cmdshell
UserDefinedFunctions
ScalarUserDefinedFunction
ReturnsasinglevalueofthetypedefinedinaRETURNSclause.
USEClassNorthwind
GO
CREATEFUNCTIONmyDateFormat
(@indatedatetime,@separatorchar(1))
RETURNSNchar(20)
AS
BEGIN
RETURN
CONVERT(Nvarchar(20),datepart(dd,@indate))
+@separator
+CONVERT(Nvarchar(20),datepart(mm,@indate))
+@separator
+CONVERT(Nvarchar(20),datepart(yy,@indate))
END
GO
SELECTdbo.myDateFormat(GETDATE(),'.')
Thisscalaruserdefinedfunctionusesacasestatementtoprovideamultiplierforthreedifferent
taxrates(0%,5%,and10%)thatvarydependingontheCategoryIDiftheproduct.
USEClassNorthwind
GO
CREATEFUNCTIONfn_TaxRate
(@ProdIDINT)
RETURNSnumeric(5,4)
AS
BEGIN
RETURN
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 43/49
(SELECT
CASECategoryID
WHEN1THEN1.10
WHEN2THEN1
WHEN3THEN1.10
WHEN4THEN1.05
WHEN5THEN1
WHEN6THEN1.05
WHEN7THEN1
WHEN8THEN1.05
END
FROMProducts
WHEREProductID=@ProdID)
END
GO
SELECTProductName,
UnitPrice,
CategoryID,
ClassNorthwind.dbo.fn_TaxRate(ProductID)ASTaxRate,
UnitPrice*ClassNorthwind.dbo.fn_TaxRate(ProductID)ASPriceWithTax
FROMProducts
MultiStatementTablevaluedFunction
AMultiStatementTablevaluedFunctionisacombinationofaviewandastoredprocedure.The
RETURNSclausespecifiesatableasthedatatypereturned.
/*
**ThisExamplecreatesamultistatementtablevaluefunction
**thatreturnsthelastnameorboththefirstnames
*/
CREATEFUNCTIONfn_Employees(@InLengthnvarchar(9))
RETURNS@EmpTabTABLE
(EmployeeIDINTPRIMARYKEY,
NameNVARCHAR(61)NOTNULL)
AS
BEGIN
IF(@InLength='ShortName')
BEGIN
Initialize@EmpTabwithLastName
INSERT@EmpTabSELECTEmployeeID,LastNameFROMemployees
END
ELSEIF(@InLength='LongName')
BEGIN
Initialize@EmpTabFirstNameLastName
INSERT@EmpTabSELECTEmployeeID,(FirstName+''+LastName)FROMemployees
END
RETURNProvidesthevalueof@EmpTabastheresult
END
GO
/*CalltheFunction*/
SELECT*FROMdbo.fn_Employees('ShortName')
ThismultistatementtablevalueduserdefinedfunctiontakesanEmplyeeIDnumberasits
parameter
andprovidesinformationaboutallemployeeswhoreporttothatperson.
/*
**Asamultistatementtablevalueduserdefined
**functionitstartswiththefunctionname,
**inputparameterdefinitionanddefinestheoutput
**table.
*/
CREATEFUNCTIONfn_FindReports(@InEmployeeIDchar(5))
RETURNS@reportsTABLE
(EmployeeIDchar(5)PRIMARYKEY,
Namenvarchar(40)NOTNULL,
Titlenvarchar(30),
MgrEmployeeIDint,
processedtinyintdefault0)
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 44/49
Returnsaresultsetthatlistsalltheemployeeswho
reporttoagivenemployeedirectlyorindirectly
AS
BEGIN
DECLARE@RowsAddedint
Initialize@reportswithdirectreportsofthegivenemployee
INSERT@reports
SELECTEmployeeID,Name=FirstName+''+LastName,Title,ReportsTo,0
FROMEMPLOYEES
WHEREReportsTo=@InEmployeeID
SET@RowsAdded=@@rowcount
Whilenewemployeeswereaddedinthepreviousiteration
WHILE@RowsAdded>0
BEGIN
Markallemployeerecordswhosedirectreportsaregoingtobe
foundinthisiteration
UPDATE@reports
SETprocessed=1
WHEREprocessed=0
Insertemployeeswhoreporttoemployeesmarked1
INSERT@reports
SELECTe.EmployeeID,Name=FirstName+''+LastName,e.Title,e.ReportsTo,0
FROMemployeese,@reportsr
WHEREe.ReportsTo=r.EmployeeID
ANDr.processed=1
SET@RowsAdded=@@rowcount
Markallemployeerecordswhosedirectreportshasbeen
foundinthisiteration
UPDATE@reports
SETprocessed=2
WHEREprocessed=1
END
RETURNProvidesthevalueof@reportsastheresult
END
GO
/*Callthefunction*/
SELECTEmployeeID,[Name],Title,MgrEmployeeIDFROMdbo.fn_FindReports(5)
Triggers
Thetriggerandthestatementthatfiresitaretreatedasasingletransactionthatcanberolledback
fromanywherewithinthetrigger.IfaROLLBACKTRANSACTIONisencontered,theentire
transactionisroledback.MinimizeoravoidtheuseofROLLBACKTRANSACTIONintriggers.You
musthavepermissiontoperformallstatementsthatdefinetriggers,thisisdifferentfromstored
procedures.
TherearenoRowLevelTrigger
AllTriggersareAFTERTriggers
TriggersdarepartoftheTransaction
UseINSTEADOFTriggerstoperformaBEFORETrigger.
INSERTTriggers
/*
**ThisfilecreatesaninserttriggerontheOrderDetails
**table.WhenarowisinsertedintoOrderDetailsthe
**ProductstableUnitsInStockcolumnisupdatedto
**reducetheamountofstockonhand.
*/
USEClassNorthwind
/*
**Iftheobjectalreadyexists(i.e.,ifthisisarebuild),dropit.
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 45/49
*/
IFEXISTS(SELECTnameFROMsysobjects
WHEREtype='TR'ANDname='OrdDet_Insert')
DROPTRIGGEROrdDet_Insert
GO
/*CreatetheINSERTTriger,InsertedisaninternalTable
**whichcanonlybeusedinINSERTTriggers
*/
CREATETRIGGEROrdDet_Insert
ON[OrderDetails]FORINSERT
AS
UPDATEPSETUnitsInStock=(P.UnitsInStockI.Quantity)
FROMProductsASPINNERJOINInsertedASI
ONP.ProductID=I.ProductID
GO
/*
**Displayresults.
*/
SELECTnameFROMsysobjects
WHEREtype='TR'
ORDERBYtype,name
GO
/*
**Executesp_helptriggerontheOrderDetailstable
*/
sp_helptrigger[OrderDetails]
/*
**CheckthevalueoftheProductstablebeforethetriggerfires
*/
SELECT*FROMProductsWHEREProductID=22
/*
**InsertanOrderDetailsrecordforproduct16
*/
INSERT[OrderDetails]
(OrderID,ProductID,UnitPrice,Quantity,Discount)
VALUES(11077,22,21.00,50,0.0)
GO
/*
**CheckthevalueoftheProductstabletoseeifitchanged
*/
SELECT*FROMProductsWHEREProductID=22
DELETETriggers
USEClassNorthwind
GO
CREATETRIGGERemp_deleteONEmployees
FORDELETE
AS
IF(SELECTCOUNT(*)FROMDeleted)>1
BEGIN
RAISERROR('Youcannotdeletemorethanoneemployeeatatime.',16,1)
ROLLBACKTRANSACTION
END
DELETEFROMEmployees
TheDeletedTableisaninternalTable
UPDATETriggers
YoucandefineatriggertomonitordataupdatesonaspecificcolumnbyusingtheIFUPDATE
statement.
USEClassNorthwind
GO
CREATETRIGGERemp_update
ONEmployees
FORUPDATE
AS
IFUPDATE(LastName)
BEGIN
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 46/49
RAISERROR('LastNamecannotbeupdated',10,1)
ROLLBACKTRANSACTION
END
UpdateEmployeesSETLastName='Hallo'whereEmployeeID=5
==>LastNamecannotbeupdated
TransactSQLExamples
Herearesometypicalexamples,whichshowstheuseofTSQL.
ShrinkingtheLogfile
SETNOCOUNTON
DECLARE@LogicalFileNamesysname,
@MaxMinutesINT,
@NewSizeINT
***MAKESURETOCHANGETHENEXT4LINESWITHYOURCRITERIA.***
USE[MyDb]Thisisthenameofthedatabase
forwhichthelogwillbeshrunk.
SELECT@LogicalFileName='MyDb_Log',Usesp_helpfileto
identifythelogicalfile
namethatyouwanttoshrink.
@MaxMinutes=10,Limitontimeallowedtowraplog.
@NewSize=10inMB
Setup/initialize
DECLARE@OriginalSizeint
SELECT@OriginalSize=sizein8Kpages
FROMsysfiles
WHEREname=@LogicalFileName
SELECT'OriginalSizeof'+db_name()+'LOGis'+
CONVERT(VARCHAR(30),@OriginalSize)+'8Kpagesor'+
CONVERT(VARCHAR(30),(@OriginalSize*8/1024))+'MB'
FROMsysfiles
WHEREname=@LogicalFileName
CREATETABLEDummyTrans
(DummyColumnchar(8000)notnull)
Wraplogandtruncateit.
DECLARE@CounterINT,
@StartTimeDATETIME,
@TruncLogVARCHAR(255)
SELECT@StartTime=GETDATE(),
@TruncLog='BACKUPLOG['+db_name()+']WITHTRUNCATE_ONLY'
Tryaninitialshrink.
DBCCSHRINKFILE(@LogicalFileName,@NewSize)
EXEC(@TruncLog)
Wrapthelogifnecessary.
WHILE@MaxMinutes>DATEDIFF(mi,@StartTime,GETDATE())timehas
notexpired
AND@OriginalSize=(SELECTsize
FROMsysfiles
WHEREname=@LogicalFileName)theloghasnotshrunk
AND(@OriginalSize*8/1024)>@NewSize
Thevaluepassedinfornewsizeis
smallerthanthecurrentsize.
BEGINOuterloop.
SELECT@Counter=0
WHILE((@Counter<@OriginalSize/16)AND(@Counter<50000))
BEGINupdate
INSERTDummyTransVALUES('FillLog')Becauseitisacharfieldit
inserts8000bytes.
DELETEDummyTrans
SELECT@Counter=@Counter+1
ENDupdate
EXEC(@TruncLog)Seeifatruncofthelogshrinksit.
ENDouterloop
SELECT'FinalSizeof'+db_name()+'LOGis'+
CONVERT(VARCHAR(30),size)+'8Kpagesor'+
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 47/49
CONVERT(VARCHAR(30),(size*8/1024))+'MB'
FROMsysfiles
WHEREname=@LogicalFileName
DROPTABLEDummyTrans
PRINT'***Performafulldatabasebackup***'
SETNOCOUNTOFF
HandlingNULLs
COUNT(*)
MostaggregatefunctionseliminatenullvaluesincalculationsoneexceptionistheCOUNTfunction.
WhenusingtheCOUNTfunctionagainstacolumncontainingnullvalues,thenullvalueswillbe
eliminatedfromthecalculation.However,iftheCOUNTfunctionusesanasterisk,itwill
calculateallrowsregardlessofnullvaluesbeingpresent.
IfyouwanttheCOUNTfunctiontocountallrowsofagivencolumn,includingthenullvalues,use
theISNULLfunction.TheISNULLfunctioncanreplacethenullvaluewithavalidvalue.
Infact,theISNULLfunctionisveryvaluableforaggregatefunctionswherenullvaluesaffectthe
resultsinanerroneousfashion.Rememberthatwhenusinganasterisk,theCOUNTfunctionwill
calculateallrows.ThefollowingissamplecodethatillustratestheimpactofnullvaluesintheAVG
andCOUNTaggregatefunctions:
SETNOCOUNTON
GO
CREATETABLETestTab(
PkeyINTIDENTITYNOTNULLCONSTRAINTpk_TestTabPRIMARYKEY,
Col1INTNULL
)
GO
INSERTTestTab(Col1)VALUES(10)
GO
INSERTTestTab(Col1)VALUES(15)
GO
INSERTTestTab(Col1)VALUES(20)
GO
INSERTTestTab(Col1)VALUES(NULL)
GO
SELECTAVG(Col1)A,
AVG(ISNULL(Col1,0))B,
COUNT(Col1)C,
COUNT(ISNULL(Col1,0))D,
COUNT(*)E
FROMTestTab
GO
DROPTABLETestTab
GO
ABCDE

1511344
Asyoucansee,COUNT(*)hascountedallrows!
NULLValuesinForeignKeys
Whenyouhavetwocolumnsthatcomprisetheprimarykey,andachildtableinheritstheprimary
keysasnullableforeignkeys,youmayhavebaddata.Youcaninsertavalidvalueintooneofthe
foreignkeycolumnsandnullintotheotherforeignkeycolumn.Then,youcanaddatablecheck
constraintthatchecksforvaliddatainthenullableforeignkeys.
Thisanomalymayoccurforanymulticolumnforeignkey.Soyouwillneedtoaddacheck
constrainttotestfortheanomaly.Initially,thecheckconstraintwillcheckfornullablevaluesinall
columns,whichcomprisetheforeignkey.Thecheckconstraintwillalsocheckfornonnullable
valueswithinthesecolumns.Ifbothcheckspass,theanomalyshouldbecircumvented.
SETNOCOUNTON
GO
CREATETABLEAdresses(
pkey1INTIDENTITYNOTNULL,
pkey2INTNOTNULL,
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 48/49
Col1INTNULL,
CONSTRAINTpk_AdressesPRIMARYKEYNONCLUSTERED(pkey1,pkey2)
)
GO
INSERTAdresses(pkey2)VALUES(2)
INSERTAdresses(pkey2)VALUES(85)
INSERTAdresses(pkey2)VALUES(41)
INSERTAdresses(pkey2)VALUES(11)
GO
CREATETABLEContact(
pkeyINTIDENTITYNOTNULLCONSTRAINTpk_ContactPRIMARYKEYNONCLUSTERED,
fkey1INTNULL,
fkey2INTNULL,
col1INTNULL,
CONSTRAINTfk_Adresses_ContactFOREIGNKEY(fkey1,fkey2)
REFERENCESAdresses(pkey1,pkey2))
GO
Thisisnowpossibleandsurelywrong!
INSERTContact(fkey1,fkey2)VALUES(NULL,85)
GO
SELECT*FROMContact
GO
DELETEFROMContact
GO
AddtheCheckConstraintontheForeignKey
ALTERTABLEContactWITHNOCHECK
ADDCONSTRAINTck_fk_Adresses_Contact
CHECK((fkey1ISNOTNULLANDfkey2ISNOTNULL)
OR(fkey1ISNULLANDfkey2ISNULL))
GO
INSERTContact(fkey1,fkey2)VALUES(NULL,85)
GO
TheINSERTstatementconflictedwiththeCHECKconstraint"ck_fk_Adresses_Contact".
DROPTABLEContact,Adresses
GO
2/7/2014 SQL Server 2000 Survival Guide
http://www.akadia.com/services/sqlsrv_programming.html 49/49