0% found this document useful (0 votes)
202 views38 pages

Creating Managed SQL Procedures in .NET

This document discusses creating stored procedures and user-defined functions (UDFs) using managed code in SQL Server 2005. It describes moving an existing sample database out of the App_Data folder and attaching it to a SQL Server instance. It then explains how to set up a Visual Studio SQL Server project to create a class library project for managed stored procedures and UDFs that integrate with the sample database. The document provides steps for configuring the solution and projects.

Uploaded by

Anil Wadhave
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
202 views38 pages

Creating Managed SQL Procedures in .NET

This document discusses creating stored procedures and user-defined functions (UDFs) using managed code in SQL Server 2005. It describes moving an existing sample database out of the App_Data folder and attaching it to a SQL Server instance. It then explains how to set up a Visual Studio SQL Server project to create a class library project for managed stored procedures and UDFs that integrate with the sample database. The document provides steps for configuring the solution and projects.

Uploaded by

Anil Wadhave
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

[Link] [Link][Link]

WorkingwithDatainASP.NET2.0::Creating StoredProceduresandUserDefinedFunctionswith ManagedCode Introduction


DatabaseslikeMicrosoftsSQLServer2005usetheTransactStructuredQueryLanguage(TSQL) forinserting, modifying,[Link] thatcanthenbeexecutedasasingle,[Link] Functions(UDFs),aconstructthatwewillexamineingreaterdetailinStep9. Atitscore,[Link],UPDATE,andDELETE statementsinherently applytoallrecordsinthecorrespondingtableandareonlylimitedbytheirWHERE [Link] [Link] [Link],CHARINDEX,and PATINDEX [Link] andWHILE. PriortoMicrosoftSQLServer2005,storedproceduresandUDFscouldonlybedefinedasacollectionofTSQL statements.SQLServer2005,however,wasdesignedtoprovideintegrationwiththe CommonLanguageRuntime (CLR),[Link],thestoredproceduresandUDFsinaSQL [Link],youcancreateastoredprocedureorUDFasa methodinaC#[Link] Frameworkandfromyourowncustomclasses. InthistutorialwewillexaminehowtocreatemanagedstoredproceduresandUserDefinedFunctionsandhowto [Link]! Note:[Link] [Link] objectsarelikelytobelessefficientwhenworkingwithsetsofdatathatdonotinvolvemuchprocedural [Link],checkoutthe AdvantagesofUsingManagedCodetoCreateDatabaseObjects.

Step1:MovingtheNorthwindDatabaseOutofApp_Data
AllofourtutorialsthusfarhaveusedaMicrosoftSQLServer2005ExpressEditiondatabasefileintheweb applicationsApp_Data folder.PlacingthedatabaseinApp_Data simplifieddistributingandrunningthesetutorials asallofthefileswerelocatedwithinonedirectoryandrequirednoadditionalconfigurationstepstotestthe tutorial. Forthistutorial,however,letsmovetheNorthwinddatabaseoutofApp_Data andexplicitlyregisteritwiththe [Link] databaseintheApp_Data folder,anumberofthestepsaremademuchsimplerbyexplicitlyregisteringthe databasewiththeSQLServer2005ExpressEditiondatabaseinstance. [Link] andNORTHWND_log.LDF placedina 1 of38

[Link],closeVisual [Link] andNORTHWND_log.LDF filesfromthewebsitesApp_Data foldertoafolder [Link] [Link] ServerManagementStudio.IfyouhaveanonExpressEditionofSQLServer2005installedonyourcomputer thenyoulikelyalreadyhaveManagementStudioinstalled.IfyouonlyhaveSQLServer2005ExpressEditionon yourcomputerthentakeamomenttodownloadandinstall MicrosoftSQLServerManagementStudioExpress. LaunchSQLServerManagementStudio.AsFigure1shows,ManagementStudiostartsbyaskingwhatserverto [Link] localhost\SQLExpressfortheservername,choose WindowsAuthenticationinthe Authenticationdropdownlist,andclickConnect.

Figure1:ConnecttotheAppropriateDatabaseInstance

Onceyouveconnected,theObjectExplorerwindowwilllistinformationabouttheSQLServer2005Express Editiondatabaseinstance,includingitsdatabases,securityinformation,managementoptions,andsoforth. WeneedtoattachtheNorthwinddatabaseintheDataFiles folder(orwhereveryoumayhavemovedit)tothe [Link] [Link],drill [Link] file,[Link] Figure2.

2 of38

Figure2:ConnecttotheAppropriateDatabaseInstance

Note:WhenconnectingtotheSQLServer2005ExpressEditioninstancethroughManagementStudiothe AttachDatabasesdialogboxdoesnotallowyoutodrilldownintouserprofiledirectories,suchasMy [Link],[Link] andNORTHWND_log.LDF filesinanonuser profiledirectory. [Link] [Link]


