|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在JOIN操作中(需要从多个数据表提取数据时),MySQL只有在主键和外键的数据类型相同时才能使用索引。November19,2003
T-SQLProgrammingPart3-ProcessingSequentiallyThroughaSetofRecords
ByGregoryA.Larsen
Atsomepointyouwillhavesomebusinesslogicthatwillrequireyoutoprocesssequentiallythroughasetofrecordsonerecordatatime.Forexampleyoumayhavealistofdatabases,andforeachdatabaseyoumaywanttobuildacommandthatwillperformsomeprocessagainsteachdatabase.Oryoumighthaveasetofrecordswhereyouwanttoprocessthrougheachrecordoneatatime,soyoucanselectadditionalinformationfromanothertablebasedontheinformationcontainedineachrecord.Thisarticlewilldiscusstwodifferentwaystoprocessthroughasetofrecordsonerecordatatime.
UsingaCursor
ThefirstmethodIwilldiscussusesacursortoprocessthroughasetofrecordsonerecordatatime.Acursorisbasicallyasetofrowsthatyoudefinebasedonarecordsetreturnedfromaquery.Acursorallowsapplicationsamechanismtoprocessthrougharesultsetonerowatatime.Withacursoranapplicationisallowedtopositionitselftoaspecificrow,scrollbackandforth,andanumberofotherthings.Itwouldtakeaseriesofarticlestodescribeallthefunctionalityofacursor.ForthepurposeofthisarticleImonlygoingtofocusonhowtousethedefaultscrollingfunctionalityofacursor.Thisdefaultfunctionalitywillonlyreadfromthefirstrowtothelastrowinacursor,onerowatatime.Iwillleaveadditionalcursortopicstoanotherarticleseries.
TodefineacursortheDECLARECURSORstatementisused.HereisthebasicformatforthesimplecursortopicIwillbediscussinginthisarticle.
DECLAREcursor_nameCURSORFORselect_statement
Thecursor_nameisthenameyouwanttoassociatewiththecursor.Theselect_statementisthequerythatwilldeterminetherowsthatmakeupthecursor.Notethereareotherparameters/optionsassociatedwiththeDECLARECURSORstatementthathelpdefinemorecomplicatedcursorprocessingthanIwillbecoveringinthisarticle.FortheseadditionaloptionspleasereadMicrosoftSQLServerBooksOnline.
Letsreviewafairlysimplecursorexample.Thisexamplewilldefineacursorthatcontainsthetop5Customer_IdsintheCustomertableintheNorthwinddatabase.ItwillthenprocessthrougheachrecorddisplayingarownumberandtheCustomerIDforeach.Hereisthecodetodothis.
declare@CustIdnchar(5)declare@RowNumintdeclareCustListcursorforselecttop5CustomerIDfromNorthwind.dbo.CustomersOPENCustListFETCHNEXTFROMCustListINTO@CustIdset@RowNum=0WHILE@@FETCH_STATUS=0BEGINset@RowNum=@RowNum+1printcast(@RowNumaschar(1))++@CustIdFETCHNEXTFROMCustListINTO@CustIdENDCLOSECustListDEALLOCATECustList
HerearetheresultsthataregeneratedfromtheprintstatementwhenIrunitagainstmyNorthwindDatabase.
1ALFKI2ANATR3ANTON4AROUT5BERGS
Letslookattheabovecodeinalittlemoredetail.Ifirstdeclaredacursorcalled"CustList".The"CustList"cursorispopulatedusingaSELECTstatementthatusestheTOPclausetoreturnonlythetop5CustomerIds.Nextthecursorisopened.Eachrecordinthe"CustList"cursorisretrieved,onerecordatatime,usingthe"FETCHNEXT"nextstatement.The"FETCHNEXT"statementpopulatesthelocalvariable@CustIDwiththeCustomerIDofthecurrentrecordbeingfetched.The@@FETCH_STATUSvariablecontrolswhethertheWHILEloopisexecuted.@@FETCH_STATUSissettozerowhenarecordissuccessfullyretrievedfromthecursor"CustList".InsidetheWHILEloopthe@RowNumvariableisincrementedby1foreachrecordprocessed.ThecalculatedRowNumberand@CustIdarethenprintedout.Lastly,a"FETCHNEXT"statementisusedtoretrievethenextrowbeforethenextcycleoftheWHILEloop.Thisprocesscontinuesonerecordatatimeuntilallrecordsincursor"CustList"havebeenprocessed.
UsingaSelectStatement
YoucanalsouseaSELECTstatementtoprocessthroughasetofrecordsonerecordatatime.TodothisIwillissueaninitialSELECTstatementthatwillreturnthefirstrow,thenaseriesoffollowonSELECTstatementswhereeachSELECTstatementretrievesthenextrow.Thisisdonebyusingthe"TOP1"clauseoftheSELECTstatement,andaWHEREstatement.
Iwillusethesameexampleasaboveandonlyreturnthetop5CustomerIDsfromtheNorthwinddatabaseCustomerstable.InthiscodeIwillusetwodifferent"SELECTTOP1"statementsandaWHILElooptoreturnall5records.Eachrecordwillbeprocessedoneatatime.
declare@CustIdnchar(5)declare@RowNumintselecttop1@CustId=CustomerIDfromNorthwind.dbo.Customersset@RowNum=0WHILE@RowNum<5BEGINset@RowNum=@RowNum+1printcast(@RowNumaschar(1))++@CustIdselecttop1@CustId=CustomerIDfromNorthwind.dbo.CustomerswhereCustomerId>@CustIDEND
HereyoucanseethefirstSELECTstatementselectsonlythefirstCustomerID.ThisIDisplacedinthelocalvariable@CustID.TheWHILEloopiscontroledbythelocalvariable@RowNum.EachtimethroughtheWHILEloop,theRowNumberandCustomerIDareprintedout.PriortoreturningtothetopoftheWHILEloopIusedanother"SELECTTOP1"statementtoselectthenextCustomerID.ThisSELECTstatementusesaWHEREclauseontheSELECTstatementtoselectthefirstCustomerIDthatisgreaterthantheCustomerIDthatwasjustprinted.TheWHILEloopisprocess5times,allowingtheSELECTTOP1methodtoretrievethetop5CustomerIDsonerecordsatatime.ThisexampleproducesthesameprintedoutputasmypriorCURSORexample.
Conclusion
HopefullythisarticlehasgivenyousomeideasonhowtouseaCURSOR,andaSELECTstatementtoprocessthroughasetofrecords.Iusebothofthesemethods,althoughIfindusingaSELECTstatementtobealittlesimplertocode.Youwillneedtodecidewhichsolutionmakesthemostsenseinyourenvironment.
如果某个数据列里包含许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列里包含的净是些诸如“0/1”或“Y/N”等值,就没有必要为它创建一个索引。 |
|