ADO Dot Net Data Tutorial
ADO Dot Net Data Tutorial
Step1:MovingtheNorthwindDatabaseOutofApp_Data
AllofourtutorialsthusfarhaveusedaMicrosoftSQLServer2005ExpressEditiondatabasefileintheweb applicationsApp_Data folder.PlacingthedatabaseinApp_Data simplifieddistributingandrunningthesetutorials asallofthefileswerelocatedwithinonedirectoryandrequirednoadditionalconfigurationstepstotestthe tutorial. Forthistutorial,however,letsmovetheNorthwinddatabaseoutofApp_Data andexplicitlyregisteritwiththe SQLServer2005ExpressEditiondatabaseinstance.Whilewecanperformthestepsforthistutorialwiththe databaseintheApp_Data folder,anumberofthestepsaremademuchsimplerbyexplicitlyregisteringthe databasewiththeSQLServer2005ExpressEditiondatabaseinstance. ThedownloadforthistutorialhasthetwodatabasefilesNORTHWND.MDF andNORTHWND_log.LDF placedina 1 of38
foldernamedDataFiles.Ifyouarefollowingalongwithyourownimplementationofthetutorials,closeVisual StudioandmovetheNORTHWND.MDF andNORTHWND_log.LDF filesfromthewebsitesApp_Data foldertoafolder outsideofthewebsite.Oncethedatabasefileshavebeenmovedtoanotherfolderweneedtoregisterthe NorthwinddatabasewiththeSQLServer2005ExpressEditiondatabaseinstance.ThiscanbedonefromSQL ServerManagementStudio.IfyouhaveanonExpressEditionofSQLServer2005installedonyourcomputer thenyoulikelyalreadyhaveManagementStudioinstalled.IfyouonlyhaveSQLServer2005ExpressEditionon yourcomputerthentakeamomenttodownloadandinstall MicrosoftSQLServerManagementStudioExpress. LaunchSQLServerManagementStudio.AsFigure1shows,ManagementStudiostartsbyaskingwhatserverto connectto.Enter localhost\SQLExpressfortheservername,choose WindowsAuthenticationinthe Authenticationdropdownlist,andclickConnect.
Figure1:ConnecttotheAppropriateDatabaseInstance
2 of38
Figure2:ConnecttotheAppropriateDatabaseInstance
clickingonthedatabaseandchoosingRename.
3 of38
Figure3:RenametheDatabasetoNorthwind
Step2:CreatingaNewSolutionandSQLServerProjectinVisual Studio
TocreatemanagedstoredproceduresorUDFsinSQLServer2005wewillwritethestoredprocedureandUDF logicasC#codeinaclass.Oncethecodehasbeenwritten,wewillneedtocompilethisclassintoanassembly (a.dll file),registertheassemblywiththeSQLServerdatabase,andthencreateastoredprocedureorUDFobject inthedatabasethatpointstothecorrespondingmethodintheassembly.Thesestepscanallbeperformed manually.Wecancreatethecodeinanytexteditor,compileitfromthecommandlineusingtheC#compiler (csc.exe),registeritwiththedatabaseusingtheCREATEASSEMBLY commandorfromManagementStudio,and addthestoredprocedureorUDFobjectthroughsimilarmeans.Fortunately,theProfessionalandTeamSystems versionsofVisualStudioincludeaSQLServerProjecttypethatautomatesthesetasks.Inthistutorialwewillwalk throughusingtheSQLServerProjecttypetocreateamanagedstoredprocedureandUDF. Note:IfyouareusingVisualWebDeveloperortheStandardeditionofVisualStudio,thenyouwillhaveto usethemanualapproachinstead.Step13providesdetailedinstructionsforperformingthesestepsmanually. IencourageyoutoreadSteps2through12beforereadingStep13sincethesestepsincludeimportantSQL ServerconfigurationinstructionsthatmustbeappliedregardlessofwhatversionofVisualStudioyouare using. StartbyopeningVisualStudio.FromtheFilemenu,chooseNewProjecttodisplaytheNewProjectdialogbox (seeFigure4).DrilldowntotheDatabaseprojecttypeandthen,fromtheTemplateslistedontheright,chooseto createanewSQLServerProject.IhavechosentonamethisprojectManagedDatabaseConstructs andplacedit withinaSolutionnamedTutorial75.
4 of38
Figure4:CreateaNewSQLServerProject
5 of38
Figure5:AssociatetheSQLServerProjectwiththeNorthwindDatabase
6 of38
Figure6:EnableSQL/CLRDebugging
Figure7:TheSolutionExplorerNowIncludesTwoProjects
7 of38
TheNORTHWNDConnectionString valueinWeb.config currentlyreferencestheNORTHWND.MDF fileinthe App_Data folder.SinceweremovedthisdatabasefromApp_Data andexplicitlyregistereditintheSQLServer 2005ExpressEditiondatabaseinstance,weneedtocorrespondinglyupdatetheNORTHWNDConnectionString value.OpentheWeb.config fileinthewebsiteandchangetheNORTHWNDConnectionString valuesothatthe connectionstringreads:DataSource=localhost\SQLExpressInitialCatalog=NorthwindIntegrated Security=True. Afterthischange,your<connectionStrings> sectioninWeb.config shouldlooksimilartothe following:
<connectionStrings> <addname="NORTHWNDConnectionString"connectionString= "DataSource=localhost\SQLExpressInitialCatalog=Northwind IntegratedSecurity=TruePooling=false" providerName="System.Data.SqlClient"/> </connectionStrings>
Step3:CreatingaManagedStoredProcedure
ToaddamanagedstoredproceduretotheNorthwinddatabasewefirstneedtocreatethestoredprocedureasa methodintheSQLServerProject.FromtheSolutionExplorer,rightclickontheManagedDatabaseConstructs projectnameandchoosetoaddanewitem.ThiswilldisplaytheAddNewItemdialogbox,whichliststhetypes ofmanageddatabaseobjectsthatcanbeaddedtotheproject.AsFigure8shows,thisincludesstoredprocedures andUserDefinedFunctions,amongothers. Letsstartbyaddingastoredprocedurethatsimplyreturnsalloftheproductsthathavebeendiscontinued.Name thenewstoredprocedurefileGetDiscontinuedProducts.cs.
8 of38
Figure8:AddaNewStoredProcedureNamed GetDiscontinuedProducts.cs
ThiswillcreateanewC#classfilewiththefollowingcontent:
usingSystem usingSystem.Data usingSystem.Data.SqlClient usingSystem.Data.SqlTypes usingMicrosoft.SqlServer.Server publicpartialclassStoredProcedures { [Microsoft.SqlServer.Server.SqlProcedure] publicstaticvoidGetDiscontinuedProducts() { //Putyourcodehere } }
Notethatthestoredprocedureisimplementedasastatic methodwithinapartial classfilenamed StoredProcedures.Moreover,theGetDiscontinuedProducts methodisdecoratedwiththeSqlProcedure attribute,whichmarksthemethodasastoredprocedure. ThefollowingcodecreatesaSqlCommand objectandsetsitsCommandText toaSELECT query thatreturnsallofthecolumnsfromtheProducts tableforproductswhoseDiscontinued field equals1.Itthenexecutesthecommandandsendstheresultsbacktotheclient application.AddthiscodetotheGetDiscontinuedProducts method.
//Createthecommand SqlCommandmyCommand=newSqlCommand() myCommand.CommandText= @"SELECTProductID,ProductName,SupplierID,CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder, ReorderLevel,Discontinued FROMProducts WHEREDiscontinued=1" //Executethecommandandsendbacktheresults SqlContext.Pipe.ExecuteAndSend(myCommand)
AllmanageddatabaseobjectshaveaccesstoaSqlContext objectthatrepresentsthe contextofthecaller.TheSqlContext providesaccesstoaSqlPipe objectviaitsPipe property.ThisSqlPipe objectisusedtoferryinformationbetweentheSQLServerdatabase andthecallingapplication.Asitsnameimplies,theExecuteAndSend methodexecutesa passedinSqlCommand objectandsendstheresultsbacktotheclientapplication. Note:ManageddatabaseobjectsarebestsuitedforstoredproceduresandUDFsthat useprocedurallogicratherthansetbasedlogic.Procedurallogicinvolvesworking withsetsofdataonarowbyrowbasisorworkingwithscalardata.The GetDiscontinuedProducts methodwejustcreated,however,involvesnoprocedural logic.Therefore,itwouldideallybeimplementedasaTSQLstoredprocedure.Itis
9 of38
implementedasamanagedstoredproceduretodemonstratethestepsnecessaryfor creatinganddeployingmanagedstoredprocedures.
Step4:DeployingtheManagedStoredProcedure
Withthiscodecomplete,wearereadytodeployittotheNorthwinddatabase.Deployinga SQLServerProjectcompilesthecodeintoanassembly,registerstheassemblywiththe database,andcreatesthecorrespondingobjectsinthedatabase,linkingthemtothe appropriatemethodsintheassembly.TheexactsetoftasksperformedbytheDeploy optionismorepreciselyspelledoutinStep13.RightclickontheManagedDatabaseConstructs projectnameintheSolutionExplorerandchoosetheDeployoption.However,deployment failswiththefollowingerror:Incorrectsyntaxnear'EXTERNAL'.Youmayneedtosetthe compatibilitylevelofthecurrentdatabasetoahighervaluetoenablethisfeature.See helpforthestoredproceduresp_dbcmptlevel. ThiserrormessageoccurswhenattemptingtoregistertheassemblywiththeNorthwind database.InordertoregisteranassemblywithaSQLServer2005database,the databasescompatibilitylevelmustbesetto90.Bydefault,newSQLServer2005 databaseshaveacompatibilitylevelof90.However,databasescreatedusingMicrosoft SQLServer2000haveadefaultcompatibilitylevelof80.SincetheNorthwinddatabase wasinitiallyaMicrosoftSQLServer2000database,itscompatibilityleveliscurrentlysetto 80andthereforeneedstobeincreasedto90inordertoregistermanageddatabase objects. Toupdatethedatabasescompatibilitylevel,openaNewQuerywindowinManagement Studioandenter:
execsp_dbcmptlevel'Northwind',90
ClicktheExecuteiconintheToolbartoruntheabovequery.
10 of38
Figure9:UpdatetheNorthwindDatabasesCompatibilityLevel
11 of38
commandexecsp_configureinthequerywindow.Thisshowsthattheclrenabled settingiscurrentlysetto0.
Figure12:TheclrenabledSettingisCurrentlySetto0
Ifyoureruntheexecsp_configureyouwillseethattheabovestatementupdatedtheclr enabledsettingsconfigvalueto1,butthattherunvalueisstillsetto0.Forthis configurationchangetotakeaffectweneedtoexecutetheRECONFIGURE command,which willsettherunvaluetothecurrentconfigvalue.SimplyenterRECONFIGUREinthequery windowandclicktheExecuteiconintheToolbar.Ifyourunexecsp_configurenowyou shouldseeavalueof1fortheclrenabledsettingsconfigandrunvalues. Withtheclrenabledconfigurationcomplete,wearereadytorunthemanaged GetDiscontinuedProducts storedprocedure.Inthequerywindowenterandexecutethe commandexecGetDiscontinuedProducts.Invokingthestoredprocedurecausesthe correspondingmanagedcodeintheGetDiscontinuedProducts methodtoexecute.Thiscode issuesaSELECT querytoreturnallproductsthatarediscontinuedandreturnsthisdatato thecallingapplication,whichisSQLServerManagementStudiointhisinstance. ManagementStudioreceivestheseresultsanddisplaysthemintheResultswindow.
13 of38
Step5:CreatingManagedStoredProceduresthat AcceptInputParameters
Manyofthequeriesandstoredprocedureswehavecreatedthroughoutthesetutorials haveusedparameters.Forexample,intheCreatingNewStoredProceduresfortheTyped DataSetsTableAdapterstutorialwecreatedastoredprocedurenamed GetProductsByCategoryID thatacceptedaninputparameternamed@CategoryID .Thestored procedurethenreturnedallproductswhoseCategoryID fieldmatchedthevalueofthe supplied@CategoryID parameter. Tocreateamanagedstoredprocedurethatacceptsinputparameters,simplyspecifythose parametersinthemethodsdefinition.Toillustratethis,letsaddanothermanagedstored proceduretotheManagedDatabaseConstructs projectnamedGetProductsWithPriceLessThan.This managedstoredprocedurewillacceptaninputparameterspecifyingapriceandwillreturn allproductswhoseUnitPrice fieldislessthantheparametersvalue. Toaddanewstoredproceduretotheproject,rightclickontheManagedDatabaseConstructs projectnameandchoosetoaddanewstoredprocedure.Namethefile GetProductsWithPriceLessThan.cs.AswesawinStep3,thiswillcreateanewC#classfile withamethodnamedGetProductsWithPriceLessThan placedwithinthepartial class StoredProcedures. UpdatetheGetProductsWithPriceLessThan methodsdefinitionsothatitacceptsaSqlMoney inputparameternamedprice andwritethecodetoexecuteandreturnthequeryresults:
[Microsoft.SqlServer.Server.SqlProcedure] publicstaticvoidGetProductsWithPriceLessThan(SqlMoneyprice) { //Createthecommand
14 of38
SqlCommandmyCommand=newSqlCommand() myCommand.CommandText= @"SELECTProductID,ProductName,SupplierID,CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder, ReorderLevel,Discontinued FROMProducts WHEREUnitPrice<@MaxPrice" myCommand.Parameters.AddWithValue("@MaxPrice",price) //Executethecommandandsendbacktheresults SqlContext.Pipe.ExecuteAndSend(myCommand) }
TheGetProductsWithPriceLessThan methodsdefinitionandcodecloselyresemblesthe definitionandcodeoftheGetDiscontinuedProducts methodcreatedinStep3.Theonly differencesarethattheGetProductsWithPriceLessThan methodacceptsasinputparameter (price),the SqlCommandsqueryincludesaparameter(@MaxPrice),andaparameterisadded totheSqlCommandsParameters collectionisandassignedthevalueoftheprice variable. Afteraddingthiscode,redeploytheSQLServerProject.Next,returntoSQLServer ManagementStudioandRefreshtheStoredProceduresfolder.Youshouldseeanewentry, GetProductsWithPriceLessThan.Fromaquerywindow,enterandexecutethecommandexec GetProductsWithPriceLessThan25,whichwilllistallproductslessthan$25,asFigure14 shows.
Figure14:ProductsUnder$25areDisplayed
Step6:CallingtheManagedStoredProcedurefrom theDataAccessLayer
15 of38
AtthispointwehaveaddedtheGetDiscontinuedProducts andGetProductsWithPriceLessThan managedstoredprocedurestotheManagedDatabaseConstructs projectandhaveregistered themwiththeNorthwindSQLServerdatabase.Wealsoinvokedthesemanagedstored proceduresfromSQLServerManagementStudio(seeFigures13and14).Inorderforour ASP.NETapplicationtousethesemanagedstoredprocedures,however,weneedtoadd themtotheDataAccessandBusinessLogicLayersinthearchitecture.Inthisstepwewill addtwonewmethodstotheProductsTableAdapter intheNorthwindWithSprocs TypedDataSet, whichwasinitiallycreatedintheCreatingNewStoredProceduresfortheTypedDataSets TableAdapterstutorial.InStep7wewilladdcorrespondingmethodstotheBLL. OpentheNorthwindWithSprocs TypedDataSetinVisualStudioandstartbyaddinganew methodtotheProductsTableAdapter namedGetDiscontinuedProducts.Toaddanewmethodto aTableAdapter,rightclickontheTableAdaptersnameintheDesignerandchoosetheAdd Queryoptionfromthecontextmenu. Note:SincewemovedtheNorthwinddatabasefromtheApp_Data foldertotheSQL Server2005ExpressEditiondatabaseinstance,itisimperativethatthecorresponding connectionstringinWeb.configbeupdatedtoreflectthischange.InStep2we discussedupdatingtheNORTHWNDConnectionString valueinWeb.config.Ifyouforgotto makethisupdate,thenyouwillseetheerrormessageFailedtoaddquery.Unableto findconnectionNORTHWNDConnectionStringforobjectWeb.configinadialogboxwhen attemptingtoaddanewmethodtotheTableAdapter.Toresolvethiserror,clickOK andthengotoWeb.config andupdatetheNORTHWNDConnectionString valueasdiscussed inStep2.ThentryreaddingthemethodtotheTableAdapter.Thistimeitshould workwithouterror. AddinganewmethodlaunchestheTableAdapterQueryConfigurationwizard,whichwe haveusedmanytimesinpasttutorials.Thefirststepasksustospecifyhowthe TableAdaptershouldaccessthedatabase:throughanadhocSQLstatementorviaanew orexistingstoredprocedure.Sincewehavealreadycreatedandregisteredthe GetDiscontinuedProducts managedstoredprocedurewiththedatabase,choosetheUse existingstoredprocedureoptionandhitNext.
16 of38
Figure15:ChoosetheUseexistingstoredprocedureOption
17 of38
Figure16:SelecttheGetDiscontinuedProducts ManagedStoredProcedure
18 of38
Figure17:SelecttheTabularDataOption
19 of38
Figure18:NametheMethodsFillByDiscontinued andGetDiscontinuedProducts
RepeatthesestepstocreatemethodsnamedFillByPriceLessThan and GetProductsWithPriceLessThan intheProductsTableAdapter forthe GetProductsWithPriceLessThan managedstoredprocedure. Figure19showsascreenshotoftheDataSetDesignerafteraddingthemethodstothe ProductsTableAdapter fortheGetDiscontinuedProducts andGetProductsWithPriceLessThan managedstoredprocedures.
20 of38
Figure19:TheProductsTableAdapter IncludestheNewMethodsAddedinthisStep
Step7:AddingCorrespondingMethodstothe BusinessLogicLayer
NowthatwehaveupdatedtheDataAccessLayertoincludemethodsforcallingthe managedstoredproceduresaddedinSteps4and5,weneedtoaddcorresponding methodstotheBusinessLogicLayer.Addthefollowingtwomethodstothe ProductsBLLWithSprocs class:
[System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select,false)] publicNorthwindWithSprocs.ProductsDataTableGetDiscontinuedProducts() { returnAdapter.GetDiscontinuedProducts() } [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select,false)] publicNorthwindWithSprocs.ProductsDataTable GetProductsWithPriceLessThan(decimalpriceLessThan) { returnAdapter.GetProductsWithPriceLessThan(priceLessThan)
21 of38
Step8:InvokingtheManagedStoredProceduresfrom thePresentationLayer
WiththeBusinessLogicandDataAccessLayersaugmentedtoincludesupportforcalling theGetDiscontinuedProducts andGetProductsWithPriceLessThan managedstoredprocedures, wecannowdisplaythesestoredproceduresresultsthroughanASP.NETpage. OpentheManagedFunctionsAndSprocs.aspx pageintheAdvancedDAL folderand,fromthe Toolbox,dragaGridViewontotheDesigner.SettheGridViewsID propertyto DiscontinuedProducts and,fromitssmarttag,bindittoanewObjectDataSourcenamed DiscontinuedProductsDataSource.ConfiguretheObjectDataSourcetopullitsdatafromthe ProductsBLLWithSprocs classsGetDiscontinuedProducts method.
Figure20:ConfiguretheObjectDataSourcetoUsetheProductsBLLWithSprocs Class
22 of38
23 of38
</asp:ObjectDataSource>
Takeamomenttoviewthispagethroughabrowser.Whenthepageisvisited,the ObjectDataSourcecallstheProductsBLLWithSprocs classsGetDiscontinuedProducts method.As wesawinStep7,thismethodcallsdowntotheDALsProductsDataTable classs GetDiscontinuedProducts method,whichinvokestheGetDiscontinuedProducts stored procedure.Thisstoredprocedureisamanagedstoredprocedureandexecutesthecodewe createdinStep3,returningthediscontinuedproducts. Theresultsreturnedbythemanagedstoredprocedurearepackagedupintoa ProductsDataTable bytheDALandthenreturnedtotheBLL,whichthenreturnsthemtothe PresentationLayerwheretheyareboundtotheGridViewanddisplayed.Asexpected,the gridliststhoseproductsthathavebeendiscontinued.
Figure22:TheDiscontinuedProductsareListed
24 of38
Step9:CreatingandCallingTSQLUDFs
UserDefinedFunctions,orUDFs,aredatabaseobjectsthecloselymimicthesemanticsof functionsinprogramminglanguages.LikeafunctioninC#,UDFscanincludeavariable numberofinputparametersandreturnavalueofaparticulartype.AUDFcanreturn eitherscalardataastring,aninteger,andsoforthortabulardata.Letstakeaquick lookatbothtypesofUDFs,startingwithaUDFthatreturnsascalardatatype. ThefollowingUDFcalculatestheestimatedvalueoftheinventoryforaparticularproduct. ItdoessobytakinginthreeinputparameterstheUnitPrice,UnitsInStock,and Discontinued valuesforaparticularproductandreturnsavalueoftypemoney.Itcomputes theestimatedvalueoftheinventorybymultiplyingtheUnitPrice bytheUnitsInStock.For discontinueditems,thisvalueishalved.
CREATEFUNCTIONudf_ComputeInventoryValue ( @UnitPricemoney, @UnitsInStocksmallint, @Discontinuedbit ) RETURNSmoney AS BEGIN DECLARE@Valuedecimal SET@Value=ISNULL(@UnitPrice,0)*ISNULL(@UnitsInStock,0) IF@Discontinued=1 SET@Value=@Value*0.5 RETURN@Value END
25 of38
Figure23:EachProductsInventoryValuesisListed
UDFscanalsoreturntabulardata.Forexample,wecancreateaUDFthatreturnsproducts thatbelongtoaparticularcategory:
CREATEFUNCTIONdbo.udf_GetProductsByCategoryID ( @CategoryIDint ) RETURNSTABLE AS RETURN ( SELECTProductID,ProductName,SupplierID,CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder, ReorderLevel,Discontinued FROMProducts WHERECategoryID=@CategoryID )
26 of38
SELECTProductID,ProductName,CategoryID FROMdbo.udf_GetProductsByCategoryID(1)
Figure24:TheProductID,ProductName,andCategoryID areListedforEachBeverage
Step10:CreatingaManagedUDF
Theudf_ComputeInventoryValue andudf_GetProductsByCategoryID UDFscreatedintheabove examplesareTSQLdatabaseobjects.SQLServer2005alsosupportsmanagedUDFs, whichcanbeaddedtotheManagedDatabaseConstructs projectjustlikethemanagedstored proceduresfromSteps3and5.Forthisstep,letsimplementtheudf_ComputeInventoryValue UDFinmanagedcode. ToaddamanagedUDFtotheManagedDatabaseConstructs project,rightclickontheproject 27 of38
Figure25:AddaNewManagedUDFtotheManagedDatabaseConstructs Project
28 of38
NotethattheUDFmethodsinputparametersareoftheircorrespondingSQLtypes: SqlMoney fortheUnitPrice field,SqlInt16 for UnitsInStock,andSqlBoolean for Discontinued. ThesedatatypesreflectthetypesdefinedintheProducts table:theUnitPrice columnisof typemoney,theUnitsInStock columnoftypesmallint,andtheDiscontinued columnoftype bit. ThecodestartsbycreatingaSqlMoney instancenamedinventoryValue thatisassigneda valueof0.TheProducts tableallowsfordatabaseNULL valuesintheUnitsInPrice and UnitsInStock columns.Therefore,weneedtofirstchecktoseeifthesevaluescontainNULLs, whichwedothroughtheSqlMoney objectsIsNull property.IfbothUnitPrice and UnitsInStock containnonNULL values,thenwecomputetheinventoryValue tobetheproduct ofthetwo.Then,ifDiscontinued istrue,thenwehalvethevalue. Note:TheSqlMoney objectonlyallowstwoSqlMoney instancestobemultipliedtogether. ItdoesnotallowaSqlMoney instancetobemultipliedbyaliteralfloatingpoint number.Therefore,tohalveinventoryValue wemultiplyitbyanew SqlMoney instance thathasthevalue0.5.
Step11:DeployingtheManagedUDF
NowthatthatthemanagedUDFhasbeencreated,wearereadytodeployittothe Northwinddatabase.AswesawinStep4,themanagedobjectsinaSQLServerProject aredeployedbyrightclickingontheprojectnameintheSolutionExplorerandchoosing theDeployoptionfromthecontextmenu. Onceyouhavedeployedtheproject,returntoSQLServerManagementStudioandrefresh theScalarvaluedFunctionsfolder.Youshouldnowseetwoentries:
l l
justdeployed. 29 of38
TotestthismanagedUDF,executethefollowingqueryfromwithinManagementStudio:
SELECTProductID,ProductName, dbo.udf_ComputeInventoryValue_Managed( UnitPrice, UnitsInStock, Discontinued )asInventoryValue FROMProducts ORDERBYInventoryValueDESC
Step12:DebuggingtheManagedDatabaseObjects
IntheDebuggingStoredProcedurestutorialwediscussedthethreeoptionsfordebugging SQLServerthroughVisualStudio:DirectDatabaseDebugging,ApplicationDebugging,and DebuggingfromaSQLServerProject.Manageddatabaseobjectscannotbedebuggedvia DirectDatabaseDebugging,butcanbedebuggedfromaclientapplicationanddirectly fromtheSQLServerProject.Inorderfordebuggingtowork,however,theSQLServer 2005databasemustallowSQL/CLRdebugging.Recallthatwhenwefirstcreatedthe ManagedDatabaseConstructs projectVisualStudioaskeduswhetherwewantedtoenable SQL/CLRdebugging(seeFigure6inStep2).Thissettingcanbemodifiedbyrightclicking onthedatabasefromtheServerExplorerwindow.
30 of38
Figure26:EnsurethattheDatabaseAllowsSQL/CLRDebugging
Figure27:SetaBreakpointintheGetProductsWithPriceLessThan Method
LetsfirstlookatdebuggingthemanageddatabaseobjectsfromtheSQLServerProject. SinceourSolutionincludestwoprojectstheManagedDatabaseConstructs SQLServerProject alongwithourwebsiteinordertodebugfromtheSQLServerProjectweneedtoinstruct VisualStudiotolaunchtheManagedDatabaseConstructs SQLServerProjectwhenwestart debugging.RightclicktheManagedDatabaseConstructs projectinSolutionExplorerandchoose theSetasStartUpProjectoptionfromthecontextmenu. WhentheManagedDatabaseConstructs projectislaunchedfromthedebuggeritexecutesthe SQLstatementsintheTest.sql file,whichislocatedintheTestScripts folder.Forexample, totesttheGetProductsWithPriceLessThan managedstoredprocedure,replacetheexisting Test.sql filecontentwiththefollowingstatement,whichinvokesthe GetProductsWithPriceLessThan managedstoredprocedurepassinginthe@CategoryID value of14.95:
execGetProductsWithPriceLessThan14.95
31 of38
Figure28:TheBreakpointintheGetProductsWithPriceLessThan MethodWasHit
InorderforaSQLdatabaseobjecttobedebuggedthroughaclientapplication,itis imperativethatthedatabasebeconfiguredtosupportapplicationdebugging.Rightclickon thedatabaseinServerExplorerandensurethattheApplicationDebuggingoptionis checked.Furthermore,weneedtoconfiguretheASP.NETapplicationtointegratewiththe SQLDebuggerandtodisableconnectionpooling.Thesestepswerediscussedindetailin Step2oftheDebuggingStoredProcedurestutorial. OnceyouhaveconfiguredtheASP.NETapplicationanddatabase,settheASP.NETwebsite asthestartupprojectandstartdebugging.Ifyouvisitapagethatcallsoneofthe managedobjectsthathasabreakpoint,theapplicationwillhaltandcontrolwillbeturned overtothedebugger,whereyoucanstepthroughthecodeasshowninFigure28.
Step13:ManuallyCompilingandDeployingManaged DatabaseObjects
SQLServerProjectsmakeiteasytocreate,compile,anddeploymanageddatabase objects.Unfortunately,SQLServerProjectsareonlyavailableintheProfessionalandTeam
32 of38
ThiscodeisnearlyidenticaltothatoftheGetProductsWithPriceLessThan methodcreatedin Step5.Theonlydifferencesarethemethodnames,theWHERE clause,andtheparameter nameusedinthequery.BackintheGetProductsWithPriceLessThan method,theWHERE clause read:WHEREUnitPrice<@MaxPrice.Here,inGetProductsWithPriceGreaterThan,weuse:WHERE UnitPrice>@MinPrice. Wenowneedtocompilethisclassintoanassembly.Fromthecommandline,navigateto thedirectorywhereyousavedtheGetProductsWithPriceGreaterThan.cs fileandusetheC# compiler(csc.exe)tocompiletheclassfileintoanassembly:
csc.exe/t:library/out:ManuallyCreatedDBObjects.dllGetProductsWithPriceGreaterThan.cs
33 of38
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe/t:library/out:ManuallyCreatedDBObjects
Figure29:CompileGetProductsWithPriceGreaterThan.cs IntoanAssembly
The/t flagspecifiesthattheC#classfileshouldbecompiledintoaDLL(ratherthanan executable).The/out flagspecifiesthenameoftheresultingassembly. Note:RatherthancompilingtheGetProductsWithPriceGreaterThan.cs classfilefromthe commandlineyoucouldalternativelyuseVisualC#ExpressEditionorcreatea separateClassLibraryprojectinVisualStudioStandardEdition.SrenJacobLauritsen haskindlyprovidedsuchaVisualC#ExpressEditionprojectwithcodeforthe GetProductsWithPriceGreaterThan storedprocedureandthetwomanagedstored proceduresandUDFcreatedinSteps3,5,and10.SrensprojectalsoincludestheT SQLcommandsneededtoaddthecorrespondingdatabaseobjects. Withthecodecompiledintoanassembly,wearereadytoregistertheassemblywithinthe SQLServer2005database.ThiscanbeperformedthroughTSQL,usingthecommand CREATEASSEMBLY,orthroughSQLServerManagementStudio.Letsfocusonusing ManagementStudio. FromManagementStudio,expandtheProgrammabilityfolderintheNorthwinddatabase. OneofitssubfolderisAssemblies.TomanuallyaddanewAssemblytothedatabase,right clickontheAssembliesfolderandchooseNewAssemblyfromthecontextmenu.This displaystheNewAssemblydialogbox(seeFigure30).ClickontheBrowsebutton,select theManuallyCreatedDBObjects.dll assemblywejustcompiled,andthenclickOKtoaddthe Assemblytothedatabase.YoushouldnotseetheManuallyCreatedDBObjects.dll assemblyin theObjectExplorer.
34 of38
Figure30:AddtheManuallyCreatedDBObjects.dll AssemblytotheDatabase
35 of38
Figure31:TheManuallyCreatedDBObjects.dll isListedintheObjectExplorer
ThiscreatesanewstoredprocedureintheNorthwinddatabasenamed GetProductsWithPriceGreaterThan andassociatesitwiththemanagedmethod GetProductsWithPriceGreaterThan (whichisintheclassStoredProcedures ,whichisinthe assemblyManuallyCreatedDBObjects). Afterexecutingtheabovescript,refreshtheStoredProceduresfolderintheObject Explorer.YoushouldseeanewstoredprocedureentryGetProductsWithPriceGreaterThan whichhasalockiconnexttoit.Totestthisstoredprocedure,enterandexecutethe followingscriptinthequerywindow:
36 of38
execGetProductsWithPriceGreaterThan24.95
Figure32:TheManuallyCreatedDBObjects.dll isListedintheObjectExplorer
Summary
MicrosoftSQLServer2005providesintegrationwiththeCommonLanguageRuntime (CLR),whichallowsdatabaseobjectstobecreatedusingmanagedcode.Previously,these databaseobjectscouldonlybecreatedusingTSQL,butnowwecancreatetheseobjects using.NETprogramminglanguageslikeC#.Inthistutorialwecreatedtwomanaged storedproceduresandamanagedUserDefinedFunction. VisualStudiosSQLServerProjecttypefacilitatescreating,compiling,anddeploying manageddatabaseobjects.Moreover,itoffersrichdebuggingsupport.However,SQL ServerProjecttypesareonlyavailableintheProfessionalandTeamSystemseditionsof VisualStudio.ForthoseusingVisualWebDeveloperortheStandardEditionofVisual Studio,thecreation,compilation,anddeploymentstepsmustbeperformedmanually,as wesawinStep13. HappyProgramming!
FurtherReading
37 of38
Formoreinformationonthetopicsdiscussedinthistutorial,refertothefollowing resources:
l l l l l l l l l l
AdvantagesandDrawbacksofUserDefinedFunctions CreatingSQLServer2005ObjectsinManagedCode CreatingTriggersUsingManagedCodeinSQLServer2005 HowTo:CreateandRunaCLRSQLServerStoredProcedure HowTo:CreateandRunaCLRSQLServerUserDefinedFunction HowTo:EdittheTest.sql ScripttoRunSQLObjects IntrotoUserDefinedFunctions ManagedCodeandSQLServer2005(Video) TransactSQLReference Walkthrough:CreatingaStoredProcedureinManagedCode
AbouttheAuthor
ScottMitchell,authorofsevenASP/ASP.NETbooksandfounderof4GuysFromRolla.com, hasbeenworkingwithMicrosoftWebtechnologiessince1998.Scottworksasan independentconsultant,trainer,andwriter.HislatestbookisSamsTeachYourself ASP.NET2.0in24Hours.Hecanbereachedatmitchell@4GuysFromRolla.com.orviahis blog,whichcanbefoundathttp://ScottOnWriting.NET.
SpecialThanksTo
Thistutorialserieswasreviewedbymanyhelpfulreviewers.Leadreviewerforthistutorial wasSrenJacobLauritsen.Inadditiontoreviewingthisarticle,Srenalsocreatedthe VisualC#ExpressEditionprojectincludedinthisarticlesdownloadformanuallycompiling themanageddatabaseobjects.InterestedinreviewingmyupcomingMSDNarticles?Ifso, [email protected].
38 of38