9FE54661B32FDD967F51D71D0D5145CC_LINEARTICLES\DATATUTORIALS\VOLUME3\CSHARP\73 \ASPNET_DATA_TUTORIAL_75_CS\APP_DATA\[Link]

clickingonthedatabaseandchoosingRename.

3 of38

Figure3:RenametheDatabasetoNorthwind

Step2:CreatingaNewSolutionandSQLServerProjectinVisual Studio
TocreatemanagedstoredproceduresorUDFsinSQLServer2005wewillwritethestoredprocedureandUDF logicasC#[Link],wewillneedtocompilethisclassintoanassembly ([Link] file),registertheassemblywiththeSQLServerdatabase,andthencreateastoredprocedureorUDFobject [Link] [Link],compileitfromthecommandlineusingtheC#compiler ([Link]),registeritwiththedatabaseusingtheCREATEASSEMBLY commandorfromManagementStudio,and [Link],theProfessionalandTeamSystems [Link] throughusingtheSQLServerProjecttypetocreateamanagedstoredprocedureandUDF. Note:IfyouareusingVisualWebDeveloperortheStandardeditionofVisualStudio,thenyouwillhaveto usethemanualapproachinstead.Step13providesdetailedinstructionsforperformingthesestepsmanually. IencourageyoutoreadSteps2through12beforereadingStep13sincethesestepsincludeimportantSQL ServerconfigurationinstructionsthatmustbeappliedregardlessofwhatversionofVisualStudioyouare using. [Link],chooseNewProjecttodisplaytheNewProjectdialogbox (seeFigure4).DrilldowntotheDatabaseprojecttypeandthen,fromtheTemplateslistedontheright,chooseto [Link] andplacedit withinaSolutionnamedTutorial75.

4 of38

Figure4:CreateaNewSQLServerProject

ClicktheOKbuttonintheNewProjectdialogboxtocreatetheSolutionandSQLServerProject. [Link],aftercreatingthenewSQLServerProjectwe areimmediatelyaskedtospecifythisinformation.Figure5showstheNewDatabaseReferencedialogboxthathas beenfilledouttopointtotheNorthwinddatabaseweregisteredintheSQLServer2005ExpressEditiondatabase instancebackinStep1.

5 of38

Figure5:AssociatetheSQLServerProjectwiththeNorthwindDatabase

InordertodebugthemanagedstoredproceduresandUDFswewillcreatewithinthisproject,weneedtoenable SQL/[Link] (aswedidinFigure5),VisualStudioasksusifwewanttoenableSQL/CLRdebuggingontheconnection(see Figure6).ClickYes.

6 of38

Figure6:EnableSQL/CLRDebugging

[Link] [Link],[Link] willlookatdebugginginStep12. WecannowaddnewmanagedstoredproceduresandUDFstothisproject,butbeforewedoletsfirstincludeour [Link]. BrowsetotheappropriatewebsitefolderandclickOK.AsFigure7shows,thiswillupdatetheSolutiontoinclude twoprojects:thewebsiteandtheManagedDatabaseConstructs SQLServerProject.

Figure7:TheSolutionExplorerNowIncludesTwoProjects

7 of38

TheNORTHWNDConnectionString [Link] [Link] fileinthe App_Data folder.SinceweremovedthisdatabasefromApp_Data andexplicitlyregistereditintheSQLServer 2005ExpressEditiondatabaseinstance,weneedtocorrespondinglyupdatetheNORTHWNDConnectionString [Link] fileinthewebsiteandchangetheNORTHWNDConnectionString valuesothatthe connectionstringreads:DataSource=localhost\SQLExpressInitialCatalog=NorthwindIntegrated Security=True. Afterthischange,your<connectionStrings> [Link] shouldlooksimilartothe following:
<connectionStrings> <addname="NORTHWNDConnectionString"connectionString= "DataSource=localhost\SQLExpressInitialCatalog=Northwind IntegratedSecurity=TruePooling=false" providerName="[Link]"/> </connectionStrings>

Note:Asdiscussedintheprecedingtutorial,whendebuggingaSQLServerobjectfromaclientapplication, [Link],[Link] disablesconnectionpooling(Pooling=false).Ifyoudonotplanondebuggingthemanagedstored [Link],enableconnectionpooling.

Step3:CreatingaManagedStoredProcedure
ToaddamanagedstoredproceduretotheNorthwinddatabasewefirstneedtocreatethestoredprocedureasa [Link],rightclickontheManagedDatabaseConstructs [Link],whichliststhetypes ofmanageddatabaseobjectsthatcanbeaddedtotheproject.AsFigure8shows,thisincludesstoredprocedures andUserDefinedFunctions,amongothers. [Link] [Link].

8 of38

Figure8:AddaNewStoredProcedureNamed [Link]

ThiswillcreateanewC#classfilewiththefollowingcontent:
usingSystem [Link] [Link] [Link] [Link] publicpartialclassStoredProcedures { [[Link]] publicstaticvoidGetDiscontinuedProducts() { //Putyourcodehere } }

Notethatthestoredprocedureisimplementedasastatic methodwithinapartial classfilenamed [Link],theGetDiscontinuedProducts methodisdecoratedwiththeSqlProcedure attribute,whichmarksthemethodasastoredprocedure. ThefollowingcodecreatesaSqlCommand objectandsetsitsCommandText toaSELECT query thatreturnsallofthecolumnsfromtheProducts tableforproductswhoseDiscontinued field [Link] [Link] method.
//Createthecommand SqlCommandmyCommand=newSqlCommand() [Link]= @"SELECTProductID,ProductName,SupplierID,CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder, ReorderLevel,Discontinued FROMProducts WHEREDiscontinued=1" //Executethecommandandsendbacktheresults [Link](myCommand)

AllmanageddatabaseobjectshaveaccesstoaSqlContext objectthatrepresentsthe [Link] providesaccesstoaSqlPipe objectviaitsPipe [Link] objectisusedtoferryinformationbetweentheSQLServerdatabase [Link],theExecuteAndSend methodexecutesa passedinSqlCommand objectandsendstheresultsbacktotheclientapplication. Note:ManageddatabaseobjectsarebestsuitedforstoredproceduresandUDFsthat [Link] [Link] GetDiscontinuedProducts methodwejustcreated,however,involvesnoprocedural [Link],[Link]

9 of38

implementedasamanagedstoredproceduretodemonstratethestepsnecessaryfor creatinganddeployingmanagedstoredprocedures.

Step4:DeployingtheManagedStoredProcedure
Withthiscodecomplete,[Link] SQLServerProjectcompilesthecodeintoanassembly,registerstheassemblywiththe database,andcreatesthecorrespondingobjectsinthedatabase,linkingthemtothe [Link] [Link] [Link],deployment failswiththefollowingerror:Incorrectsyntaxnear'EXTERNAL'.Youmayneedtosetthe [Link] helpforthestoredproceduresp_dbcmptlevel. ThiserrormessageoccurswhenattemptingtoregistertheassemblywiththeNorthwind database.InordertoregisteranassemblywithaSQLServer2005database,the [Link],newSQLServer2005 [Link],databasescreatedusingMicrosoft [Link] wasinitiallyaMicrosoftSQLServer2000database,itscompatibilityleveliscurrentlysetto 80andthereforeneedstobeincreasedto90inordertoregistermanageddatabase objects. Toupdatethedatabasescompatibilitylevel,openaNewQuerywindowinManagement Studioandenter:
execsp_dbcmptlevel'Northwind',90

ClicktheExecuteiconintheToolbartoruntheabovequery.

10 of38

Figure9:UpdatetheNorthwindDatabasesCompatibilityLevel

Afterupdatingthecompatibilitylevel,[Link] deploymentshouldcompletewithouterror. ReturntoSQLServerManagementStudio,rightclickontheNorthwinddatabaseinthe ObjectExplorer,[Link],drilldownintotheProgrammabilityfolderand thenexpandtheAssembliesfolder.AsFigure10shows,theNorthwinddatabasenow includestheassemblygeneratedbytheManagedDatabaseConstructs project.

Figure10:TheManagedDatabaseConstructs AssemblyisNowRegisteredwiththe NorthwindDatabase

[Link] [Link] pointstotheGetDiscontinuedProducts methodinthe ManagedDatabaseConstructs assembly.

11 of38

WhentheGetDiscontinuedProducts storedprocedureisexecuted,it,inturn,executesthe GetDiscontinuedProducts [Link] editedthroughManagementStudio(hencethelockiconnexttothestoredprocedure name).

Figure11:TheGetDiscontinuedProducts StoredProcedureisListedintheStored ProceduresFolder

Thereisstillonemorehurdlewehavetoovercomebeforewecancallthemanagedstored procedure:[Link] byopeninganewquerywindowandexecutingtheGetDiscontinuedProducts stored [Link]:Executionofusercodein [Link]. ToexaminetheNorthwinddatabasesconfigurationinformation,enterandexecutethe 12 of38

commandexecsp_configureinthequerywindow.Thisshowsthattheclrenabled settingiscurrentlysetto0.

Figure12:TheclrenabledSettingisCurrentlySetto0

NotethateachconfigurationsettinginFigure12hasfourvalueslistedwithit:the [Link] fortheclrenabledsetting,executethefollowingcommand:


execsp_configure'clrenabled',1

Ifyoureruntheexecsp_configureyouwillseethattheabovestatementupdatedtheclr enabledsettingsconfigvalueto1,[Link] configurationchangetotakeaffectweneedtoexecutetheRECONFIGURE command,which [Link] windowandclicktheExecuteiconintheToolbar.Ifyourunexecsp_configurenowyou shouldseeavalueof1fortheclrenabledsettingsconfigandrunvalues. Withtheclrenabledconfigurationcomplete,wearereadytorunthemanaged GetDiscontinuedProducts [Link] [Link] correspondingmanagedcodeintheGetDiscontinuedProducts [Link] issuesaSELECT querytoreturnallproductsthatarediscontinuedandreturnsthisdatato thecallingapplication,whichisSQLServerManagementStudiointhisinstance. ManagementStudioreceivestheseresultsanddisplaysthemintheResultswindow.

13 of38

Figure13:TheGetDiscontinuedProducts StoredProcedureReturnsAllDiscontinued Products

Step5:CreatingManagedStoredProceduresthat AcceptInputParameters
Manyofthequeriesandstoredprocedureswehavecreatedthroughoutthesetutorials [Link],intheCreatingNewStoredProceduresfortheTyped DataSetsTableAdapterstutorialwecreatedastoredprocedurenamed GetProductsByCategoryID thatacceptedaninputparameternamed@CategoryID .Thestored procedurethenreturnedallproductswhoseCategoryID fieldmatchedthevalueofthe supplied@CategoryID parameter. Tocreateamanagedstoredprocedurethatacceptsinputparameters,simplyspecifythose [Link],letsaddanothermanagedstored proceduretotheManagedDatabaseConstructs [Link] managedstoredprocedurewillacceptaninputparameterspecifyingapriceandwillreturn allproductswhoseUnitPrice fieldislessthantheparametersvalue. Toaddanewstoredproceduretotheproject,rightclickontheManagedDatabaseConstructs [Link] [Link].AswesawinStep3,thiswillcreateanewC#classfile withamethodnamedGetProductsWithPriceLessThan placedwithinthepartial class StoredProcedures. UpdatetheGetProductsWithPriceLessThan methodsdefinitionsothatitacceptsaSqlMoney inputparameternamedprice andwritethecodetoexecuteandreturnthequeryresults:
[[Link]] publicstaticvoidGetProductsWithPriceLessThan(SqlMoneyprice) { //Createthecommand

14 of38

SqlCommandmyCommand=newSqlCommand() [Link]= @"SELECTProductID,ProductName,SupplierID,CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder, ReorderLevel,Discontinued FROMProducts WHEREUnitPrice<@MaxPrice" [Link]("@MaxPrice",price) //Executethecommandandsendbacktheresults [Link](myCommand) }

TheGetProductsWithPriceLessThan methodsdefinitionandcodecloselyresemblesthe definitionandcodeoftheGetDiscontinuedProducts [Link] differencesarethattheGetProductsWithPriceLessThan methodacceptsasinputparameter (price),the SqlCommandsqueryincludesaparameter(@MaxPrice),andaparameterisadded totheSqlCommandsParameters collectionisandassignedthevalueoftheprice variable. Afteraddingthiscode,[Link],returntoSQLServer [Link], [Link],enterandexecutethecommandexec GetProductsWithPriceLessThan25,whichwilllistallproductslessthan$25,asFigure14 shows.

Figure14:ProductsUnder$25areDisplayed

Step6:CallingtheManagedStoredProcedurefrom theDataAccessLayer
15 of38

AtthispointwehaveaddedtheGetDiscontinuedProducts andGetProductsWithPriceLessThan managedstoredprocedurestotheManagedDatabaseConstructs projectandhaveregistered [Link] proceduresfromSQLServerManagementStudio(seeFigures13and14).Inorderforour [Link],however,weneedtoadd [Link] addtwonewmethodstotheProductsTableAdapter intheNorthwindWithSprocs TypedDataSet, whichwasinitiallycreatedintheCreatingNewStoredProceduresfortheTypedDataSets TableAdapterstutorial.InStep7wewilladdcorrespondingmethodstotheBLL. OpentheNorthwindWithSprocs TypedDataSetinVisualStudioandstartbyaddinganew methodtotheProductsTableAdapter [Link] aTableAdapter,rightclickontheTableAdaptersnameintheDesignerandchoosetheAdd Queryoptionfromthecontextmenu. Note:SincewemovedtheNorthwinddatabasefromtheApp_Data foldertotheSQL Server2005ExpressEditiondatabaseinstance,itisimperativethatthecorresponding [Link].InStep2we discussedupdatingtheNORTHWNDConnectionString [Link] makethisupdate,[Link] [Link] [Link],clickOK [Link] andupdatetheNORTHWNDConnectionString valueasdiscussed [Link] workwithouterror. AddinganewmethodlaunchestheTableAdapterQueryConfigurationwizard,whichwe [Link] TableAdaptershouldaccessthedatabase:throughanadhocSQLstatementorviaanew [Link] GetDiscontinuedProducts managedstoredprocedurewiththedatabase,choosetheUse existingstoredprocedureoptionandhitNext.

16 of38

Figure15:ChoosetheUseexistingstoredprocedureOption

[Link] GetDiscontinuedProducts managedstoredprocedurefromthedropdownlistandhitNext.

17 of38

Figure16:SelecttheGetDiscontinuedProducts ManagedStoredProcedure

Wearethenaskedtospecifywhetherthestoredprocedurereturnsrows,asinglevalue,or [Link] returnsthesetofdiscontinuedproductrows,choose thefirstoption(Tabulardata)andclickNext.

18 of38

Figure17:SelecttheTabularDataOption

Thefinalwizardscreenallowsustospecifythedataaccesspatternsusedandthenames [Link] FillByDiscontinued [Link].

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 [Link] ProductsBLLWithSprocs class:
[[Link] ([Link],false)] [Link]() { [Link]() } [[Link] ([Link],false)] [Link] GetProductsWithPriceLessThan(decimalpriceLessThan) { [Link](priceLessThan)

21 of38

BothmethodssimplycallthecorrespondingDALmethodandreturntheProductsDataTable [Link] markupaboveeachmethodcausesthesemethods tobeincludedinthedropdownlistintheSELECTtaboftheObjectDataSourcesConfigure DataSourcewizard.

Step8:InvokingtheManagedStoredProceduresfrom thePresentationLayer
WiththeBusinessLogicandDataAccessLayersaugmentedtoincludesupportforcalling theGetDiscontinuedProducts andGetProductsWithPriceLessThan managedstoredprocedures, [Link]. [Link] pageintheAdvancedDAL folderand,fromthe Toolbox,[Link] propertyto DiscontinuedProducts and,fromitssmarttag,bindittoanewObjectDataSourcenamed [Link] ProductsBLLWithSprocs classsGetDiscontinuedProducts method.

Figure20:ConfiguretheObjectDataSourcetoUsetheProductsBLLWithSprocs Class

22 of38

Figure21:ChoosetheGetDiscontinuedProducts MethodfromtheDropDownListin theSELECTTab

Sincethisgridwillbeusedtojustdisplayproductinformation,setthedropdownlistsin theUPDATE,INSERT,andDELETEtabsto(None)andthenclickFinish. Uponcompletingthewizard,VisualStudiowillautomaticallyaddaBoundFieldor [Link] thesefieldsexceptforProductName andDiscontinued,atwhichpointyourGridViewand ObjectDataSourcesdeclarativemarkupshouldlooksimilartothefollowing:


<asp:GridViewID="DiscontinuedProducts"runat="server" AutoGenerateColumns="False"DataKeyNames="ProductID" DataSourceID="DiscontinuedProductsDataSource"> <Columns> <asp:BoundFieldDataField="ProductName"HeaderText="ProductName" SortExpression="ProductName"/> <asp:CheckBoxFieldDataField="Discontinued" HeaderText="Discontinued" SortExpression="Discontinued"/> </Columns> </asp:GridView> <asp:ObjectDataSourceID="DiscontinuedProductsDataSource"runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetDiscontinuedProducts"TypeName="ProductsBLLWithSprocs">

23 of38

</asp:ObjectDataSource>

[Link],the ObjectDataSourcecallstheProductsBLLWithSprocs classsGetDiscontinuedProducts [Link] wesawinStep7,thismethodcallsdowntotheDALsProductsDataTable classs GetDiscontinuedProducts method,whichinvokestheGetDiscontinuedProducts stored [Link] createdinStep3,returningthediscontinuedproducts. Theresultsreturnedbythemanagedstoredprocedurearepackagedupintoa ProductsDataTable bytheDALandthenreturnedtotheBLL,whichthenreturnsthemtothe [Link],the gridliststhoseproductsthathavebeendiscontinued.

Figure22:TheDiscontinuedProductsareListed

Forfurtherpractice,[Link] displaytheproductslessthantheamountenteredintotheTextBoxbycallingthe ProductsBLLWithSprocs classsGetProductsWithPriceLessThan method.

24 of38

Step9:CreatingandCallingTSQLUDFs
UserDefinedFunctions,orUDFs,aredatabaseobjectsthecloselymimicthesemanticsof [Link]#,UDFscanincludeavariable [Link] eitherscalardataastring,aninteger,[Link] lookatbothtypesofUDFs,startingwithaUDFthatreturnsascalardatatype. ThefollowingUDFcalculatestheestimatedvalueoftheinventoryforaparticularproduct. ItdoessobytakinginthreeinputparameterstheUnitPrice,UnitsInStock,and Discontinued [Link] theestimatedvalueoftheinventorybymultiplyingtheUnitPrice [Link] 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

OncethisUDFhasbeenaddedtothedatabase,itcanbefoundthroughManagement StudiobyexpandingtheProgrammabilityfolder,thenFunctions,andthenScalarvalue [Link] querylikeso:


SELECTProductID,ProductName,dbo.udf_ComputeInventoryValue (UnitPrice,UnitsInStock,Discontinued)asInventoryValue FROMProducts ORDERBYInventoryValueDESC

Ihaveaddedtheudf_ComputeInventoryValue UDFtotheNorthwinddatabaseFigure23 showstheoutputoftheaboveSELECT querywhenviewedthroughManagementStudio. AlsonotethattheUDFislistedundertheScalarvalueFunctionsfolderintheObject Explorer.

25 of38

Figure23:EachProductsInventoryValuesisListed

[Link],wecancreateaUDFthatreturnsproducts thatbelongtoaparticularcategory:
CREATEFUNCTIONdbo.udf_GetProductsByCategoryID ( @CategoryIDint ) RETURNSTABLE AS RETURN ( SELECTProductID,ProductName,SupplierID,CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder, ReorderLevel,Discontinued FROMProducts WHERECategoryID=@CategoryID )

Theudf_GetProductsByCategoryID UDFacceptsa@CategoryID inputparameterandreturnsthe resultsofthespecifiedSELECT [Link],thisUDFcanbereferencedintheFROM (orJOIN)clauseofaSELECT [Link], ProductName,andCategoryID valuesforeachofthebeverages.

26 of38

SELECTProductID,ProductName,CategoryID FROMdbo.udf_GetProductsByCategoryID(1)

Ihaveaddedtheudf_GetProductsByCategoryID UDFtotheNorthwinddatabaseFigure24 showstheoutputoftheaboveSELECT querywhenviewedthroughManagementStudio. UDFsthatreturntabulardatacanbefoundintheObjectExplorersTablevalueFunctions folder.

Figure24:TheProductID,ProductName,andCategoryID areListedforEachBeverage

Note:FormoreinformationoncreatingandusingUDFs,checkoutIntrotoUser [Link] Functions.

Step10:CreatingaManagedUDF
Theudf_ComputeInventoryValue andudf_GetProductsByCategoryID UDFscreatedintheabove examplesareTSQLdatabaseobjects.SQLServer2005alsosupportsmanagedUDFs, whichcanbeaddedtotheManagedDatabaseConstructs projectjustlikethemanagedstored [Link],letsimplementtheudf_ComputeInventoryValue UDFinmanagedcode. ToaddamanagedUDFtotheManagedDatabaseConstructs project,rightclickontheproject 27 of38

[Link] TemplatefromtheAddNewItemdialogboxandnamethenewUDFfile udf_ComputeInventoryValue_Managed.cs.

Figure25:AddaNewManagedUDFtotheManagedDatabaseConstructs Project

TheUserDefinedFunctiontemplatecreatesapartial classnamedUserDefinedFunctions withamethodwhosenameisthesameastheclassfilesname (udf_ComputeInventoryValue_Managed,inthisinstance).Thismethodisdecoratedusingthe SqlFunction attribute,whichflagsthemethodasamanagedUDF.


usingSystem [Link] [Link] [Link] [Link] publicpartialclassUserDefinedFunctions { [[Link]] publicstaticSqlStringudf_ComputeInventoryValue_Managed() { //Putyourcodehere returnnewSqlString("Hello") } }

Theudf_ComputeInventoryValue methodcurrentlyreturnsaSqlString objectanddoesnot [Link] threeinputparametersUnitPrice,UnitsInStock,andDiscontinued andreturnsaSqlMoney

28 of38

[Link] udf_ComputeInventoryValue UDF.


[[Link]] publicstaticSqlMoneyudf_ComputeInventoryValue_Managed (SqlMoneyUnitPrice,SqlInt16UnitsInStock,SqlBooleanDiscontinued) { SqlMoneyinventoryValue=0 if(![Link]&&![Link]) { inventoryValue=UnitPrice*UnitsInStock if(Discontinued==true) inventoryValue=inventoryValue*newSqlMoney(0.5) } returninventoryValue }

NotethattheUDFmethodsinputparametersareoftheircorrespondingSQLtypes: SqlMoney fortheUnitPrice field,SqlInt16 for UnitsInStock,andSqlBoolean for Discontinued. ThesedatatypesreflectthetypesdefinedintheProducts table:theUnitPrice columnisof typemoney,theUnitsInStock columnoftypesmallint,andtheDiscontinued columnoftype bit. ThecodestartsbycreatingaSqlMoney instancenamedinventoryValue thatisassigneda [Link] tableallowsfordatabaseNULL valuesintheUnitsInPrice and UnitsInStock [Link],weneedtofirstchecktoseeifthesevaluescontainNULLs, whichwedothroughtheSqlMoney objectsIsNull [Link] and UnitsInStock containnonNULL values,thenwecomputetheinventoryValue tobetheproduct [Link],ifDiscontinued istrue,thenwehalvethevalue. Note:TheSqlMoney objectonlyallowstwoSqlMoney instancestobemultipliedtogether. ItdoesnotallowaSqlMoney instancetobemultipliedbyaliteralfloatingpoint [Link],tohalveinventoryValue wemultiplyitbyanew SqlMoney instance thathasthevalue0.5.

Step11:DeployingtheManagedUDF
NowthatthatthemanagedUDFhasbeencreated,wearereadytodeployittothe Northwinddatabase.AswesawinStep4,themanagedobjectsinaSQLServerProject aredeployedbyrightclickingontheprojectnameintheSolutionExplorerandchoosing theDeployoptionfromthecontextmenu. Onceyouhavedeployedtheproject,returntoSQLServerManagementStudioandrefresh [Link]:
l l

dbo.udf_ComputeInventoryValue theTSQLUDFcreatedinStep9,and dbo.udfComputeInventoryValue_Managed themanagedUDFcreatedinStep10thatwas

justdeployed. 29 of38

TotestthismanagedUDF,executethefollowingqueryfromwithinManagementStudio:
SELECTProductID,ProductName, dbo.udf_ComputeInventoryValue_Managed( UnitPrice, UnitsInStock, Discontinued )asInventoryValue FROMProducts ORDERBYInventoryValueDESC

ThiscommandusesthemanagedudfComputeInventoryValue_Managed UDFinsteadoftheT SQLudf_ComputeInventoryValue UDF,buttheoutputisthesame.ReferbacktoFigure23to seeascreenshotoftheUDFsoutput.

Step12:DebuggingtheManagedDatabaseObjects
IntheDebuggingStoredProcedurestutorialwediscussedthethreeoptionsfordebugging SQLServerthroughVisualStudio:DirectDatabaseDebugging,ApplicationDebugging,and [Link] DirectDatabaseDebugging,butcanbedebuggedfromaclientapplicationanddirectly [Link],however,theSQLServer 2005databasemustallowSQL/[Link] ManagedDatabaseConstructs projectVisualStudioaskeduswhetherwewantedtoenable SQL/CLRdebugging(seeFigure6inStep2).Thissettingcanbemodifiedbyrightclicking onthedatabasefromtheServerExplorerwindow.

30 of38

Figure26:EnsurethattheDatabaseAllowsSQL/CLRDebugging

ImaginethatwewantedtodebugtheGetProductsWithPriceLessThan managedstored [Link] GetProductsWithPriceLessThan method.

Figure27:SetaBreakpointintheGetProductsWithPriceLessThan Method

LetsfirstlookatdebuggingthemanageddatabaseobjectsfromtheSQLServerProject. SinceourSolutionincludestwoprojectstheManagedDatabaseConstructs SQLServerProject alongwithourwebsiteinordertodebugfromtheSQLServerProjectweneedtoinstruct VisualStudiotolaunchtheManagedDatabaseConstructs SQLServerProjectwhenwestart [Link] projectinSolutionExplorerandchoose theSetasStartUpProjectoptionfromthecontextmenu. WhentheManagedDatabaseConstructs projectislaunchedfromthedebuggeritexecutesthe [Link] file,whichislocatedintheTestScripts [Link], totesttheGetProductsWithPriceLessThan managedstoredprocedure,replacetheexisting [Link] filecontentwiththefollowingstatement,whichinvokesthe GetProductsWithPriceLessThan managedstoredprocedurepassinginthe@CategoryID value of14.95:
execGetProductsWithPriceLessThan14.95

[Link],startdebuggingbygoingtotheDebug menuandchoosingStartDebuggingorbyhittingF5orthegreenplayiconintheToolbar. ThiswillbuildtheprojectswithintheSolution,deploythemanageddatabaseobjectstothe Northwinddatabase,[Link] [Link],thebreakpointwill

31 of38

behitandwecanstepthroughtheGetProductsWithPriceLessThan method,examinethe valuesoftheinputparameters,andsoon.

Figure28:TheBreakpointintheGetProductsWithPriceLessThan MethodWasHit

InorderforaSQLdatabaseobjecttobedebuggedthroughaclientapplication,itis [Link] thedatabaseinServerExplorerandensurethattheApplicationDebuggingoptionis [Link],[Link] [Link] Step2oftheDebuggingStoredProcedurestutorial. [Link],[Link] [Link] managedobjectsthathasabreakpoint,theapplicationwillhaltandcontrolwillbeturned overtothedebugger,whereyoucanstepthroughthecodeasshowninFigure28.

Step13:ManuallyCompilingandDeployingManaged DatabaseObjects
SQLServerProjectsmakeiteasytocreate,compile,anddeploymanageddatabase [Link],SQLServerProjectsareonlyavailableintheProfessionalandTeam

32 of38

[Link] EditionofVisualStudioandwanttousemanageddatabaseobjects,youwillneedto [Link]: 1. 2. 3. 4. Createafilethatcontainsthesourcecodeforthemanageddatabaseobject, Compiletheobjectintoanassembly, RegistertheassemblywiththeSQLServer2005database,and CreateadatabaseobjectinSQLServerthatpointstotheappropriatemethodinthe assembly.

Toillustratethesetasks,letscreateanewmanagedstoredprocedurethatreturnsthose productswhoseUnitPrice [Link] [Link] andenterthefollowingcodeintothe file(youcanuseVisualStudio,Notepad,oranytexteditortoaccomplishthis):


usingSystem [Link] [Link] [Link] [Link] publicpartialclassStoredProcedures { [[Link]] publicstaticvoidGetProductsWithPriceGreaterThan(SqlMoneyprice) { //Createthecommand SqlCommandmyCommand=newSqlCommand() [Link]= @"SELECTProductID,ProductName,SupplierID,CategoryID, QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder, ReorderLevel,Discontinued FROMProducts WHEREUnitPrice>@MinPrice" [Link]("@MinPrice",price) //Executethecommandandsendbacktheresults [Link](myCommand) } }

ThiscodeisnearlyidenticaltothatoftheGetProductsWithPriceLessThan methodcreatedin [Link],theWHERE clause,andtheparameter [Link] method,theWHERE clause read:WHEREUnitPrice<@[Link],inGetProductsWithPriceGreaterThan,weuse:WHERE UnitPrice>@MinPrice. [Link],navigateto [Link] fileandusetheC# compiler([Link])tocompiletheclassfileintoanassembly:
[Link]/t:library/out:[Link]

33 of38

[Link] innotinthesystemsPATH,youwillhavetofullyreference itspath,%WINDOWS%\[Link]\Framework\version\,likeso:

C:\WINDOWS\[Link]\Framework\v2.0.50727\[Link]/t:library/out:ManuallyCreatedDBObjects

Figure29:[Link] IntoanAssembly

The/t flagspecifiesthattheC#classfileshouldbecompiledintoaDLL(ratherthanan executable).The/out flagspecifiesthenameoftheresultingassembly. Note:[Link] classfilefromthe commandlineyoucouldalternativelyuseVisualC#ExpressEditionorcreatea [Link] haskindlyprovidedsuchaVisualC#ExpressEditionprojectwithcodeforthe GetProductsWithPriceGreaterThan storedprocedureandthetwomanagedstored proceduresandUDFcreatedinSteps3,5,[Link] SQLcommandsneededtoaddthecorrespondingdatabaseobjects. Withthecodecompiledintoanassembly,wearereadytoregistertheassemblywithinthe [Link],usingthecommand CREATEASSEMBLY,[Link] ManagementStudio. FromManagementStudio,expandtheProgrammabilityfolderintheNorthwinddatabase. [Link],right [Link] displaystheNewAssemblydialogbox(seeFigure30).ClickontheBrowsebutton,select [Link] assemblywejustcompiled,andthenclickOKtoaddthe [Link] assemblyin theObjectExplorer.

34 of38

Figure30:[Link] AssemblytotheDatabase

35 of38

Figure31:[Link] isListedintheObjectExplorer

WhilewehaveaddedtheassemblytotheNorthwinddatabase,wehaveyettoassociatea storedprocedurewiththeGetProductsWithPriceGreaterThan [Link] accomplishthis,openanewquerywindowandexecutethefollowingscript:

CREATEPROCEDURE[dbo].[GetProductsWithPriceGreaterThan] ( @price[numeric](18,0) ) WITHEXECUTEASCALLER AS EXTERNALNAME[ManuallyCreatedDBObjects].[StoredProcedures].[GetProductsWithPriceGreaterThan] GO

ThiscreatesanewstoredprocedureintheNorthwinddatabasenamed GetProductsWithPriceGreaterThan andassociatesitwiththemanagedmethod GetProductsWithPriceGreaterThan (whichisintheclassStoredProcedures ,whichisinthe assemblyManuallyCreatedDBObjects). Afterexecutingtheabovescript,refreshtheStoredProceduresfolderintheObject [Link] [Link],enterandexecutethe followingscriptinthequerywindow:

36 of38

execGetProductsWithPriceGreaterThan24.95

AsFigure32shows,theabovecommanddisplaysinformationforthoseproductswitha UnitPrice greaterthan$24.95.

Figure32:[Link] isListedintheObjectExplorer

Summary
MicrosoftSQLServer2005providesintegrationwiththeCommonLanguageRuntime (CLR),[Link],these databaseobjectscouldonlybecreatedusingTSQL,butnowwecancreatetheseobjects [Link]#.Inthistutorialwecreatedtwomanaged storedproceduresandamanagedUserDefinedFunction. VisualStudiosSQLServerProjecttypefacilitatescreating,compiling,anddeploying [Link],[Link],SQL ServerProjecttypesareonlyavailableintheProfessionalandTeamSystemseditionsof [Link] 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:[Link] ScripttoRunSQLObjects IntrotoUserDefinedFunctions ManagedCodeandSQLServer2005(Video) TransactSQLReference Walkthrough:CreatingaStoredProcedureinManagedCode

AbouttheAuthor
ScottMitchell,authorofsevenASP/[Link], [Link] independentconsultant,trainer,[Link] [Link]@[Link] blog,whichcanbefoundat[Link]

SpecialThanksTo
[Link] [Link],Srenalsocreatedthe VisualC#ExpressEditionprojectincludedinthisarticlesdownloadformanuallycompiling [Link]?Ifso, dropmealineatmitchell@[Link].

38 of38

You might also like