Professional Documents
Culture Documents
hu tmogatsval
Minden jog fenntartva. A szerz s a kiad a knyv rsa sorn trekedtek arra, hogy a lert tartalom a lehet legpontosabb s napraksz legyen. Ennek ellenre elfordulhatnak hibk, vagy bizonyos informcik elavultt vlhattak. A pldkat s a mdszereket mindenki csak sajt felelssgre alkalmazhatja. Javasoljuk, hogy felhasznls eltt prblja ki s dntse el sajt maga, hogy megfelel-e a cljainak. A knyvben foglalt informcik felhasznlsbl fakad esetleges krokrt sem a szerz, sem a kiad nem vonhat felelssgre. Az oldalakon elfordul mrka- valamint kereskedelmi vdjegyek bejegyzjk tulajdonban llnak.
Kiad: Jedlik Oktatsi Stdi Kft. 1215 Budapest, v u. 8-12. Internet: http://www.jos.hu E-mail: jos@jos.hu Felels kiad: a Jedlik Oktatsi Stdi Kft. gyvezetje
Bevezet
2012 tavaszn, majdnem fl vszzaddal az SQL-nyelv kifejlesztse utn elrkezettnek lttam az idt, hogy rjak egy knyvet a Transact SQL nyelvrl. Hogy mirt pont most? s egyltaln minek, ha a vilg telis-tele van SQL-knyvekkel? Azrt, mert angol nyelv szakirodalom van bven, taln mg napraksz is akad, de magyarz lersokkal tzdelt, a legjabb fejlesztseket is figyelembe vev magyar nyelv knyv nincs a piacon. Emellett j apropt knlt, hogy ha most rok knyvet, elcspem az SQL Serverek j hullmt, az SQL 2012-t, s olyan ultramodern dolgokrl is rhatok, amelyek nlkl ugyan van let, de milyen? No meg a lustasg is vezrelt, hogy ha most ezt megrom, a kvetkez verziig, azaz legalbb hrom vig nem lesz dolgom a knyv frisstsvel. Felsorolvn a motivciimat, akr bele is kezdhetnk a lnyegi rszbe. Minden ilyen knyv ktelezen tartalmaz valamifle trtneti ttekintst. Mivel az SQL-nyelv s a Microsoft SQL Server trtnete elgg regnyes, n sem hagyom ki ezt a lehetsget. Kezdjk taln azzal, hogy ha valaki egy klfldi eladst meghallgat az SQL Serverrl, szreveheti, hogy a beszlk klnsen a rgi motorosok gy ejtik ki az SQL-t, hogy szkel vagy szkvel. No mr most ha valaki tanulta ann az angol bct, vagy ha nem is tanulta, de ismeri az bcs gyermekntt, mg ha eddig el is kerlte esetleg a figyelmt, most biztosan felrmlik eltte, hogy a sz az bizony nem az S, hanem a C bet. Akkor mirl is beszlnek ezek? CQL-rl? Az meg mi? Nos, a CQL az nem ms, mint SEQUEL, avagy Structured English Query Language1, azaz struktrlt angol lekrdezsi nyelv. A 70-es vekben az IBM kutati az SQL-nyelvet nem programozsi nyelvknt hoztk ltre. A nyelv eredeti clcsoportja ugyanis az adatbzis-alkalmazsok felhasznli vagy legalbbis felgyeli voltak, clja pedig nem ms, mint hogy az alkalmazsokbl programozs nlkl, pusztn egy termszetes nyelv hasznlatval okosan el lehessen lltani klnbz halmazokat. A nemes cl igen gyorsan megbukott, mert a felhasznlk kt terleten is gyarlnak bizonyultak: egyfell nem lehet elvrni egy humanoidtl, hogy ismerje az adatbzis pontos szerkezett, amely nlkl a lekrdezs eleve kudarcra van tlve, msfell egy tlagos ember nem kpes kttt szintaxist hasznlva kifejezni magt. Minden SQL-parancs mind a mai napig egy-egy hibtlan angol nyelv mondat ugyan, de csak egyetlen helyes vltozat a lehetsges kismilli kombinci kzl. Teht mind az adatbzis szerkezett, mind a lekrdezsi nyelvet tanulni kell. Ezrt olvasod most ezt a knyvet. A nyelvet gy tkereszteltk SQL-re, amiben persze szerepet jtszott egy j kis szabadalmi per is, mivel a SEQEL rvidtsre benyjtotta ignyt egy brit replgyr is. A szabadalmi csetepatk nem mai keletek, mr eleink is trdig gzoltak bennk.
http://en.wikipedia.org/wiki/SQL
Ltezik egy folyamatosan fejld szabvny magra az SQL-nyelvre, amelyet a nagy tekintly ANSI szabvnyszervezet tart karban. Ez az SQL-nyelvet tbb rszre bontja: Data Definition Language, a tblk s egyb objektumok ltrehozsra, mdostsra s trlsre, teht CREATE, ALTER, DROP Data Query Language, a lekrdeznyelv, vagyis a j reg SELECT Data Manipulation Language, azaz INSERT, UPDATE, DELETE Data Control Language, a jogosultsglltgats nyelve, GRANT, REVOKE, DENY
A piacon szmtalan SQL-alap adatbziskezel van, gyors felsorolskppen csak nhny nv: Oracle, MySQL, DB2, Informix, Sybase s persze a Microsoft SQL Server. Az ANSI SQL-szabvny tkrben azt gondolhatnnk, hogy az imnt felsorolt rendszerek SQL-nyelve azonos. Nos, ez egyltaln nincs gy. A jelensg oka, hogy az ANSI SQL kvetzemmdban dolgozik, a fejldst pedig a piaci szereplk diktljk, de olyan iramban, hogy a szabvnytestlet csak kapkodja a fejt. A legfrissebb szabvny az ANSI SQL 2008, de hol van mr 2008? Emiatt sajnos a szabvnyban megjelen minden j elem mr rg megvalsult az egyes adatbziskezelkben, mgpedig gy, ahogy az egyes gyrtk azt jnak talltk. Ezrt nincs kt egyforma trigger, ezrt lteznek egyedi, eltr JOIN szintaxisok. St, bizonyos alapvet terleteket a szabvny egsz egyszeren nem vesz figyelembe, mintha nem is lteznnek. A triggereket pldul csak 1999-ben legalizltk, de addigra mindegyik gyrtnak mr a sokadik verzij triggermegoldsa ltezett prhuzamosan. Tudtommal nem is vltoztatta meg egyik sem a maga triggerimplementcijt emiatt az aprsg miatt. Ezzel el is jutottunk a Transact SQL-nyelvhez, ami nem ms, mint a szabvnyos ANSI SQL-nyelv kiegsztse mindazzal, amit a Microsoft, illetve korbban a Sybase jnak ltott. Mi? Igen, jl olvastad. A regnyes trtnelem feltrja elttnk, hogy a Microsoft SQL Server nem ms, mint a SyBase SQL Server forkolsa. A Microsoftnak ez a termke is felvsrls tjn kerlt a knlatba. A Microsoft SQL Server legels verzija, a 4.2 megegyezett a SyBase SQL Server 4.2-es verzijval. A Microsoft ugyanis megvsrolta a SyBase forrskdjt, amit a lke SyBase a kvetkez korltozsokkal bocstott a Microsoft rendelkezsre: rendben van, uraim, de nk a sajt pldnyukat csak s kizrlag Windows platformon hasznlhatjk. Ht ez pont elegend volt a Microsoftnak ahhoz, hogy SQL Servervel a semmibe nyomja a SyBase-t, s megszorongassa akr az Oracle-t, akr a DB2-t. (Kitr: Nekem volt szerencsm dolgozni a Microsoft SQL Server 4.21A verzival. Pestiesen szlva netuddmeg. Nem volt benne szinte semmi a maiakhoz kpest! Egy nyomorult nvekv azonost megszerzshez SELECT MAX(*) FROM TBLA lekrdezst kellett rni, amivel az ember persze bebortotta a prhuzamos vgrehajtsnak a lehetsgt is.) Ennyit a dics mltrl, most jjjn a jelen s a jv!
Tartalomjegyzk
1 ISMERKEDS AZ SQL SERVER MANAGEMENT STUDIVAL ........................................................ 10
1.1 1.2 1.3 1.4 1.5 1.6 1.7 KAPCSOLDS SQL SERVERHEZ, ADATBZISHOZ ............................................................................. 10 MIT CSINL A FA? ................................................................................................................... 12 ADATBZIS, TBLK, DIAGRAMOK LTREHOZSA ............................................................................. 12 ADATBZIS SCRIPTEK .................................................................................................................. 16 MIT TUD A QUERY ABLAK? .......................................................................................................... 19 SQL-NEVEZKTAN ...................................................................................................................... 20 TOVBBI HASZNOS BIGYSGOK ................................................................................................... 21
CSOPORTOSTS, GROUP BY ...................................................................................................... 43 A MSODIK WHERE - A HAVING ................................................................................................ 44 RSZSSZEGEK KSZTSE, ROLLUP .............................................................................................. 44 KOCKULAT, CUBE ...................................................................................................................... 46 CSOPORTOSTS EXTRM KOMBINCIKBAN................................................................................... 46
9.1 9.2
ZROLSI RENDSZER, LIVELOCK, DEADLOCK, SP_LOCK ....................................................................... 81 SZEMTOLVASS, OPTIMIZER HINTEK ............................................................................................. 84
10
10.1 10.2 10.3 10.4 10.5 10.6
PROGRAMOZS ........................................................................................................ 86
VLTOZK ................................................................................................................................ 86 CIKLUS, ELGAZS ...................................................................................................................... 87 ESET-LEG (CASE) ....................................................................................................................... 88 TROLT ELJRS ........................................................................................................................ 88 TRIGGER ................................................................................................................................... 97 SKALRIS S TBLAFGGVNYEK ................................................................................................. 100
11
11.1 11.2 11.3
12
12.1
13
13.1 13.2
14
14.1 14.2 14.3
15 16 17 18
SQL AZURE MANAGEMENT PORTL..............................................................................127 SQL AZURE MIGRATION WIZARD .................................................................................131 SQL AZURE ADATBZIS ELRSE KLIENS ALKALMAZSBL ....................................................135 SQL AZURE DATA SYNC .............................................................................................138
1
1.1
Els fejezetnkben vgigegersznk az SQL Server Management Studio felletn s lehetsgein, vgigprblva mindazt, ami fontos, kihagyva azokat az elemeket, amelyek tl sok haszonnal nem kecsegtetnek. Egy SQL-knyvnek tlnyom rszben SQL-parancsokat, scripteket kell tartalmaznia, ezrt az egrtologatst lerendezzk az els fejezetben. A tovbbiakban mr mindent SQL-paranccsal fogunk csinlni. Most azonban mg kell a kattintgats, hiszen mg be sem lptnk az SSMS nven rvidtett legfbb rendszerfelgyeleti eszkzbe, az SQL Server Management Studiba. Tegyk fel, hogy a Kedves Olvask rendelkeznek valamilyen SQL Server 2012 pldnnyal, amiben rendszergazdai jogosultsgot lveznek (klnben a parancsok fele nem mkdne nekik), amire vagy gy tettek szert, hogy k egy vllalati SQL Server felels szakemberei, vagy teleptettek maguknak egy 180 napos ingyenes prbaverzit, esetleg leszedtk s teleptettk az ingyenes SQL Expresst. Miutn mindenki tisztzta magban, melyik SQL Serveren dolgozhat korltlanul, indtsa el az SSMS-t a Start menbl, illetve ha olyan nincs, akkor a Windows 8 arcba kezdje begpelni, hogy SQL, s mris megkapja a tallati listban! (Ilyen trivilis lpseket nem szeretnk rszletesen kifejteni, az az SQLguru-aspirns, aki nem tudja, mi az a Start men, srgsen forduljon szakemberhez!) Els lpsknt kapcsoldjunk egy SQL Serverhez! Az brn az n SSMS-em kapcsolati listja lthat, amin szerepel egy-kt specilis szervernv, amiket hamarosan rviden elmagyarzok. Normlis esetben a Server name mezben mindssze az adott szmtgp neve szerepel. De nlam ez:
Soronknt a kvetkezket ltjuk: Bertam a mezbe egy pontot. Ez mindig az aktulis, helyi SQL Server tpldnyt jelenti, ezzel a helyben teleptett elsdleges (nem nevestett) pldnyhoz lehet kapcsoldni. A pont trkkt akkor szoktam hasznlni, ha fogalmam sincs a Windows szmtgpnevrl. (A ponttal egyenrtk a (local) is, ha valaki tbbet szeret gpelni) A listban a legfels sor egy SQL Server nevestett pldnyhoz kapcsoldik, amelyik a laptopomon lakik. A neve: MARCELL-THINK\SQLEXPRESS. (Ezt egybknt a Visual Studim teleptette fel.) A msodik a Windows Azure-ban tallhat SQL Serverem becses neve. Btran lerhatom ide, mert az Azure szervereket a jogosultsgon fell szigor IP-cm alap hozzfrsi szablyok
10
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA vdik, lehet prblkozni a hekkelssel, ha valakinek gy tetszik. A neve: qmtr3jedvd.database.windows.net A harmadik, furcsa nev valami a Visual Studiban futtatott ASP.NET MVC webalkalmazsom AppData knyvtrbl indul, User kontextusban fut adatbzis, aminek a nevt nem volt trivilis sszevadszni, de gy most r tudok kapcsoldni az SSMS-szel, hogy teljes kr hozzfrst kapjak a Visual Stdio korltozott lehetsgei helyett2.
Az brn nem ltszik, de van mg egy kapcsoldsi lehetsg, ugyanis az SQL Expresszel, vagy ahelyett lehet telepteni a LocalDB nev mg kisebb adatbzist, ami annyira mini, hogy mg szolgltatst sem telept, hanem ha rcsatlakozunk, elindul az sqlserver.exe processz, s ahhoz tudunk kapcsoldni. A LocalDB funkcijban megegyezik a legnagyobb kipts, Enterprise vltozattal, mert az a clja, hogy a fejlesztknek olyan szolgltatskszletet biztostson teleptgets nlkl, amilyen csak a nagy adatkzpontokban van. A LocalDB-hez gy lehet csatlakozni, s mivel ez az informci nem lelhet fel sehol a szakirodalomban (legalbbis 2012. prilis 19-n mg nem, vagy nem talltam meg), ezzel az egy kpernykppel nlklzhetetlenn s felbecslhetetlenn tettem ezt a knyvet:
A trkk teht a kvetkez: az SQL Server neve helyre ezt kell rni: (localdb)\v11.0 Ha bertuk az SQL Server nevt (vagy egy pontot, a helyi SQL Server elrsre), kvetkezik az autentikci. Windowsos krnyezetben j esllyel Windows logint, felhben nagy valsznsggel SQL-logint fogunk hasznlni. Ez utbbi esetben az SQL Server maga kezeli a bejelentkezsi neveket, jelszavakat.
Ezt a mondatot is rgja az id vasfoga. Az SQL Server Data Toolsszal a Visual Studio is teljes kr kpessgeket kap.
11
1.2
Miutn ltrejtt a kapcsolat s belptnk, bal szlen egy Object Explorer nvre hallgat faszerkezetben ltjuk az SQL Servernk vickeit-vackait. Vannak neki adatbzisai, biztonsgi belltsai stb. Minket most kizrlag az adatbzis g rdekel. Amit fontos tudnunk a frl s a helyzetrzkeny menrl, az az, hogy minden szinten szinte minden van. rdemes legalbb egyszer jobb gombbal vgigkattogni az egszen, mert minden objektumnl ms s ms, azon a ponton relevns menpontok bukkannak fel. Hogy csak egyetlen pldt mutassak (a tbbi hzi feladat), egy adatbzison pldul az albbi tekintlyes mennyisg funkci rhet el:
Ezenfell a fa egy SQL-tantmester is egyben, mert brmit csinlunk, vgl is csak SQL-scriptet futtat, amit az SQL Profilerrel elleshetnk tle, s ksbb azzal vagnykodhatunk, hogy egy paranccsal meg tudunk csinlni roppant sszetettnek tn feladatokat.
1.3
Jhet az els rdemi lps, az adatbzis ltrehozsa. A knyvben egy online bank adatbzisnak ltrehozst kvethetjk vgig, ezrt az j adatbzis neve legyen Bank! Mivel most mg egerszs zemmdban vagyunk, a bal oldali fban jobbkattintunk a Databases gon, kivlasztjuk a New Database menpontot, s a felbukkan ablakban megadjuk az adatbzisunk nevt, gy:
12
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Az adatbzist most alaprtelmezett mretben, alaprtelmezett helyen, alaprtelmezett nvekedsi belltsokkal hozzuk ltre. Ha majd egyszer netaln rok egy SQL Admin knyvet is, ott rszletesen kitrek ezekre, vagy tudom javasolni a 40 rs SQL Admin tanfolyamot. Most azonban click ok! Mivel tbb adatbzist nem szndkozunk ltrehozni, itt s most megadom a ltrehozs SQLparancst is, el ne maradjon:
13
Figyeljk meg, hogy mindkt mez esetn kitiltottam a NULL rtkeket! A CityID-nl ez remlem egyrtelm, a Name meznl pedig azrt, mert nvtelen vros nincsen. Ha nem tudjuk egy vros nevt, vletlenl se hozzunk ltre olyan rekordot, ami res nevet tartalmaz! Ha vgeztnk, keressk meg az eszkzsoron a ments ikont (az idsebb nemzedk kedvrt: floppylemez, a fiatalabbak meg keressk a feje tetejre lltott mosogatgpet), katt oda, adjuk a tblnak a Cities nevet, s kszen vagyunk. j tblnk szpen megjelenik a fban bal oldalon, mindenfle frisstgets nlkl. (Ez csak termszetes, nem? Ha majd scriptekkel dolgozunk, egyltaln nem lesz termszetes. Sem a fa, sem az IntelliSense nem fogja automatikusan szrevenni az alkotsainkat. Ezrt van a fban minden elemen, a hierarchia minden szintjn Refresh menpont.) A Cities feladata egybknt az lesz, hogy amikor felvesznk gyfeleket, akkor a vrosnv helyett a vros egyedi azonostjt troljuk a Customers tblban, ezzel eleget tve egy csom normalizlsi szablynak (1, 2, s mg a 3 is). Msodik tblnkat egy msik grafikus szerkesztfellettel, a Database Diagrammal hozzuk ltre, hogy lssuk, hogy bizony kett ilyennk van. Keressk meg az adatbzis alatt a Database Diagrams gat, nyissuk ki, a felbukkan zenetre termszetesen olvass nlkl mondjuk azt, hogy YES, s ezutn mr mkdik a jobbklikk a Database Diagrams gon3. Az albbi brra sszemontroztam a folyamatot, melynek sorn megjelenti a ltez tblinkat (mind az egyet, a Cities tblt) s az Add gomb segtsgvel fel is vesszk azt a diagramra.
A kvncsibbak kedvrt azt krdezte, csinlhat-e tblt a diagramok elmentsre. Nyilvn csinlhat, klnben nem is mkdik ez a funkci.
14
6. bra - a diagramszerkeszt
Msodik tblnkat, a Customerst gy hozzuk ltre, hogy jobbklikkelnk a diagram egy res rszn (konkrtan a semmin, az res felleten), s a felbukkan menbl a New Table menpontot vlasztjuk. Ez a tbladesigner majdnem ugyanaz, mint az elz, de van pr klnbsg. Pldul ez elre bekri az j tbla nevt (legyen Customers). A mezk tulajdonsgt pedig ne alul keressk, hanem jobbra, de csak azutn, hogy F4-gyel elcsalogattuk a Properties ablakot. Ismt egy sszevgott jelenet kvetkezik, ahol pp a CustomerID mezt csinlom meg IDENTITY-stl, PRIMARY KEY-estl:
Ezt kveten gyors egymsutnban ksztsnk egy FirstName s egy LastName mezt, mindkettnek j lesz az nvarchar(50) meztpus, s ne legyenek nullozhatk! Majd jn egy klnlegessg. Megalkotjuk a vevk s a vrosok kztti kapcsolatot, kialaktva a kt tblt sszekt referencilis integritsi szablyt. Ennek az a menete, hogy ksztnk egy CityID nev, INT tpus, nem nullozhat mezt a Customers tblban, majd megfogjuk ennek a sornak a fejrszt, s rvontatjuk az egrrel a Cities tblra, gy:
15
A Citiesen bell akrhol elejthetjk, mert gyis felugrik egy ablak, hogy melyik mezt melyikkel szeretnnk kapcsolatba hozni. Mivel furfangosan azonos mezneveket hasznltunk (ez a javasolt), nem sok dolgunk van a kivlasztssal, csak az Enter tlegelse. Nyomjunk egy mentst (floppy=mosogatgp), adjunk a diagramnak egy bartsgos nevet, ssk az Entert, amg visszabeszl, s ezzel nemcsak a diagramot mentjk el, hanem a tblt is legenerlja kapcsolatostul-mindenestl. Akik mindeddig trelmetlenkedtek, hogy mikor jnnek mr a scriptek, rmmel jelenthetem, hogy most. Ez a kt tbla ahhoz kellett, hogy rdemben kiprblhassuk az adatbzis smjnak scriptfjlba mentst, mert most mr van valamink, st kt valamink, amin ezt a funkcit be lehet mutatni.
1.4
Adatbzis scriptek
Jelenleg egy fejleszti gpen dolgozunk. Vals krnyezetben egy plusz munkafzis szksges ahhoz, hogy a ksz adatbzist eljuttassuk a felhasznlsi helyre. Ehhez tipikusan scriptet hasznlunk, mellyel 100%-os hsggel le tudjuk kpezni az adatbzis szerkezett anlkl, hogy a fejleszti gpen felvett nyamvadt tesztadatainkat is magunkkal cipelnnk, mint azt egy ments-visszallts vagy egy lecsatols-felcsatols tenn. Vigyzat, Script menpontbl kett is van, s az, amelyik odatolakodik a szemnk el, nem az, amelyik ezt a funkcit tudja! A Bank adatbzis loklis menjben tallhat egy tolakod Script Database as menpont (lsd a 2. brt), ami azonban csak s kizrlag a CREATE/ALTER/DROP DATABASE utastst scripteln le, a tblinkat nem. Neknk azonban a Tasks almenben lv Generate SQL Script menpont kell, mert ez mindent visz. Indtsuk el! A megjelen varzsl els lapja szoksosan rdektelen. Next. A msodik lapon azonban mr ltszik, hogy ez egy mindenev script lesz, noha egyelre csak tblink vannak. Ha lennnek egyb 16
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA objektumaink, azokat is egyesvel ki lehetne vlasztani. Most maradjunk a minden kivlasztsnl, Next! A kvetkez lapon vlasszunk ki clllomsnak egy j lekrdezablakot (Save to new query window), Next, Next, Finish. Az eredmny egy csodlatos script, ami nemcsak azt a nulla darab belltst tartalmazza az adatbzison, amit mi kivlasztottunk, hanem a default rtkeket is, teht tkletes lersa jelenlegi adatbzisunknak. Tblstul. Aki nem hiszi, trlje btran a bank adatbzist, majd futtassa le ezt a scriptet, s visszakapja ugyanazt az adatbzist. Kitr: n is le szerettem volna trlni a magamt, de nem lehetett, mert a hibazenet szerint a fik a bnyban dolgoznak, teht van egy rejtett kapcsolatunk a Bank adatbzis fel. Ha SMSS-szel trlnk, a prbeszdpanelen van alul egy kilvsi opci:
Mivel a kapcsolatok megszaktsra sok msik mvelet esetn is szksg lehet, nzzk meg, hogyan tehetjk ezt meg az adatbzis letrlse nlkl! Ha minden lekrdezablakot tlltunk az adatbzisrl, s a fban is kistlunk, becsukjuk, elvileg minden kapcsolatot elengednk. Ha mg mindig makacskodik, ki kell lni azt a valakit, aki potyzik az adatbzisban. Ehhez hasznljuk az SSMS ikonsorrl elindthat Activity Monitort, gy:
17
Persze ehhez hozz kell tenni, hogy a megszaggatott kapcsolatok azonnal visszajnnek, ha csak nem lltjuk t az adatbzist egyfelhasznls zemmdra, amit pont erre talltak ki!
18
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA A script lefutsa utn visszakapott adatbzisbl kt dolog hinyzik: az adatok (szerencsre) s az adatbzis diagram (sajnos, merthogy az is adat).
1.5
Ha mr gy belefutottunk a lekrdezablakba, nzzk meg tzetesen, mit tud. Nyissunk egy j ablakot a scriptnk mell az eszkzsoron tallhat legnagyobb gomb, a New Query megnyomsval! (Tetszleges szm lekrdezablakunk lehet egyszerre nyitva, amelyek mindegyike kln felhasznlnak szmt az SQL Server szmra, gy nem lt bele az sszes tbbi kapcsolat tranzakciiba. Hogy ez licencgyben mit jelent, ne firtassuk, mert fogalmam sincs! ) Ebbe az ablakba rjuk be letnk els (?) SQL-parancst, egy SELECT-et! J egyszer legyen, mindssze azokat a kulcsszavakat hasznljuk fel a SELECT parancsbl, amiket ktelez vagyis semmi mst, mint a SELECT-et! (ltalnos tvhit, hogy a SELECT-tel mindenkppen tblbl kell lekrdeznnk. Ez egyltaln nincs gy. Krdezhetnk konstansokbl, kifejezsekbl, tblartk fggvnyekbl stb.)
SELECT 1
Mit tehetnk ezzel a scripttel? 1. Lefuttathatjuk. (Execute gomb az eszkzsoron vagy F5, vagy a nagyon rgi motorosoknak CTRL+E) Ez a lekrdezs egy egysoros, egyoszlopos tblt ad vissza, melynl a mez s a tbla neve egyarnt res. 2. Lpsenknt futtathatjuk. (Debug gomb vagy ALT-F5) Ennek majd trolt eljrsoknl, fggvnyeknl s triggereknl lesz jelentsge. 3. Ha tl sokig tart a futsa, lellthatjuk a most pp szrke, de futs kzben piros STOP gombbal. 4. Futtats nlkl leellenrizhetjk, hogy helyes-e a szintaxisa. (Kk pipa gomb) 5. Futtats nlkl megnzhetjk, hogy ha lefuttatnnk, az SQL Server milyen vgrehajtsi terv mentn produkln a sorokat. (Felismerhetetlen ikon a kk piptl jobbra vagy CTRL+L, Estimated Execution Plan) Ez utbbit gyakrabban hasznljuk, mint az ember gondoln. Egy igazi SQL-guru llandan kvncsi, mi zajlik a boszorknykonyhban, mert ltalnos esetben mi csak a parancsot adjuk ki, de hogy az SQL Server hogyan lltja el boszorknyos gyessggel az eredmnyhalmazt, az nem rajtunk mlik. Hogy egy rtelmes pldt is nzznk rgtn a vgrehajtsi tervre, krdezzk le a tblinkrl trolt informcit az egybknt ANSI-szabvnyos metaadat-lekrdezsi lehetsggel!
19
Jegyezzk meg, hogy a fa fltt tallhat adatbziskivlaszt NEM a fra van hatssal, hanem a lekrdezablakra! Mindig! s egyben kivtel nlkl! (Hogy akkor mirt nem a lekrdezs felett van? errl az erg mkusokat kellene megkrdezni.) Ennek az rtalmatlan lekrdezsnek pedig ilyen a vgrehajtsi terve:
Ne menjnk most bele rszleteiben, hogy itt mi micsoda, csak csodlkozzunk r a szpsgre.
1.6
SQL-nevezktan
Mieltt elkezdnk eszeveszett tempban tovbbi objektumokat ltrehozni, rviden emlkezznk meg az SQL-nevezktannak hvott tudomnyrl! Ez a tudomnyterlet alapveten azzal a krdssel foglalkozik, annak hatrait feszegeti, hogy milyen neveket adhatunk az SQL-objektumoknak. A tudomny mai llsa szerint brmilyen butasgot kitallhatunk, hvhatunk egy tblt, vagy akr egy mezt rvztr tkrfrgp-nek, pusztn annyi a feladatunk, hogy az ilyen idtlen neveket [ ] zrjelek kz tegyk.
20
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA A nevezktan msik nagy terlete a foglalt szavak krdse. Sajnos brmennyire is tetszik, hogy egy dtummezt gy hvunk, hogy Date, a tudomny llspontja szerint mint nv, ez is ostobasg, mivel az SQL-nyelvben a Date foglalt sz, egy adattpus, meglep mdon a dtum tpus neve. s mit csinlunk a butasgokkal? Szgletes zrjelbe tesszk, s vidman hasznljuk. De vigyzat! Ez a tudomny nem foglalkozik azzal, miknt ll fejre a kliensalkalmazs vagy a weboldal ilyen nevektl, gyhogy vigyzzunk, mit fogadunk el a tantsok kzl! n pldul [Date] nev oszlopot nem csinlnk, de mindenki szabadon azt tesz, amit akar. Egy msik nagy filozfiai krdskr, hogy hogyan tallunk meg egy objektumot az SQL-vilgban. Ha azt mondom, SELECT * FROM CUSTOMERS, ugyan milyen alapon merszeli az SQL Server megtallni ezt a tblt? Erre a krdsre csak akkor tudunk rdemben vlaszolni, ha megtanuljuk, hogy minden SQLobjektumnak valjban ngytag a neve, melyek kzl hrmat el tudunk hagyni, ha a krnyezeti felttelek ezt lehetv teszik. A Customers tbla teljes neve valjban kiszolglnv.adatbzisnv.smanv.objektumnv, azaz MARCELL-THINK\SQLEXPRESS.Bank.dbo.Customers melybl a szervernv elhagyhat, mert pp erre a szerverre csatlakoztam (SQL Servereken tvel lekrdezsek esetn ez nincs gy!), az adatbzisnv elhagyhat, mert ebben az adatbzisban llok pp, s a sma is elhagyhat, mert itt rszletesen nem taglalt okokbl az objektumoknak ltalban dbo a smja (kivve a kivteleket), gy az egyetlen nvdarabka, ami tnyleg szksges, az a hivatkozott objektum, jelen esetben a tbla neve.
1.7
Mieltt vgrvnyesen elmerlnnk a scripttengerben, emlkezznk mg meg felsorolsszeren azokrl a tovbbi eszkzkrl, amelyek egy SQL-admin lett knyelmess teszik, s hbe-hba a fejlesztk is j hasznt veszik! SQL Profiler: az SQL Serverre berkez parancsokat kapja el, s teszi rtelmezhetv, elemezhetv szmunkra. Lass lekrdezsek kiszrstl a deadlockok elemzsn t indexek tuningolsig sok mindenre hasznljuk. Database Engine Tuning Advisor: a Profiler j bartja. A Profiler ltal sszegyjttt terhelsminta alapjn javaslatot tud tenni egy optimlis indexturmix kialaktsra. SQLCMD: ez a parancssori eszkz mindent tud, amit az SSMS, csak az a krds, hogy aki hasznlja, az tudja-e a szksges parancsokat. BCP: a j reg parancssori kipi-kopi eszkz. A knyv rsnak pillanatban ez a legintelligensebb eszkz helyi SQL-adatok felhbe mozgatsra, mert csak ez tudja az IDENTITY mezket helyesen feltlteni (-E kapcsol).
21
A nyelv elemei kzl elsknt az egyes objektumok ltrehozsrt felels DDL-nyelvrszt tekintjk t. Ezt megelzen picit elmerengnk az adatbzistervezs elmletn, az gynevezett norml formkon, valamint a felhasznlhat adattpusokon.
2.1
Amikor ltrehozunk egy adatbzist, szinte kivtel nlkl a valsg egy darabkjt ntjk bitekbe. A mi clunk, hogy ez a lehet legellentmondsmentesebben trtnjen meg. Eskdt ellensgnk a redundancia, mert ha brmit kt pldnyban trolunk, mindig fennll a veszlye annak, hogy csak az egyik pldnyt mdostjuk, ezltal sztzillva az adatok nellentmonds-mentessgt, mert utna ki fogja megmondani, melyik adat az rvnyes? Ahogy a monds tartja: addig, s csak addig tudod, hogy mennyi a pontos id, amg egyetlen rd van. Amint van kett, tbb el nem dntd, mennyi az id! Redundancibl sokfle ltezik. Vannak teljesen lthat, s vannak rejtzkd pldnyok. Mindkt tpust irtjuk. A normalizlsi szablyok lnyege, hogy egyszer mdszerek betartsval kiirtsuk az ellentmonds lehetsgt az adataink kzl. Normalizlsi szablybl van vagy hat, melyek egyre kisebb redundancikra lnek. A gyakorlatban elegend, ha az els hrmat betartjuk, mert akkor mr a tmegkatasztrfa biztosan elkerl minket. A norml formk szabatos lersa sok helyen olvashat, n most itt inkbb a magyarrl magyarra fordtott, teht rthet vltozatot teszem kzz, s mg a sorszmokat is mdostom kiss, gy lesz a hrombl az albbi ngy:
22
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA 1. Az adatbzis nem egy Excel tbla. Ne tgy fel egy lapra mindent! Vlaszd kln az objektumaidat, s pakold ket kln tblkba! Ha kell, tbb tucat vagy akr tbb szz tblba. Ettl nem kell flni. A tblidban szerepl egyedeket azonostsd egy kulcsmezvel, melynl j tlet, ha a kulcs nmagban nem jelent semmit (nem egy szemlyi szm vagy valami), mert ha nem jelent semmit, akkor ksbb nemigen lesz olyan knyszer, hogy megvltoztasd, ja s mellesleg az rtelmetlen kulcsok sokkal kisebbek tudnak lenni (pl. egsz szmok), amelyekkel sokkal knnyebb lesz a tblkat sszekapcsolni, s mg az indexeket sem hizlaljk feleslegesen4. 2. A tblkban trolt egyedek kztt kulcsmezk alapjn teremts kapcsolatot! Mivel kapcsolatonknt egyetlen rtkprod van, ebbl kvetkezen nem az apa mutat az t gyerekre az t kezvel, hanem mindig a gyermekek mutatnak egy kezkkel az apjukra. A gyermek kezt nevezd idegen kulcsnak, a kapcsolatot pedig referencilis integritsnak! 3. Ne trolj olyan adatot a rekordokban, amelyek nem a kulcsmeztl fggnek! Rossz tlet pldul a Customers tblban trolni a vrosnevet s az irnytszmot, mert ebben az esetben az irnytszm a vrostl fgg s vice versa, semmi kzk a kulcshoz5. 4. Ne hasznlj tovbb bonthat sszetett mezket. Ha van egy nv mezd, bontsd fel vezetknvre s keresztnvre, mert klnben sohasem fogod tudni megmondani, hogy Sndor Bla Imrnek melyik (kett?) a keresztneve. (Msrszrl ez is problmkat vet fel. Ha nem lennnek soknev emberek, ez egy j tipp lenne. De vannak. Prof. Dr. Phd. ifj. K Pl.) Miutn ezt a sok okossgot mind bemagoltuk, tovbblphetnk az adattpusok fel.
2.2
Htkznapi adattpusok
Kt rszre bontom az adattpusok taglalst. Ebben a rszben a gyakran hasznlt adattpusokat vesszk sorra, mg egy kln fejezetben a klnleges adattpusokkal foglalkozunk. 2.2.1 Egsz szmok Egsz szmbl ngyfle van az SQL Serverben: TINYINT (8 bit, 0..255 (nem eljeles)) SMALLINT (16 bit, -32768..32767) INT (32 bit, mnusz ktmillird..plusz ktmillird) BIGINT(64 bit mnusz csilli..plusz kvadrilli)
Ezek kzl manapsg mr taln csak a kt nagyot hasznljuk. Tipikus felhasznlsi terletk pldul az azonostkpzs, amihez segtsget ad az IDENTITY() nev fggvny, mellyel kombinlva egy INT csodlatosan nvekv egyedi szmllt kpez. 2.2.2 Pontos szmok Kztes lps a lebegpontos (vagy lebegpontatlan? ) szmok fel a trt szmok trolsra is kpes, de pontos adattpus, a DECIMAL, melynek ANSI-neve NUMERIC, s amelyikbl kt msik,
4
Merthogy az elsdleges kulcs minden egyes indexbe bekerl, mert az indexek erre a kulcsra mutatnak. nem mindegy, hogy 4 bjtot ismtelgetek a 14 indexemben, vagy 88 bjtot. 5 Itt jegyzem meg, hogy adatmegtartsi okokbl el szoktuk kvetni ezt a hibt, mert nem mindegy, hogy egy fs szmla rekordba belemsolom a vrost, s emiatt az ott soha tbb nem vltozik meg, hiba varilnak a Vros tbln, vagy hirtelen visszamenleg megvltozik. A redundancinak is lehet gyakorlati haszna!
23
ADATKEZELS OTTHON S A FELHBEN pnzgyi tpus is szrmazik, a MONEY s a SMALLMONEY. Ezekben az a kzs, hogy ha mondjuk ngy tizedesjegyig pontosak, akkor azt az letk rn is tartjk, s ha valamilyen matematikai mvelettel kireplnnk ebbl, aritmetikai hibval elszllnak. Ez kell ahhoz, hogy kerektsi hibk nlkl megsszuk a pnzgyeket. Egy DECIMAL mez a teljes szmsor s a tizedesjegyek darabszmval adhat meg, pldul gy: DECIMAL(9,2). Ez egy maximum 9 jegy szmot takar, melynek maximum kt tizedesjegye lehet de ha valban van kt tizedesjegye, mr csak 7 szmjegye lehet az egszrszben. 2.2.3 Lebegpontos szmok A FLOAT s a REAL tpusok valk igazi matematikai mveletek vgzsre. A FLOAT a nagy testvr, a REAL viszont feleannyi bjtot hasznl. A szmtartomnyok mindkettnl irdatlanok, lsd Books Online. Bels trolsuk alap plusz hatvnykitev stlus, kettes szmrendszerben brzoldnak, ebbl kvetkezen pont a tizedestrtekkel bajban vannak, mert a 0.1 csak vgtelen kettedestrt alakban trolhat kettes szmrendszerben6. Az albbi plda jl mutatja, mit nem tud a FLOAT, mert bizony 10 x 0.1 az csak 0.99999999999999999999999999999999999999999:
DECLARE @I FLOAT=0 WHILE @I<>1 BEGIN SET @I=@I+.1 PRINT 'Vgtelen ciklus? :-O' END
Ebben az a fura, hogy ha kiratom a ciklusban a@I rtkt, akkor ott azt ltom, hogy 1. Ezek szerint a kirshoz kerekt de belsleg biztosan nem. Mondjuk ki, hagyomnyos alkalmazsok esetn a kettes szmrendszerben trolt lebegpontos szmok letveszlyt jelentenek. (Blogger komment: ki az szerencstlen, aki gy hasonlt ssze lebegpontos szmokat? Ht n, a plda kedvrt! A helyes megolds az lenne, hogy tudvn a kerektsi mizrit addig megyek a ciklussal, amg a vltozm s a clrtk klnbsge egy bizonyos hatr al esik, pldul WHILE 1-@I < 0.0001) 2.2.4 Szveges tpusok Szveges tpusbl van egy pr. Megklnbztethetjk ket a trols mdja szerint (fix vagy vltoz hosszsg) vagy a karakterkszletk szerint (hagyomnyos vagy unicode). De akrhogy is, mindegyik vltozat stpusa a CHAR(x), mely x bjton trolja a karaktereket, ha esik, ha f. Ha nem tesznk bele x darab karaktert, kiegszti szkzkkel, vele nem lehet kibabrlni. viszont ezltal kibabrl velnk, mert beletesznk a mezbe egy rtket, s egy msikat, a szkzkkel feltltttet kapjuk vissza. Az albbi pldt ppgy rdemes beptygni s kiprblni, mint az elz ciklusosat. rdekes!
Akit rdekel a mirt, ht azrt, mert a tzes szmrendszer prmtnyezi a 2 s az 5, ezek kzl az simn lerhat kettes szmrendszerben, m az 1/5 csak vgtelen kettedestrttel, a kett szorzata, a 0.1 szintn nem, teht pont a szoksos tizedek, szzadok nem.
24
Most nzzk meg, mennyi lehet az x rtke ezeknl az adattpusoknl! Ehhez rintlegesen meg kell ismerkednnk az SQL Server adattrolsval. 2.2.4.1 Lapok Az SQL Server minden adatot gynevezett lapokon (page) trol, ami egyben az adatmozgats, ments alapegysge is. Minden lap mrete 8 kilobjt, se tbb, se kevesebb. Mivel ltalban minden adat a rekordok belsejben troldik, ez azt is jelenti, hogy egy rekord nem lehet nagyobb 8 kilobjtnl, st, egyetlen mez sem lehet nagyobb ennl, kivve, ha ki van vve - a rekordbl. Teht a VARCHAR(x) tpusnl x 1 s 8000, NVARCHAR(x) esetn 1 s 4000 kz kell hogy essen ahhoz, hogy befrjen a rekordba. Ha ennl nagyobb lenne az adat, hasznlhatjuk a VARCHAR(MAX) NVARCHAR(MAX)
tpusokat, melyek ha tlnylnak, kikltznek a 8k-s laprl. Egyetlen valdi htrnya a (MAX)-nak, hogy az ilyen mezket nem lehet indexelni mivel kikltztek a rekordbl, a laprl, mindenbl. 2.2.5 Dtum- s idtpusok Az SQL Server Gergely-naptr tmogatsa fenomenlis. Itt s most mindenkinek megtiltom, hogy sajt maga prblja kiszmolni a jv vet, a nyolc munkanapot vagy brmi ms dtumszersget, mert az elszlls garantlt, csak ki kell vrni!7 Erre megvannak a beptett dtumtpusok s dtumfggvnyek! A dtum trolsa nagyon sokat fejldtt az SQL Server nhny korbbi verzijban. A kezdeti egyszer DATETIME helyett jtt a DATETIME2 s a DATETIMEOFFSET, melyek egyre nagyobb pontossgot, illetve ez utbbi rvn idznakezelst is megvalstottak. Ma, amikor elrhet kzelsgbe kerltek a felhk, s brmikor gy alakulhat, hogy egy adatbzisunk nhny idznval odbbkltzik, szerintem nem rdemes ms tpussal foglalkozni, mint a DATETIMEOFFSET-tel. A tbbi a mlt. Ltni fogjuk ksbb, hogy az idznarsz nem sok vizet zavar, viszont korrektt teszi a dtumokkal val jtszadozst.
J, hogy n hogy ltom a jvt! Amikor ezeket a sorokat rtam, 2012. februr 26-a volt, pp utaztam Redmondba a szoksos ves MVP Summitra. A replgpen kalapltam ssze ezt a fejezetet. s hrom napra r, februr 29-n a Windows Azure mindenestl lellt, mert a szkvet rosszul kezelte az egyik algoritmusuk. Kzzel dtumoztak. Ugye?
25
ADATKEZELS OTTHON S A FELHBEN 2.2.6 Binris tpusok Binris adatmezben troljuk a dolgozk fnykpt, a PDF-dokumentumokat, a kottkat s a ZIPfjlokat. A Microsoft Research ksztett egy tanulmnyt8, melyben kimutatjk, hogy nem is olyan buta dolog fjlokat trolni az SQL adatbzisokban. 1 MB-nl kisebb fjlok esetn az SQL Server kenterbe veri az NTFS-t. A dolgozk foti tipikusan ilyen, picike kpfjlok. SQL Serverbe velk! Itt kt adattpus kzl vlaszthatunk, BINARY s VARBINARY, ers preferencia a var-os vltozaton, s ennek a mrete is lehet (MAX). 2.2.7 Logikai tpus Logikai tpusknt a BIT jutott neknk, ez van, de ez is elg. A BIT egy biten troldik, persze ha egy rekordban csak egyetlen BIT tpus meznk van, akkor nem, mert egyedi bitek trolst sem a memria, sem a merevlemez nem tudja. Teht ilyenkor egy bjtot foglal. De ha lenne esetleg mg egy bitnk, az is elfrne ezen a bjton, s mg tovbbi hat. Hny rtke lehet egy bitnek? Ugye, hogy kett? Nulla vagy egy, igaz vagy hamis, frfi vagy n. Kivve az SQL Server bitjeit, mert azok hromllapotak, ugyanis ez az adattpus is lehetv teszi res rtk, NULL trolst! 2.2.8 Globally Unique Identifier Ha valaki olyan online bankot kszt, mint amilyen a mink is lesz, hamar szembeslni fog azzal a knyelmetlen dologgal, hogy a weblapon megjelentett rekordokat valahogyan azonostani kell, de ezzel gyelni kell, mert a weblapba gyazott azonostkat brki megszerezheti, ha mskpp nem, az oldal forrskdjbl. Ha a weblapon a csodlatosan automatikusan nvekv INT tpus egyedi kulcsot hasznljuk azonostknt, akkor sajnos azt kockztatjuk, hogy idita hekkerek megprblnak ms rekordokhoz hozzfrni, mint amihez joguk van, mert simn kitalljk ms felhasznlk azonostit (hisz egyesvel nvekv szmokrl van sz), s gy jrnak, mint 2011-ben a Citibank. Mr vagy 200-300 ezer bankszmla sszes adatt olvastk el gyes hekkerek az URL tirklsval, mire a Citi szlelte (?) a problmt, s beavatkozott9. Kell lennie egy msik tnak, egy kitallhatatlan, egyedi azonostnak. Van is! Az adattpust gy hvjk, UNIQUEIDENTIFIER, s GUID tpus rtkeket trolhatunk benne, amit adott esetben elsdleges kulccs is tehetnk. j s j GUID-okat a NEWID() fggvnnyel krhetnk magunknak.
2.3
Mai adsunkban azt krdezzk az itt megjelent jtkosoktl, hogy vajon az egr azonos-e az gerfval vagy Eger vrosval. A vlaszok prtatlan elbrlsra, kedves nzink, egy SQL Servert hvunk segtsgl. Az els krds teht gy hangzik: az egr egyenl-e gerrel? ra indul!
8 9
26
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Alapbelltsok szerint az egr nem ger, megnyugodhatunk. (Ha az egyenlsg igaz, a fenti lekrdezs kirja, hogy igaz. Ellenkez esetben res halmazt kapunk.) s mi a helyzet Eger s eGeR esetn?
27
Ezen fell a jtk a betkkel kategriba tartozik a sok-sok stringfggvny, melyekkel keresni, vgni, balrl-jobbrl lecsapni, egyszval mindent lehet, amire gy nagy vonalakban szmt minden programoz lelklet polgrtrsunk. Javaslom a helpben feltni a String functiuons fejezetet.
2.4
A Gergely-naptr az, ami. Mr egyszer korbban megtiltottam a sajt kszts dtumgrcslst, amibe csakis belebukhat az ember. Viccesen hangzik, de ez is megtrtnt eset: Kldj virgot Szknap nev ismerseidnek! Ez ellen vd, ha nem mi magunk szszmtlnk a dtumokkal, hanem rbzzuk Gergelyre, a naptrra. Els feladatknt szmolja ki mindenki, hny ves. Intuitv megkzelts (nem vals szlinappal, fele ilyen ids sem vagyok):
SELECT GETDATE()-'1940.01.01'
Mert ugye a matek az matek, a kivonsnak mkdnie kell. Vgl is kapunk valamilyen eredmnyt, panaszra nem lehet okunk, br hogy mi ez az eredmny, a j g sem tudja:
De hogy nem letkor, az bizonyos. Leszrhetjk a kvetkeztetst, hogy dtumokat nem gy kell egymsbl kivonni. Hanem akkor hogyan? Ht dtumfggvnyekkel! Van ugyanis egy direkt dtumkivonsra kifejlesztett fggvny az SQL Serverben, a DATEDIFF(), ami mg azt is kezeli, hogy milyen mrtkegysgben krjk a klnbsget. vben? Napban? Msodpercben? A fenti feladat helyes megoldsa:
28
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA megfelel fggvnyt (DATEADD()) hasznlnm, mert abban tisztn olvashat, hogy nyolc mit akarunk hozzadni. vet? Napot? Hnapot?
SELECT EOMONTH(GETDATE())+1
2.5
Az a mocsok NULL
Adattpus-krbejr fejezetnkben nem mehetnk el sz nlkl az res rtkek, a NULL mellett, amely annyi kezdnek keserti meg az lett. Nem tallja meg ket a keressekben, nem lehet tudni rla, hogy valdi NULL vagy generlt, s mg sorolhatnnk. Ezek miatt a problmk miatt is javasolt a nullozhat mezk szmt a minimumra szortani. Msrszt persze az is igaz, ha van egy ktelezen kitltend mez, amibe nincs mit rni, a felhasznlk hlyesgeket fognak oda bevinni, knyszersgbl. Mert dolgozni kell. Az az adat, ami csak nha van, az nem az objektum sajt tulajdonsga, az egy gyermekrekord inkbb. Altblnl normlis viselkeds, hogy egy gyermekrekord vagy van, vagy nincs. De ha mr vannak NULL-jaink, nzzk meg, hogyan bnjunk el velk! Alaphelyzetben, ha nem lltgatunk semmit, hanem maradunk az ANSI-szabvnyos alapbelltsnl10, igaz lesz a kvetkez szably:
A teljessg kedvrt jegyezzk meg, hogy ki lehet lpni az ANSI vilgbl a SET ANSI_NULLS OFF paranccsal, s akkor NULL=NULL! A tovbbi lersban arra tmaszkodunk, hogy nem vagyunk mi ilyen fejlettek, nem kapcsolunk semmit sehova. Ami meg is felel a gyakorlatban kvetett cselekvsi sornak.
29
2.6
CREATE TABLE
Azt hiszem, eleget tudunk ahhoz, hogy el tudjuk kszteni a tbbi tblt, amire bankunknak szksge van. Elszr is kell egy Accounts tbla, ami a Kedves gyfl bankszmljt reprezentlja. Aztn szksgnk lesz egy Transactions tblra, ami a bankszmlamveleteket gyjtgeti. Mi kell teht egy bankszmlatblba? Egyedi azonost, ami nem a bankszmlaszm, hanem csak egy sima INT. Nem lehet NULL, de legyen szves automatikusan nvekedni, s kulcsmezknt viselkedni! gyflkd, ami a Customers tblra mutat. Ez sem lehet res, olyan nincs, hogy egy bankszmla senkihez sem tartozik. Bankszmlaszm, ami valjban egy szveg, nem maradhat resen, viszont tutira sohasem lesz benne kezetes karakter. Egyenleg - az pont nem, mert azt a tranzakcik sszestsbl nyerjk. Az lland, minden egyenleglekrdezsnl lefut brutlis kiszmtgatst ksbb korrigljuk. Ltrehozs dtuma ezt a mezt automatikusan fogjuk tltgetni, naplzsi clbl, s okosan olyan dtumformtumot vlasztunk, ami idznahelyes. Egy krikszkraksz kd, ami a szmlt gy azonostja, hogy btran kitehessk az azonostt a webre. Taln mondanom sem kell, hogy ez sem lehet res. Ja, s a kutya sem akar a GUIDokkal egyesvel veszdni, minden rekordban jelenjen meg magtl egy j GUID!
Transact SQL-l:
CREATE TABLE Accounts( AccontID INT PRIMARY KEY IDENTITY NOT NULL, CustomerID INT NOT NULL FOREIGN KEY REFERENCES Customers(CustomerID), AccountNumber VARCHAR(88) NOT NULL, CreationDate DATETIMEOFFSET NOT NULL DEFAULT GETUTCDATE(), URLCode UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID()
30
)
Ha lenne mr gyfelnk, fel is vihetnnk egy bankszmlt. Ha lenne mr vrosunk, fel is vihetnnk egy gyfelet. A referencilis integrits szpsgei ! j vros:
Vagny! Jhet a Transactions tbla. Mi kell bele? Egyedi azonost, nem lehet NULL, de legyen szves automatikusan nvekedni, s kulcsmezknt viselkedni! Szmlaszm kapcsolatmez, ami az Accounts tblra mutat. Ez sem lehet res, olyan nincs, hogy egy tranzakci semelyik bankszmlhoz sem tartozik. A tranzakci msik rsztvevjnek neve. Akitl pnzt kaptunk vagy akinek adtunk. Nem lehet res, de bven lehet benne kezetes karakter. Az Omnbl kapott pnzt tovbbutaljuk Hongkongba. Mennyisg, ami megmutatja, hogy mekkora sszeg mozgott. Lehet negatv szm is, trt szm is, de az nem lenne baj, ha a 0.1 az nem 0.099999999999 lenne. Pnznem. Ebbe a mezbe a pnznem kdjt kell berni, pldul HUF, EUR stb. Ktelez mez ez is. A pnznem mindig hrom karakteres, akrmi trtnjk is. Ltrehozs dtuma ezt a mezt automatikusan fogjuk tltgetni, naplzsi clbl, s okosan olyan dtumformtumot vlasztunk, ami idznahelyes. Egy krikszkraksz kd, ami a tranzakcit azonostja, hogy btran kitehessk az azonostt a webre.
CREATE TABLE Transactions( TransactionID INT PRIMARY KEY IDENTITY(1,1) NOT NULL, AccountID INT NOT NULL FOREIGN KEY(AccountID) REFERENCES dbo.Accounts (AccountID), Partner NVARCHAR(88) NOT NULL, Amount MONEY NOT NULL, Currency CHAR(3) NOT NULL, CreationDate DATETIMEOFFSET(7) NOT NULL DEFAULT (getutcdate()),
31
INSERT Cities VALUES('Gdll') INSERT Customers VALUES('Ben', 'K', 2) INSERT Customers VALUES('Damon', 'Hill', 2) INSERT Accounts(CustomerID, AccountNumber) VALUES(2, '987654364353453') INSERT Transactions(AccountID, Partner, Amount, Currency) VALUES (1, 'Lehman Brothers', 100000000, 'USD'), (1, 'Enron', 2370000000, 'EUR'), (1, 'Postabank', 888888, 'HUF'), (2, 'Lehman Brothers', -100000000, 'USD'), (1, 'Fuggers International', 8768700000, 'USD'), (1, 'Uncle Sam', 4, 'USD')
2.7
IntelliSense
Ha most jl megnzzk a bal oldali fban, miket alkottunk, nem ltszanak. Mivel nem az SSMS-szel csinltuk a tblkat, nem is vette ket szre. Egy Refresh a Tables gon majdnem mindent megold, azonban a lekrdezablakban minden j objektumunk nevt pirossal alhzva ltjuk. A msik szerepl, aki nem vette szre, hogy j objektumokat hoztunk ltre, az az IntelliSense. Rajta pedig egy CTRL+SHIFT+R segt.
2.8
Szmtott mezk
Vannak olyan mezk, melyeknek nem mi adunk rtket, hanem az SQL Server. Lttunk mr ilyet, az IDENTITY j plda erre. Egy msik lehetsg, ha a tbla egyik sorban szerepeltetnk egy szmtott mezt. Olyan rtkekre gondolok, amiket nagyon gyakran kell lekrdezni, viszont nem nll rtkek, pldul mint az fs r. Tiszta redundancia, az igaz, de a redundns rtk karbantartsa az SQL Server rszrl biztostott. Az fa taln nem a legjobb plda, mert flvenknt vltozik, akkor legyen egy bankkrtyajutalk, amit fixen 3%-nak vesznk. gy kszthetnk egy szmtott mezt a Transactions tblba:
32
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA ez a szmtott mez troldjon is, vagyis mg csak kiszmolnia se kelljen az SQL Servernek, hanem az adat azonnal rendelkezsre lljon a lekrdezsek szmra.
2.9
tnevezsek
Egy rvid kitr erejig emlkezznk meg az tnevezsekrl! Egy fejleszts sorn szmtalan esetben elfordulhat, hogy egy mezt vagy egy tblt t kell nevezni. Erre mindenki mondhatja, hogy nem j tlet, mert az tnevezett tbla kiesik a r hivatkoz trolt eljrsok s nzetek all, s ez igaz is. Ettl mg az tnevezs ignye fennll, ebbl nem engedek. Erre a feladatra az sp_rename trolt eljrst hasznljuk, merthogy az ANSI SQL-ben nincs erre a clra semmifle parancs. Egy tbla tnevezse gy nz ki:
33
Az SQL-nyelv legfontosabb rsze a lekrdeznyelv. Minden mst eljtknak tekinthetnk, amely csupn ahhoz kell, hogy legyen mit lekrdeznnk. Ennek a rsznyelvnek az univerzlis kulcsszava a SELECT, amelyre az SQL Server harap, s ami ez utn kvetkezik, azt megprblja lekrdezsknt rtelmezni.
3.1
A legegyszerbb SELECT-utasts, amit mindenki ismer, mg azok is, akik soha letkben nem lttak adatbziskezelt, a
34
Mg egy fontos dolgot kell tudnunk a csillagrl: fedindex-killer. Ltezik egy olyan fogalom az SQL Serverben, hogy fed index. Ez azt az esetet jelenti, amikor egy lekrdezs minden mezjt lefedi egy index tartalma, teht nem kell lemenni a tblhoz az adatokrt, minden megtallhat a tblnl jval kisebb s jval kevsb macerlt indexben. Nos, a csillag eleve lehetetlenn teszi, hogy az SQL Server ezt a fantasztikus gyorsttrkkt alkalmazza.
3.2
A csillag helyn nemcsak meznevek llhatnak a felsorolsban, hanem kifejezsek is. Egy kifejezs lehet egy sima konstans, egy matematikai kifejezs, egy fggvnnyel megdolgozott adat vagy akr egy komplett (begyazott) SELECT utasts. Az albbi pldn az els mez egy konstans, a msodik egy fggvny, a harmadik egy matematikai kifejezs, a negyedik egy begyazott SELECT (amit mindig zrjelek kz kell rni, errl ismeri fel a fordt a begyazst):
Hopp, nem maradt le valami? Egyik meznknek sincs neve! Ezen knnyen segthetnk a mez ALIASok bevezetsvel. Minden mezt tetszlegesen t lehet nevezni rptben, a tblkbl rkezket is. A lekrdezsnk szptsnek kvetkez lpse a keresztel. Minden meznek nevet adunk:
A csillag egybknt maga is csak egy mez a mezlistban. Sokan meglepdnek, ha a csillag utn vesszvel felsorolva tovbbi dolgokat krdeznk le, pedig ez tisztn lehetsges.
ADATKEZELS OTTHON S A FELHBEN bank gyfelei kztt. Vletlenszeren szeretnnk kivlasztani a nyerteseket. Erre (sok egyb ms lehetsges megolds mellett) ez a mdszer alkalmas, ahol a csillag mell plusz mezknt magt Fortuna istenasszonyt idztk meg:
3.3
Kvetkez kulcsszavunk a FROM. Sok-sok oldallal korbban mr lttuk, hogy a FROM nem ktelez kulcsszava a SELECT-utastsnak. Lekrdezhetnk a kibertrbl is adatokat (pl. konstansok, fggvnyek, vltozk). Normlis lekrdezsek esetn azonban szinte biztos, hogy van egy FROM kulcsszavunk, ami mgtt tbla, illetve tblk llhatnak. (A tblt tgan kell rtelmeznnk, mert nemcsak fizikai, ltez tblink lehetnek, hanem tblatpus vltozink, valamint tblartket visszaad fggvnyeink, begyazott lekrdezseink is.) Ha tblt szltunk meg, mindig gondoljunk arra, hogy a tblk neve ngytag, s adott esetben ezt ki is kell rni (pldul elosztott lekrdezsek esetn). A tblkra is vonatkozik az AS-os tnevezs, aminek nagy hasznt fogjuk venni tbbtbls lekrdezseknl, mert nemcsak rengeteg gpelstl kml meg minket, de egyes esetekben az egyrtelmsg meg is kvnja, hogy tblkat rptben tnevezznk (pl. nhivatkoz JOIN). A tbbtbls lekrdezsekre kln fejezetben trnk vissza. gy krdeznk le fggvnybl:
36
3.4
Kvetkez ldozatunk a szrsekrt felels WHERE kulcssz. Ez olyannyira fontos, hogy azt mondanm, az a SELECT, amelyikben nincs WHERE felttel, nem rdemli meg, hogy lefuttassuk. Ha valaki tolvassa az ANSI SQL kritikit, az egyik tbbek kztt az, hogy tl knny vele sokmilli sort lekrdezni, tl knny vletlenl az sszes sort kitrlni vagy mdostani, lvn hogy a WHERE nem ktelez rsze a lekrdezsnek. Ha teljestmnytuningolsrl beszlnk, nem szabad figyelmen kvl hagyni, hogy a legnagyobb lehetsg mindig az, ha a kliensalkalmazsok nem krnek le egymilli sort feleslegesen, hogy abbl kliensoldalon vlasszk ki azt az tt, amit megjelentenek a kpernyn. Sajnos mg mind a mai napig szmtalan ilyen buta alkalmazs ltezik, st, j pnzrt ruljk ezeket a piacon. Mi ne legynk ennyire bnk, vizsgljuk meg, hogyan lehet a szmunkra szksges sorokat lekrdezni! A legegyszerbb eset, amikor egy mezrtkre keresnk, pldul
WHERE Mezo=42
Tl azon, hogy a 42 a vlasz a mindenre, krds, hogy vajon egy ilyen lekrdezs hny sort adna vissza abbl a tblbl, amelyikben a Mezo nev mez szerepel? Sajnos erre nem az a vlasz, hogy egyet. Ez ugyanis attl fgg, mi ez a mez? Ha az egyedi kulcs, akkor egyet. Ha a npessg letkora, akkor taln a sorok 10%-t. Ha ez a negyvenkettesek tblja, akkor pedig az sszes sort. Termszetesen van egyenltlensgvizsglat (<, >, >=, <=) is, meg nemegyenl (<>), meg vannak logikai kifejezsek (AND, OR, NOT), de ezek mindenkinek a knykn jnnek ki, ht menjnk is tovbb a kevsb htkznapi szrsek fel! 3.4.1 BETWEEN A BETWEEN egy als s egy fels rtkhatr kz es elemeket fogja meg. A BETWEEN 8 AND 9 rtelemszeren a 8 s 9 kz es szmokat adja vissza, belertve a 8-at s a 9-et is. Nem is ez a lnyeg, hanem a mvelet univerzalitsa. A BETWEEN 2001.01.01 AND 2013.11.11 pontosan jl mkdik dtummezk esetn, megsprolva ezzel egy csom dtummatematikzst. Mi tbb, szveges adatokon is mkdik! Vajon az albbi lekrdezs visszaadja-e Gipsz Jakabot?
37
ADATKEZELS OTTHON S A FELHBEN 3.4.2 LIKE Ha mr a szveges mezknl tartottunk, vgezznk el egy-kt szveges keresst! A LIKE opertor lehetv teszi, hogy tartalomtredkekre keressnk. (Ez nem keverend ssze a szabadszveges, magyarul freetext lekrdezsekkel, mert az teljesen mskpp mkdik!) gy kereshet meg az sszes M-betvel kezdd vezetknev gyfelnk:
SELECT * FROM Customers WHERE Lastname IN (SELECT DISTINCT Lastname FROM Customers WHERE FirstName LIKE 'Jakab')
Ez a lekrdezs sszeszedi az sszes vevt, akinek a vezetkneve megegyezik msik olyan vevk vezetknevvel, akik Jakabok.
3.5
TOP
A TOP szcskra mg trjnk vissza a teljessg kedvrt! Nemcsak a legels x darab, hanem a legels x szzalknyi sort is lekrdezhetjk vele a kvetkez mdon:
38
SELECT TOP (SELECT COUNT(*) FROM Customers WHERE FirstName LIKE 'Jakab') PERCENT * FROM Customers
Ez ugyan elg gyefogyott lekrdezs, mert annyi szzalknyi sort krnk, ahny darab Jakabunk van, de legalbb ltjuk, hogy az rtelmetlen lekrdezsek rsnak csak a fantzink szab hatrt.
3.6
DISTINCT
Az imnt mr hasznltuk, rjuk teht le, mire is val. A DISTINCT kulcssz segtsgvel kidoblhatjuk az azonos sorokat, egyetlen sort megtartva kzlk. A mvelet a teljes sorra vonatkozik, azt figyeli, ezrt rdemes a mezk szmt minimalizlni a lekrdezsben, vagy legalbb az egyedi kulcsot kihagyni, mert ha a kulcsmez belekeveredik, rtelemszeren minden sor klnbz lesz, a DISTINCT pedig nem csinl semmit. Egy oldallal korbban lthattunk egy gynyr pldt a klnbz vezetknevek kigyjtsre.
3.7
ORDER BY
A sorba rendezs nagy tudomny. Ennek az az oka, hogy - a vltoz hosszsg szveges mezk miatt - a rekordoknak nincs elre elrendelt fizikai sorrendjk, ezrt ha valaki ORDER BY nlkl futtat le egy lekrdezst, ne csodlkozzon, hogy a kvetkez adatmdosts utn esetleg ms sorrendben kapja vissza a rekordokat, mint annakeltte. Az ORDER BY maga a megolds, az letbiztosts, hogy biztosak lehessnk abban, hogy amit lekrdeznk, az mindig adott sorrendben rkezik. Ami egybknt lehet nvekv s cskken is. Ha valaki le szeretn vlogatni az t legbecsesebb gyfelt, akkor nyilvn Amount szerint cskken sorrendben kell krnie a listt, hogy a tetejn legyenek a nagyobb rtkek. A sorba rendezs irnyt az ORDER BY Mez utn biggyesztett ASC, DESC kulcsszavakkal mdosthatjuk kvnalmainknak megfelelen.
SELECT TOP 5 * FROM Transactions ORDER BY Amount DESC, CreationDate ASC, Partner DESC
Ezenfell az ORDER BY arra is kpes, hogy a sorba rendezsi oszlopokat pozci alapjn adjuk meg, valahogy gy:
39
SQL Injection
SQL Server esetn az albbi hekkelsi lehetsg knlkozik sok-sok alkalmazsnl: ha az alkalmazsok olyan butn vannak megrva (sok esetben gy van), hogy gondolkods nlkl beveszik az adatot a kliensprogrambl, s belehelyettestik egy SQL-lekrdezsbe, igen furcsa parancsok szlethetnek. Kpzeljk magunk el az albbi (ostoba ennek ellenre mgis gyakori) bejelentkez-rutint, mely mondjuk egy PHP-alkalmazsban cscsl, s minden bejelentkezskor lefut:
"SELECT * FROM Users WHERE Username='" + $UName +"'" AND Password=" + $Pwd +"'"
Ez gy mkdik, hogy a bejelentkezskor a paramterek behelyettestsvel sszell a lefuttatand SQL-parancs, bekldjk az SQL Servernek, s ha megfelel nevet s jelszt adunk meg, van eredmnyhalmaz (j esllyel egy sort kapunk vissza), ha viszont brmelyik paramter, akr a nv, akr a jelsz rossz, res halmaz az eredmny. Erre ptve a programoz kszthet egy elgazst, hogy vagy beenged, vagy nem enged be az alkalmazsba. Hibtlan, ugye? No, akkor adjuk be nekik a kvetkez felhasznlnevet: Jakab (Jakab s egy aposztrf). Ezzel egszen biztosan megbortjuk a kdot, mert innentl az aposztrfok szma pratlan, hiszen behoztunk egy plusz feleslegeset a kpbe. Egszen pontosan ez lesz a lefuttatand kd a behelyettestsek elvgzse utn:
40
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Innen mr egyenes t vezet tetszleges parancsok lefuttatshoz. Ha a bejelentkez szemlyt gy hvjk, hogy Jakab SHUTDOWN --, akkor szegny sosem tud bejelentkezni, mert az SQL Server az neve lttn mindig lell. Ha pedig valakit gy hvnak, hogy JakabDROP TABLE Students, nos, akkor behvjk a szlt elbeszlgetsre az iskolba.
Ha egy aut rendszma netn XYZ-123 DROP TABLE Cars--, akkor bizony a belgy felktheti a gatyjt.
Mieltt az ORDER BY hekkerkpessgeit elemeznnk, mg rjuk le, mi lehet a vdekezs mdja az SQL Injection ellen. Soha ne csinljunk a fentihez hasonl stringkolbszolst. Pont. Rszletesebben: soha ne csinljunk olyat, hogy egy paramter nem is paramter, csak egy darabka string, amit befznk a parancsba! Hiba knyelmes, ne csinljunk ilyet! Helyette hasznljunk valami normlis
41
ADATKEZELS OTTHON S A FELHBEN paramterbehelyettestsi mdszert, mondjuk a .net megfelel objektumait, vagy hvjunk meg trolt eljrst a bejelentkeztetshez!
4.1
Sorok letapogatsa
A tetszleges parancs tvezet minket a tetszleges adat lekrdezse fel. Nincs olyan, hogy kicsi SQL Injection. Ha a rs megvan, azon keresztl brmit ki lehet hzni. Az els lps persze a piszklhat tbla szerkezetnek lekrdezse, hogy tudjuk, mi is hullott az lnkbe. Nos, az ORDER BY picit segt a tbla szerkezetnek feldertsben. Az albbi mdszerrel egy tmad ki tudja tapogatni a visszaadott mezk szmt. Ber hasra egy ORDER BY 60 sorba rendezst, ami elszll, ha nincs 60 oszlopunk. 60-tl egyesvel cskkentgetve vgl el lehet jutni addig a szmig, amikor mr a lekrdezs rendben lefut na pont annyi meznk van! Nem clom az SQL Injection rszletes taglalsa, innen nem megynk tovbb. Az SQL Injection nagyon szp, s egyben nagyon bonyolult tudomny. Nagyon szp eredmnyeket lehet vele elrni, gondoljunk itt sok szeretettel a sitten l Albert Gonzalezre11, aki 300 milli hitelkrtyaadatot lopott el (egymaga!) SQL Injection segtsgvel! Az imnti iskolaplda arra alkalmas, hogy bemutassa azt a fajta out of the box gondolkodsmdot, ami a hekkerek sajtja. Remlem, elg rmiszt ahhoz, hogy minden adatbzis-programoz egyszer s mindenkorra komolyan vegye az SQL Injectiont.
11
http://en.wikipedia.org/wiki/Albert_Gonzalez
42
Eljtt az ideje a szmtsoknak. Ebben a fejezetben klnbz sszegzseket fogunk vgezni risi mennyisg adatunkon.
5.1
Aggregtumfggvnyek
Az SQL Server szmos hasznos s jl ismert aggregtumfggvnyt tartalmaz, valamint j sok olyat, amirl ennyi v utn sem tudom, hogy mire j. Amikrl knnyszerrel meg tudjuk llaptani, hogy mit is csinlhatnak, azok a kvetkezk: AVG(), SUM(), MIN(), MAX(), COUNT() s ezzel krlbell ki is merlt az ltalam rtelmezhet fggvnyek kre. Van mg standard deviancia, meg ilyenek, de ezeket tudtommal mentlis betegsgekkel lehet inkbb sszefggsbe hozni (deviancia, ugye ). Kr hogy csak a deviancinak van fggvnye, mert ha a skizofrninak is lenne, azt mondhatnnk, az SQL Server teljes kren alkalmas mentlhigins problmk megoldsra. De gy nem. Az a nhny fggvny viszont, amit rtnk, pont azt csinlja, amire szmtunk. Pldul a SUM() meglep mdon sszegez. Gyorsan sszegezzk teht a Transactions tblban a pnzeket, hogy lssuk, hogyan is mkdik:
Hirtelen fordtsban: a Currency mez rvnytelen, mert nem szerepel sszegzsben (ht mr hogy szerepelne?), de mg a GROUP BY listban sem. Mg magyarabbul: az a baj, hogy volt egy csom sorunk, amit az Amount mezre rpakolt SUM() egy sorr rntott ssze. A Currency mezvel meg nem csinltunk semmit, teht jelenleg tbbsoros. gy kellene szegny SQL Servernek egy j kis tblzatot faragnia, hogy az egyik mez tbbsoros, a msik meg egysoros. Nem fog menni.
5.2
Csoportosts, GROUP BY
A hibazenetben hivatkozott GROUP BY gy oldja fel ezt az ellentmondst, hogy az ott felsorolt mezk szerint csoportokat kpez az eredmnyhalmazon, majd a SUM() is az egyes csoportokon dolgozik. Ha teht az utastsnak engedelmeskedve betesszk a Currency mezt a GROUP BY zradkba, csodlatos s vgre - rtelmes eredmnyt kapunk:
43
Ez nagyon jl sikerlt, ezen felbuzdulva jelentsk meg a partnert is a lekrdezsben! Mondjuk rakjuk a csoportostsi felttelek kz! Merthogy lehet egynl tbb felttel szerint csoportostani, bizony!
Mg hivatalosabb lenne a Lehman Brothers csdje, ha csak a zr sszeg sorokat adn vissza a lekrdezsnk. Ha megprblkozunk a WHERE-felttellel, s oda berjuk, hogy WHERE SUM(Amount)=0, hibazenetet kapunk, hogy nincs ilyen sor. Valban, amikor a WHERE kirtkeldik, mg nincs. Ezt kveti a GROUP BY s az sszegzs, s ennek a msodik tblnak van egy msodik, sajt WHERE felttele, gy hvjk, HAVING.
5.3
SELECT Currency, Partner, SUM(Amount) FROM Transactions GROUP BY Currency, Partner HAVING SUM(Amount)=0
Ez remekl mkdik. Ne ijedjnk meg attl, hogy most a lekrdezsben ktszer szerepel a SUM() fggvny, az SQL Server elg okos ahhoz, hogy csak egyszer szmolja ki az sszegzst.
5.4
A fnknk elllt azzal az tlettel, hogy j-j ez a csoportosts, de mgiscsak szeretn ltni a pnznemenknti bontatlan sszegeket is. Mit tehetnnk? Engedelmeskednk neki. A cl rdekben berjuk az elz parancs vgre, hogy WITH ROLLUP:
Mindegyik j sornak tulajdonsga, hogy van benne egy vagy tbb NULL rtk. Ezek azrt vannak, mert a ROLLUP tnykedse valjban az, hogy megcsinlja a csoportostsokat gy, ahogy elzleg is, majd beszr egy olyan rszsszeget, ahol az utols csoportostst nem veszi figyelembe (ez nlunk a Partner), oda teht egy NULL-t tesz. Ezzel megmagyarztuk az els hrom piros sort: pnznemenknt egy-egy totl. Na de mi a legvgn a NULL-NULL? Az pedig a grand totl! A ROLLUP jobbrl haladva felgngylti a csoportostsokat, s egszen addig teszi ezt, amg az sszes csoportoststl megszabadul, ergo az sszes sszevont csoportmezbe NULL kerl, az sszegmezbe pedig egy orbitlis grand totl. Itt jn be a kpbe a csnya NULL megint, mert ugyan hogyan tudjuk most megllaptani, hogy egyegy NULL valdi NULL-e, mert NULL pnznem is volt az adatbzisban, vagy egy a lekrdezs ltalgenerlt NULL? J hrem van, kln fggvny dolgozik a ROLLUP mellett, ami pont ezt hivatott kimutatni, a neve GROUPING(), s gy nz ki a hasznlata:
SELECT Currency, GROUPING(Currency), Partner, GROUPING(Partner), SUM(Amount) FROM Transactions GROUP BY Currency, Partner WITH ROLLUP
45
ADATKEZELS OTTHON S A FELHBEN Ha ez megvan, fel is vagyunk kszlve valami nagyon vad dologra. A fnk azt kri, hogy brzoljuk az egyes pnznemekhez s partnerekhez kiszmolt rszsszegeket egy Descarteskoordintarendszerben. (A fnk vagy matematikus, vagy nem felejt. Vgl is ltalnos iskolban foglalkoztunk vele. Vagy nem?)
5.5
Kockulat, CUBE
Mieltt az elkeseredettsg rr lenne a lelknkn, elmondom, hogy a fnk krsnek igen egyszeren eleget lehet tenni. Csupn a ROLLUP szt kell kicserlni CUBE-ra, s kszen is vagyunk. Hogy mirt? Mert a CUBE kvzi ugyanazt csinlja, mint a ROLLUP, csak nem jobbrl balra, hanem minden kombinciban kiszmolja a rszsszegeket, amelyeket ezek utn a GROUPING() fggvny rtkei alapjn el tudunk helyezni a koordintarendszerben.
SELECT Currency, GROUPING(Currency), Partner, GROUPING(Partner), SUM(Amount) FROM Transactions GROUP BY Currency, Partner WITH CUBE
Egy picivel tbb rszsszeget kapunk, hisz most mr minden ltez s nem ltez csoportostsi s nem csoportostsi kombincira kiszmoldott, de annyi baj legyen, a lnyeg, hogy rtjk! (?)
Nhny rtket tpakoltam a koordintarendszerbe, hogy ltszdjon a logika. A grand totl kerl az origba, minden kistotl az adott tengelyre, a kiszmtott sszegecskk pedig a megfelel pozcikra. Azt is ltni kell, hogy valjban ez egy kocka, csak a mi pldnkban ppen ktdimenzis, mert mindssze kt csoportostsi felttelnk van. Ha hrom lenne, rendes, 3D-s kockban tudnnk az adatokat brzolni, ha ngy, akkor pedig ngydimenzisban. A rajzolgatshoz sok sikert kvnok, de megjegyzem, ezt gy nem szoktuk brzolni. Arra val az Excel, hogy ezeket az akrhny dimenzis kockkat emszthetv, kezelhetv tegye. Nem tudom, feltnt-e, hogy rvid kirndulst tettnk az OLAP-kockk vilgba?
5.6
s ezzel mg mindig nincs vge. Mind a ROLLUP, mind a CUBE ktttplys jrm, tetszleges sszegzskombincikra nem kpes. Erre is van azonban lehetsg, st, meglep mdon igny is. A
46
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA YouTube-on tallhat TSQL-mokfuts12 cm videmban lthat egy plda, aminl a GROUPING SETS lehetsg nagyban megknnytette egy komplex lekrdezs kialaktst. me egy plda, amikor csak s kizrlag a Currency s a Partner rszsszegeire vagyok kvncsi, a pici totlokra egyltaln nem:
SELECT Currency, GROUPING(Currency), Partner, GROUPING(Partner), SUM(Amount) FROM Transactions GROUP BY GROUPING SETS((Partner), (Currency))
s az eredmny:
12
http://www.youtube.com/watch?v=I6ILya-p-DE
47
Tkletesen megtervezett adatbzisunk messze tbb, mint egy tblbl ll. Ennek megfelelen lekrdezseinknek is figyelembe kell vennie ezt a jellegzetessget, meg kell tanulnunk sszekapcsolt tblkbl lekrdezni adatokat. A tblk sszekapcsolst a JOIN opertor vgzi, amely a FROM-ban felsorolt tblk kztt teremt kapcsolatot. Sokan tvesen azt hiszik, hogy lekrdezskor tekintettel kell lennnk a tblaszerkezet kialaktsakor megadott referencilis integritsi szablyokra. Errl sz sincs. Annyi azonban igaz, hogy tblinkat leggyakrabban a fellltott apa-fi kapcsolatok mentn krdezzk le. De hogy rgtn valami rtelmetlennel kezdjk, a JOIN szintaxist egy olyan lekrdezsen mutatom be, amelyik gy kapcsolja ssze a bankszmlkat a tranzakcikkal, hogy prt kpez, ahol a bankszmla ltrehozsi dtumnak hnapsorszmt kisebb, mint a tranzakci sszegbl nyert 3%os krtyadj egsz rsze. Csak hogy bizonytsam, hogy brmit brmivel sszekapcsolhatunk.
SELECT * FROM Accounts INNER JOIN Transactions ON DATEPART(MONTH, Accounts.CreationDate) < CAST(CardFee AS INT)
St, akr olyan felttelt is rhatunk a dzsoinhoz, amit a hekkerek szoktak hasznlni:
6.1
Figyeljk meg az alapszintaxist: FROM Table1 INNER JOIN Table2 ON felttel! Ebben egyedl az INNER JOIN lehet ismeretlen, ht elmagyarzom. Az INNER, vagy ms nven termszetes, naturlis JOIN egyezsget keres az rintett tblkban a felttel mentn. Pontosabban akkor ad sort a kimenetre, ha a felttel igaz. Apa-fi esetben ez a sorprokat eredmnyezi, mrmint ha a felttelben egyenlsget, hivatalosan equijoint hasznlunk. Lssunk akkor egy rtelmes pldt is, keressk a tranzakcikhoz tartoz szmlaszmot! A kapcsolat felttele, hogy az Accountnak az AccountID-je megegyezzen a Transactionban megbj apa-azonostval, aminek trkksen szintn AccountID a neve:
48
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA s most nhny szt az eredmnyhalmazrl. Ha nem vigyzunk, ez a lekrdezs mg gyilkosabb lehet, mint az egy tbln elkvetett korltozs nlkli lekrdezs. A JOIN ugyanis egy rislepedt kpez az egyestett tblkbl, sokszorosan, gyakorlatilag minden gyermekrekordhoz megismtelve az aparekordot. Egymilli gyerek t olyan apval, akiknek fnykpe van brutlis. Csak a szoksos mondkmat sulykolhatom: legyen WHERE-feltteled tenked. ssze tudunk-e kapcsolni kettnl tbb tblt egy mg nagyobb leped ellltshoz? Termszetesen. A JOIN tovbbi tblkkal gy bvthet, hogy az els kettt mint lepedt hozzkapcsoljuk a harmadikhoz, majd azt mint lepedt hozzktjk a negyedikhez s gy tovbb. Neknk ngy tblnk van, az ebbl kszlt mindent betakar lepedvszon gy nz ki:
SELECT * FROM Cities c JOIN Customers cu ON c.CityID=cu.CityID JOIN Accounts a ON a.CustomerID=cu.CustomerID JOIN Transactions t ON a.AccountID=t.AccountID
s az eredmny, a 86 mezs, soksoros leped:
6.2
A termszetes JOIN trskeres tpus. Akinek nincs trsa, az nem is ltezik. Sok alkalmazsnl fedezhet fel az a hiba, amit rviden csak az INNER JOIN tknak hvhatunk, hogy nem jelenik meg a pnztrgpen a termk, mert nem vittek fel hozz semmilyen akcit. Nem jn fel a knyvtri katalgusban a szerz, mert egyetlen knyve sincs bent. Nem lehet jelentkezni a weben a tanfolyamra, mert a httrben valaki nem rendelt hozz tantermet - ami egybknt a regisztrcit semmilyen formban nem akadlyozza. s persze hova tnt Damon Hill? Kell lennie olyan megoldsnak, amivel nem vesztjk el a bankszmlval mg nem rendelkez gyfeleket. Van is, gy hvjk, OUTER JOIN, s gy viselkedik, hogy egy adott tblbl megtartja az rva sorokat is. Pontosabban abbl a tblbl, amelyikre rbknk, hogy na, ez marad. A bal (LEFT OUTER JOIN), vagy a jobb (RIGHT OUTER JOIN), vagy mindkett (FULL OUTER JOIN). Ez utbbihoz elg beteg, referencilis integritst nlklz adattartalom is szksgeltetik Itt jn Damon Hill:
SELECT * FROM Cities c JOIN Customers cu on c.CityID=cu.CityID LEFT OUTER JOIN Accounts a ON a.CustomerID=cu.CustomerID LEFT OUTER JOIN Transactions t ON a.AccountID=t.AccountID
49
Remek, itt van Damon Hill, de lyukas nemcsak a benzintartlya, hanem a kereke is. A gyermektblkban minden adata NULL lett. Ami nem meglep, ha tudjuk, hogy nincs is gyermektbla-bejegyzse, egy sem. Most ismt itt llunk egy sereg NULL-lal, s els ltsra nem tudjuk eldnteni, hogy amit kaptunk, az igazi NULL (mert ugyan van bankszmlaszma Damon Hillnek, de nincs kitltve egyik mez sem), vagy generlt NULL (mert a gyermekrekord egyltaln nem ltezik). Erre a problmra van egy kzenfekv megolds. Ha figyelmesebben megszemlljk az eredmnyt, egy rulkod ellentmondst fedezhetnk fel. Maga a lekrdezs egyenlsgen alapult, igaz? De ha megnzzk, a CustomerID mezkre ez nem igaz! Az apatblban 4, a gyermektblban NULL. Ami gy egyenl, hogy kzben nem egyenl, az a generlt NULL biztos jele. s onnantl abbl a gyermektblbl minden NULL generlt nyilvn. A msik fontos dolog, hogy ktszer kellett kirnom a LEFT OUTER JOIN-t. Ennek oka az, hogy brmelyik gyermektbla ismt kihajtja Damon Hillt, ha nincs benne odavonatkoz sor. Ebbl az kvetkezik, hogy ha egy szinten elkezdtnk OUTER-ezni, azt kvetkezetesen vgig kell vinni lefel az adott irnyban, klnben nem csinltunk semmit.
6.3
Van a JOIN-oknak egy klnleges formja, a CROSS JOIN, ami az eddigiektl eltren nem ignyel felttelmegadst, mivel a kt hivatkozott tbla minden sort gondolkods nlkl sszeprostja egymssal. n ezt ltalban tesztadatgenerlsra hasznlom. Csinlok egy vezetknevek s egy keresztnevek tblt, mindegyikben tz-tz nvvel, majd sszekrosszolom ket, s mris van 100 vevm. Ha mg kzps nevet is felveszek tzet, s hrom tblt krosszolok, ezer vevm lesz. Ezer vevt ha sszekrosszolok ezer egyb adattal, egymilli soros tblt nyerek. s gy tovbb. Nem olyan nagy rdngssg szert tenni egy tbb milli soros tblra.
6.4
Self Join
Nem kln jointpus, mgis kln trgyaljk az nhivatkoz kapcsolatokat. Egy olyan kapcsolatot kpzeljnk el, ahol egy tblt nmagval kapcsolunk ssze valamilyen felttel mentn! Tipikus plda, amikor egy tblzatban valamilyen hierarchikus, pldul fnk-beosztott viszonyt kpeznk le oly mdon, hogy minden ember idegen kulccsal mutogat a fnkre. Egy ilyen tblban egy fnk beosztottjait gy tudjuk ellltani, ha ezt a tblt nmagval sszekapcsoljuk a hierarchit megvalst mez mentn. Ksztsnk egy tblt a bank dolgozival! Ne nagyon cicomzzuk, elg, ha nevk van meg persze a hierarchia: 50
CREATE TABLE Employees( EmployeeID INT NOT NULL PRIMARY KEY IDENTITY, BossID INT NULL FOREIGN KEY REFERENCES Employees(EmployeeID), Name NVARCHAR(88) )
rdemes megfigyelni, hogy a BossID, mely a fnkre mutat, nullozhat, msklnben egy rva darab sort nem lehetne felvinni ebbe a tblba. (Rejtvny: mirt?) s akkor jjjenek a dolgozk:
INSERT Employees(BossID, Name) VALUES (NULL, 'Mrges Gyula'), (1, 'Szorgos Kata'), (1, 'Pancser Gza'), (3, 'Okos Imre'), (3, 'Lusta Diszn')
Mrges Gyula a fnk, mert az fnke NULL nincs fnke. Kt kzvetlen beosztottja Szorgos Kata titkrn s Pancser Gza mszaki fosztlyvezet. Ez utbbinak van kt mrnke, Okos Imre s Lusta Diszn. Hogyan tudjuk lekrdezni Mrges Gyula beosztottait? gy:
Termszetesen a msik irnyban is kutakodhatunk a hierarchiban. Vajon kicsoda Okos Imre kzvetlen fnke? A JOIN felttelnek megfordtsval felfel tnk:
Sajnos nincs tovbb. Ha egynl tbb hierarchiaszintet szeretnnk egy lekrdezssel feltrni, az Employees tblt jra s jra hozz kellene mg kapcsolnunk. Ami jrhatatlan, hisz nem tudjuk, hny szintet is kell bejrni. A hierarchik kifejtsnek sokkal kifinomultabb mdja az gynevezett Common Table Expression, amire ebben a knyvben nem trek ki annak bonyolultsga miatt. Rekurzi Brrrrr A msik lehetsg pedig, hogy nem idegen kulcsokkal, hanem a HierarchyID adattpus felhasznlsval valstjuk meg a hierarchit. Erre az utols fejezetben ltunk pldt.
51
ADATKEZELS OTTHON S A FELHBEN Evezznk bksebb vizekre! A tblk sszekapcsolsnak msik mdja, amikor egymssal kompatibilis eredmnyhalmazokat fznk ssze.
6.5
Gyakori helyzet, hogy egy erteljesen hasznlt tblbl a rgebbi rekordokat temeljk egy msik, hasonl vagy azonos felpts tblba archivls cljbl. A rgi adatok eltvoltsval az l tbla megknnyebbl. Innentl azonban az adataink kt tblban vannak, s ha pont egy olyan idszakaszt kell elemeznnk, ami mindkt tblt rinti, gondban vagyunk. Hogyan lehet kt lekrdezs eredmnyt sszefzni? Ht UNION opertorral! Az alapmkdst remekl szemllteti az albbi lekrdezs:
Hogy ez meg mire j? Ht hekkelsre! Ttelezzk fel, hogy hekkernknek van egy frank SQL Injection hozzfrse a Customers tblnkra, de neki az Accounts tbla adatai kellennek! Igen m, de az a frnya lekrdezs, amit srlkenynek tallt, gy nz ki, teht nem beszlhet le a Customers tblrl:
52
SELECT * FROM Customers WHERE LastName = 'Akrki' UNION SELECT NULL, NULL, AccountNumber, NULL FROM Accounts--'
s mris az v 300 milli bankkrtyaadat. n mondtam, hogy lekrdezsi stringet nem fznk! Ugye megmondtam!
6.6
Begyazott lekrdezsek
Begyazott lekrdezst mr korbban hasznltunk. k azok a zrjelbe tett SELECT utastsok, amelyek egy-egy kifejezs helyn llhatnak, s kln, elre kirtkeldnek. Visszatrsi rtkk szerint megklnbztetnk egy- s tbbrtk begyazott lekrdezseket. Az egyrtkeket minden teketria nlkl felhasznlhatjuk pldul egyenlsgvizsglat esetn pldul gy: WHERE Mezo=(SELECT 1ertek FROM Tablacska). Ha azonban megcsszik a begyazott lekrdezs, s egynl tbb rtket produkl, az imnti egyenlsg gy borul fel, hogy meg sem ll a hibazenetig. Van azonban megolds a problmra. WHERE felttel esetn az albbi mdostkat hasznlhatjuk begyazott lekrdezsek s egyenlsgfelttel sszeboronlsra: Plda: ANY: a begyazott lekrdezs eredmnyhalmazbl ha brmelyik kielgti a felttelt, ok ALL: a begyazott lekrdezs eredmnyhalmazbl ha mindegyik egyszerre kielgti a felttelt, ok SOME: ez ugyanaz, mint az ANY, ANSI SQL nyelven megfogalmazva
SELECT * FROM Customers WHERE LastName = ANY (SELECT DISTINCT Lastname FROM Customers WHERE FirstName LIKE 'Jakab')
Ez a korbbi IN-es plda trva ANY-re, s tovbbra is azokat a vevket adja vissza, akiknek a vezetkneve megegyezik brmelyik msik Jakab vezetknevvel.
6.7
Korrellt "szabkveri"
Eddig mindig gy vettk, hogy a begyazott lekrdezs nmagban elvan, kln, nmagban j elre lefuttathat, produkl egy rtket, amit behelyettestnk s ksz. Van azonban a begyazott
53
ADATKEZELS OTTHON S A FELHBEN lekrdezseknek egy formja, amelyik nem ilyen. Lehetsg van ugyanis arra, hogy a hv belepiszkljon a hvott lekrdezsbe. Ezeket hvjuk korrellt lekrdezseknek. Jellegket tekintve a JOIN-okkal rokonok. Ha pldul az elz lekrdezst talaktjuk gy, hogy figyelembe vesszk a hv keresztnevt, egy olyan lekrdezshez jutunk, mintha a Customers tblt nmaghoz JOIN-oltuk volna a FirtName mez mentn. (A kls Customer tblnak knytelen voltam becenevet adni, hogy megklnbztessem a belstl.)
SELECT * FROM Customers c WHERE LastName = ANY (SELECT DISTINCT Lastname FROM Customers WHERE FirstName LIKE c.FirstName)
Ennek a lefutsa igen rdekes jelleget mutat. Mindaddig nem lehet kirtkelni a bels lekrdezst, amg meg nincs a kls kvetkez sora. gy ez most kls-bel-kls-bels lktetssel fog lefutni, soronknt. Illetve az SQL Server felismeri, hogy ez olyan, mint egy JOIN, s t is rja a lekrdezsi tervet JOIN-ra. Kis okos!
6.8
Nzetek
A begyazott lekrdezsek kln tpusa az elmentett begyazott lekrdezs, a VIEW, mely nem ms, mint egy nvvel elltott, elmentett SELECT, amit ksbb tblaknt tudunk felhasznlni. A nzet tblaknt viselkedik a hv szmra, de egy olyan tbla, ami az igazi fizikai tblknak csak egy ltalunk vlasztott szelett mutatja meg. Nhny sort s nhny oszlopot. Nzettel el lehet rejteni bizonyos nem publikus oszlopokat a kvncsi tekintetek ell. Nhny gyakorlati plda:
54
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA A felhasznl ne lssa a naplzsi oszlopokat. Ne is tudjon rla, hogy vannak ki_vitte_fel meg mikor_tetted_ezt oszlopok Ha egy adatbzisban logikai trlst valstunk meg a sorokon egy isDeleted BIT tpus mezvel, ennek nem szabad ltszania az les megjelentsben. St, ugyanezzel a bittel knnyedn tudunk csinlni egy Kuka nzetet, ami csak a trlteket mutatja. Minden utaz gynk csak azokat az eladsokat lssa, amelyek hozz tartoznak! stb.
Emellett a nzetek arra is alkalmasak, hogy komplexitst rejtsnk el vele. Megfogjuk a hromtbls JOIN-t, s belerakjuk egy nzetbe, innentl a hvk szmra ez csak egyetlen hatalmas tbla. Nem beszlve a szmtsignyes GROUP BY s aggregtumlekrdezsekrl, amelyeket szintn bele lehet pakolni egy nzetbe, hogy soha tbb ne lssuk a gusztustalan sok kdot. s vgl a nzetek tartalmt le is lehet mentetni az SQL Serverrel, aminek hatsra tizenmilliszorosra gyorsulnak, mert valjban nem futnak le tbb, hanem a lemezrl felolvassk a ksz adatokat. Az albbi pldban egy kompelxitselrejt nzetet ltunk, amely nem engedi lttatni a vgfelhasznlval, hogy a Customer tblnak mg mindenfle karbantartsi mezi is vannak (URLCode pldul).
A nzet trzsben megadott lekrdezsre bizonyos korltozsok vonatkoznak, amit majd ki-ki a hibazenetek mentn jl kitapasztal. Pldul nem lehet a SELECT-ben ORDER BY, illetve mgis, de csak ha TOP is van, meg ilyenek. Megjegyezhetetlen.
55
ADATKEZELS OTTHON S A FELHBEN Ha egy nzet tbb tbla sszekapcsolsval alkotta meg azt a tblt, amit a felhasznl lt, a mdosts gy vltozik, hogy lehet mdostani, de csak olyan UPDATE fut le, ami egyszerre egy idben csak egy httrtblt mdost. A nzetek biztonsgi funkcijnl fontos krds, hogy a nzeten keresztl idegen adatot tudok-e macerlni. Mit tesz egy olyan mdosts esetn, amely lthatatlan, de ltez adatra vonatkozik? Tbb-kevsb az elvrsoknak megfelelen viselkedik, br sarokba lehet szortani olyan UPDATE-tel, ami egy lthat sort lthatatlann mdost, mert megteszi. Ha valakinek ez a viselkeds nem tetszik, a nzet ltrehozsi parancsba a vgre vegye fel a WITH CHECK OPTION-t, gy:
ALTER VIEW KisCustomers AS SELECT CustomerID, LastName, FirstName FROM Customers WITH CHECK OPTION
Egy msik opci pedig lehetv teszi, hogy a nzet defincijt soha tbb senki ne tudja elrni (belertve magunkat is), melyhez a WITH ENCRYPTION kiegszts alkalmazst javallom. Titkosts utn ne csodlkozzunk, ha a nzet tbb nem szerkeszthet, nem scriptelhet, nem mozgathat, s sszessgben semmit nem lehet vele csinlni, ami a defincijval kapcsolatos. Vgezetl emlkezznk meg a VIEW-k teljestmnynvel hatsrl, vagy ms nven a materializcirl! Az eddigi nzeteink tulajdonkppen nem lltak msbl, mint egy elmentett SELECTutastsbl. Valahnyszor a nzetet babrljuk, az alatta lv tbln s tblkon dolgozunk. Ha egy bonyolult szmts van a nzetben, az bizony minden futtatskor jra s jra kiszmtdik. Van azonban egy lehetsg, ami ezt a sok jraszmtst kikszbli, ez pedig a materializci, vagy ms nven az adattartalom lementse. Erre nincs kln parancs az SQL Serverben. A materializci akkor kvetkezik be, amikor valaki custered indexet pakol a nzetre. Sajnos a materializcinak 8-10 megjegyezhetetlen14 felttele van, gyhogy aki ilyet csinl, majd a hibazenetek eligaztjk, mit kell mg tennie. Sok sikert!
14
Persze, hogy tudom, de olyan szraz, hogy ha rendesen a knyvbe rnm, mindenki lt helyben elaludna. J ez itt a lblcben. Kell bele WITH SCEMABINDING, COUNT_BIG() s egyedi rtk mez, nem lehet benne nem determinisztikus rtk mez, az indexnek pedig clusterednek kell lennie.
56
Tuning alapok I.
Most, hogy a lekrdezsekrl mr mindent tudunk (kivve a CTE-ket, az EXCEPT-et, INTERSECT-et, a HIERARCHYID-t, az XML-lekrdezseket, a geokordintkat s a pocedurlis nyelvi elemeket v. mit adtak neknk a rmaiak), rtrhetnk a teljestmnyhangols krdsre. Azt mr emltettk, hogy a lekrdezsek legjobb bartja az az index, amelyik hathatsan segt a lekrdezs adatainak ellltsban. Arra is trtnt utals, hogy ha egy lekrdezshez nincs j index, az SQL Server vgig fogja kurkszni a tblt az adatok elrse rdekben. Mi mst tehetne? St, mg az is igaz, hogy az SQL Server maga dnt a megfelel indexek kivlasztsrl, mert ugyan ki ltott mr olyat, hogy egy lekrdezsben mi magunk megadjuk a hasznland indexet? n lttam. s hamarosan mindannyian ltni fogunk ilyet. De ez csak kivtel lesz, ami ersti a szablyt:
7.1
Fontos fogalom a lekrdezs szelektivitsa, ez hatrozza meg, vajon egy jnak tn indexet valban rdemes-e hasznlni, vagy olyan sok sort ad vissza a lekrdezs, hogy felesleges veszdni az indexszel. A szelektivits pedig az gynevezett indexstatisztikbl derl ki. Amikor egy mezre indexet ksztnk (st, nha anlkl is), az SQL Server ltrehoz egy statisztiknak nevezett valamit, amit arra hasznl, hogy elre tudja, hny sort fog rinteni az adott lekrdezs. A statisztika alapjn egy WHERE-felttelrl elre tudja, hogy az 10, 100 vagy 1000 sort ad vissza. Mr amennyiben a statisztika nem elavult. Ha nem bntalmazzuk az adatbzis belltsait, a statisztikk nem elavultak, mert automatikusan ltrejnnek minden index mell, s a karbantartsuk is automatikus, ha egy bizonyos mennyisg indexkulcs megvltozott. Furfangos krds: ksztettnk-e mr indexet a Bank adatbzis brmelyik tbljn, azon bell brmelyik mezn? Az a hangszr, aki azt vlaszolta, hogy igen, ksztettnk. Amikor ugyanis a kulcsmeznket megjelltk a PRIMARY KEY jelzssel, a httrben ltrejtt egy nem is akrmilyen, hanem frtztt (clustered, j kis flrefordts, bocsnat, nem n voltam) egyedi (unique) index. (Gyorsan egy kis
57
ADATKEZELS OTTHON S A FELHBEN fogalommagyarzat: A clustered gyakorlati jelentse: e szerint a mez szerint fizikailag is sorba rendezte a rekordokat. Unique: nem lehet az indexben kt azonos rtk.) s ha mr gy esett, vele prhuzamosan ltrejtt egy hozz tartoz indexstatisztika is. gy nznek ki egyms mellett:
Indexeket egyes mezkre vagy mezcsoportokra hozunk ltre, egy tbln akr tbbet is. Egy index a szlinap mezre, egy index a vrosnvre stb. A clustered indexnl idzznk el egy picit! Mit jelent az, hogy fizikailag sorba rakta a rekordokat? Egy hasonlattal vilgtanm meg a krdst: a budapesti telefonknyv lapjain tnylegesen (fizikailag) helyes sorrendben vannak az ldozatok bocsnat, az elfizetk. A telefonknyvn teht van egy vezetknv+keresztnv clustered (frtztt?) index. Ha ez a hasonlat rthet, a hangszr prjt az kapja (hogy meglegyen a sztere!), aki megmondja, hogy hny clustered index szerepelhet egy tbln. Igen, pontosan ugyanannyi, ahnyfle fizikai sorrendje lehet egy telefonknyvnek. Egy, egyetlenegy.
7.2
Ezzel elrkeztnk az indexek mkdshez s hasznlhatsghoz. A telefonknyves hasonlat annyira j, hogy nagyon rlnk, ha n talltam volna ki, de sajnos loptam valakitl, s mr nem is emlkszem, kitl. Maradjunk teht a telefonknyvnl. Hogyan lehet kikeresni a telefonknyvbl az sszes Gipsz Jakabot? Mi sem egyszerbb, beleprgetnk a G-ig, tovbbgrgetnk a Gipsz-ig, majd Gipsz Jakabig, s onnantl sorban egyms utn jnnek a Gipsz Jakabok, ugrlgatni nem is kell. Az utols Gipsz Jakab utn biztosra vehetjk, hogy nem lesz tbb, megllhatunk. Akkor most keressk ki az sszes Jakabot! Jaj. De ht mit vacilllunk, van egy vezetknv+keresztnv indexnk, benne a nevek helyes sorrendben vagyis hogy iz Ezen indexen bell a Jakabok akrhol lehetnek! Vagyis ez az index nem alkalmas Jakab-keressre. Akkor mi marad? Oldalanknt vgiglapozni a teljes telefonknyvet, kiszedve belle a Jakabokat. Ht igen. Az SQL Server esetn is gy van. Ha egy index sorrendje rossz, akkor az rossz index, hiba digitlis, s nem papralap.
58
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA A teljes tbla vgignzse is egy lekrdezsi stratgia az SQL Serverben, gy hvjk, Table Scan, illetve ha van a tbln clustered index (norml esetben mindig van), akkor Clustered Index Scant fogunk ltni, de ez attl mg ugyanaz. A kvetkez feladat a hangszrrt (h, ez mr 3/5 surround!) annak megvlaszolsa, hogy milyen lekrdezsi stratgival lehet a budapesti telefonknyvbl kikeresni az sszes dugulselhrt kisiparost. n nyert, Table Scan15 az egyetlen ltez megolds. Melynek kltsgignyt ne feszegessk. Nem vletlen, hogy dugulselhrtt szaknvsorbl keresnk. s ezzel elrkeztnk a tovbbi, nonclustered (rtsd: hagyomnyos) indexekhez. Mi lenne, ha a szaknvsor nem tartalmazn a szaki elrhetsgt, csak egy mutatt a Hivatalos Telefonknyv adott oldaln egy adott sorra? Akkor megvalsulna a hagyomnyos index, melynek hasznlata a kvetkez. Ha egy adott szaki elrhetsgt keressk, gyorsan megtalljuk a szakmt az indexben, majd hopp, elkapjuk a telefonknyvet, feltjk a megadott oldalon, s mr meg is van a kvnt telefonszm. Ha arra vagyunk kvncsiak, van-e a vrosban patkolkovcs, feltjk a szaknvsort, amiben vagy megtalljuk a patkolkovcsokat, vagy nem, de akr gy, akr gy, a keress befejezdtt, a telefonknyvre nem kell tugrani, mert senki nem krdezett telefonszmot. Ha Sopronban jtsszuk ugyanezt a jtkot, s ki akarjuk keresni a fogorvosok telefonszmt, az egy msik helyzet, mert Sopronban minden msodik lakos fogorvos (az osztrkok miatt), gy hall felesleges a szaknvsorbl tugrani a telefonknyvre meg vissza, kvetkez fogorvos, meg vissza, oda, vissza, oda, vissza, ilyen esetben a szaknvsort pihenni hagyjuk, s vgignyaljuk a telefonknyvet. A lekrdezs szelektivitsa kisebb annl, aminl megrn veszdni az indexszel. Ezzel egy ltalnos tanulsghoz jutottunk. Nem mi hatrozzuk meg, hogy egy index j lesz-e egy lekrdezs gyorstsra, s mg csak nem is az SQL Server, hanem az adat maga! Az adatok eloszlsa, szelektivitsa a kulcskrds! Ha valamibl kevs van, j lesz az index! Ha meg rengeteg, uccu neki, Table Scan. Nem rdemes erltetni. Ezzel t is vettk az indexels elmleti alapjait, sajnlom, hogy csak hrom hangszrt osztottam ki, ez van, lpjnk tl ezen a hinyossgon! (Van bal s jobb, meg center. Nem elg?)
7.3
15
A Scan sznl addott volna egy tall magyarts, a sznkzs, tblasznkzs, de vgl elvetettem, mert fjt lerni.
59
Technikai rtelemben nem annyira gyors, mint lehetne. Merthogy egsz egyszeren vgigtalpal a Cities tbln (emlkezznk, Clustered Index Scan=Table Scan, csak gy rja ki a kis butus). Ez olyan krds volt, amire nincs index, de tallat sem. Mint a hhny szakma jeles kpviseli a telefonknyvben. Egybknt ha egy felhasznlknt egy tblt krdezgetnk, megdbbenten gyors az SQL Server. Szinte mindegy, hogy hny rekordon, akr tbb millin futtatjuk, hast. Pedig a nemltezs megllaptshoz is vgig kell msznia a tbln. Egymilli vros mindssze olyan 8 megabjtnyi adat, aminek az ezerszerese fr el egy pendrjvon, azaz egymillird vros mg simn hordozhat kategrij adatmennyisget jelent. Ez azt jelenti, hogy akrhogy kzdnk, a vros tblnk egy az egyben be fog frni a memriba, s msodpercenknt tbb millird gpi kd utastst vgrehajt processzorunk is gy falja fel, mint n reggelire a rntottt. A tipikus fejleszti tveds, amikor a sajt gpn minden hast, s azt gondolja, ez majd les helyzetben is gy fog tekerni. Ht nem. Egyrszt a felhasznlk szma garantltan tbb lesz, mint egy. Msrszt ha egy ilyen lekrdezs nem rnknt egyszer, hanem percenknt tzezerszer fut le, ott mr minden milliszekundum szmt. Percenknt tzezerszeri lefutst pedig mg aprcska weboldalakkal, nhny szz ltogatval is el lehet rni, ha valaki idtlenl rja meg a kdjt, s mg nem is gyorsttraz (kessel). Tapasztalatbl mondom! Az a tny, hogy az adatbzis-alkalmazsok 90%-a index nlkl kezdi meg az lett, nem jelenti azt, hogy sokig hzni is fogja gy. Az adatmennyisg s a felhasznlszm nvekedsvel garantltan be fog borulni. Lssuk, mirt! Csinljunk indexet a tblra, s nzzk meg, ennek hatsra hogyan vltozik a feldolgozs!
60
Els pillantsra taln ugyanolyannak ltszik, mint az elz, de ez nem igaz. Egyrszt ltjuk a feliratbl, hogy a NameIndexet hasznlja, msrszt az ikonja is ms, tmegy rajta a kk villm, mg az elzekben L-bet szeren fekdt alatta. A megnevezse is ms, ez nem Scan, hanem Seek, keress, vagyis az brrl sszessgben az olvashat le, hogy a NameIndexet hasznlta, mgpedig helyesen, bejrva a benne megbv ft. Kellene csinlni egy egymilli soros ellenprbt, hogy mi a klnbsg a kt stratgia kztt! Ezzel ne fertzzk meg a szp kis banki tblinkat, ksztsnk egy direkt erre a clra ltrehozott tblt, mondjuk dtumokkal, gy:
300 milliszekundum egymilli soron. Ht emiatt kr lenne vergdni az indexekkel, mondhatn valaki. De ne feledjk el, hogy egy felhasznl dolgozik prhuzamosan, s a teljes tbla vlhetleg bent van a fizikai memriban. A krds inkbb az, hogy objektve hnyszorosra gyorsul ez a lekrdezs, ha odaadjuk neki a megfelel indexet. A kliensoldali statisztika j dolog, de a szerveroldali mg jobb. Kapcsoljuk be a 8k-s lapok mozgst lemr statisztikt ezzel a paranccsal:
SET STATISTICS IO ON
Ezt kveten lefuttatva (s tnylegesen lefuttatva, F5!) a fenti parancsot, a Messages fln a kvetkez rdekes sorokat olvashatjuk:
Table 'Osszevissza_datumok'. Scan count 1, logical reads 2853, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Magyarra fordtva: a tblnkhoz egyszer kellett hozznylnia, amikor is 2853 darab 8k-s lapot olvasott vgig, ami mind a memriban volt (logical read= memriaolvass), s nulla darabot kellett a merevlemezrl beolvasnia merthogy mind a memriban volt. (A teljes adatmennyisgnk teht 2853 * 8k = 22 MB, egymilli dtum plusz egymilli integer.) Most tegynk indexet a Datum mezre, s futtassuk jra!
7.4
Ha mr tuningolunk, emlkezznk meg az gynevezett optimizer hintekrl, melyeket l (produkcis) krnyezetben nem hasznlunk, hiszen azt felttelezzk, az SQL Server gyis okosabb nlunk, ami igaz is. Elfordulhatnak azonban olyan esetek, amikor ltszlag nem annyira okos, s j lenne trgyilagosan sszehasonltani, hogy az ltala vlasztott megolds tnyleg annyival jobb-e, mint ami els ltsra logikusnak tnik. Rengeteg optimizer hint ltezik, mi most csak egyet hasznlunk, azt, amelyikkel indexhasznlatot (vagy nemhasznlatot) tudunk kiknyszerteni. Az elz lekrdezst msoljuk le egyms al kt pldnyban, s az egyikre varrjuk r az indexet, akr tetszik neki, akr nem (egybknt tetszik, hisz ezt hasznlta magtl is) a WITH (INDEX=DatumIndex) utastssal, mg a msikrl tiltsuk le az indexet a WITH (INDEX=0) utastssal, gy:
SELECT * FROM Osszevissza_datumok WITH (INDEX=DatumIndex) WHERE Datum='1848.03.15' SELECT * FROM Osszevissza_datumok WITH (INDEX=0) WHERE Datum='1848.03.15'
Majd a kt sort egytt kijellve nyomjunk egy nagy CTRL+L-t (Estimated Execution Plan), s vizsgljuk meg a kt vgrehajtsi tervet! Ami rdekes lesz, az a kt lekrdezs vgrehajtsi teljestmnynek egymshoz val arnya, melyet pirossal bekarikztam:
63
Megllapthatjuk, hogy a tbla vgigolvassa vitte el az egyestett vgrehajtsbl az id16 100%-t, majd a fennmarad 0%-nyi id alatt az indexes lekrdezs is lefutott. Teht a kzel ezerszeres gyorsuls nem vicc, itt is ltszik, hogy tredkid alatt fut le az indexszel gyorstott lekrdezs.
7.5
Egy msik tuningolsi rdekessg a csillag karakter hasznlata, illetve nemhasznlata. Sokszor szoktam mondani, hogy a csillag tiltott karakter, most eljtt az ideje, hogy megtudjuk, mirt. Kltzznk vissza a Customers tblra, s krdezzk le Damon Hillt:
Ez az id valjban nem id, hanem IO-mvelet, a lekrdezshez felhasznland 8k-s lapok szma. Mivel a lekrdezs idejt a legnagyobb mrtkben az hatrozza meg, hny 8k-s lapot kell megmozgatni, n a tovbbiakban idt rok, mert ettl mg a mondat is olvashatbb lesz. Fejben mindenki fordtsa t az id-t 8ks lap-ra! Ksznm.
64
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Szerencsre keznkben van az eszkz, amivel ki tudjuk knyszerteni az indexhasznlatot, s ki tudjuk mrni, hogy vajon mirt nem hasznlja? Futtassuk az albbi kt parancsot egytt kijellve, s mindjrt kiderl a turpissg:
SELECT * FROM Customers WHERE LastName='Hill' SELECT * FROM Customers WITH (INDEX=LastNameIndex) WHERE LastName='Hill'
Az els az eredeti lekrdezs, a msodik pedig az a vltozat, amelyikben rerszakolom azt az indexet, amelyiket valamilyen okbl nem hajland hasznlni. A vgrehajtsi tervek a kvetkezkppen alakulnak:
A piros karikk alatt ltszik, hogy az indexmentes lekrdezs az sszestett id 33%-t, az indexes pedig 67%-t vitte el, teht az indexes lekrdezs ebben az esetben ktszer annyi idt emszt fel, mint a sima Table Scan. Hmmm. Biztosan az lehet a httrben, hogy a msodik vgrehajtsi terv valami hiperbonyolult, rtelmetlen akrmi lett, amiben mg JOIN is van. Aki erre tippelt, nem jr messze az igazsgtl, a krds mr csak az, mi ez a kosz ottan? Ha ez a csnya komplexits nem csszik be, biztosan az indexes lett volna az olcsbb. De becsszott. Most jn a vaslogika. Milyen adatok szerepelnek a LastNameIndex indexnkben? Benne vannak a vezetknevek, szpen binris fba felfzve, knnyen keresheten. Emellett benne van az elsdleges kulcs mint mutat, amivel arra a sorra mutat, amelyikbl szrmazik. s mi melyik mezket kvnjuk kilistzni a fenti lekrdezssel? A mindensget, a csillagos eget.
65
ADATKEZELS OTTHON S A FELHBEN Emiatt ha a delikvensnket villmgyorsan megkeressk az indexszel, mg csak kt adathoz jutottunk hozz, a vezetknevhez s az elsdleges kulcshoz. Ez a kvnt adatmennyisg fele se. A kulcsrtk birtokban most le kell frni a tblig, Damon Hill megfelel sorig, s fel kell olvasni a maradk adatokat. Ez lenne a Key Lookup lps, mely a kulcs alapjn a tbbi adatot felhozza a mlybl. Most akkor van kt adathalmazunk, az, ami az indexbl jtt, s az, ami a tblbl. Ezt a kettt a kulcsmez segtsgvel sszedzsoinoljuk (Nested Loop), s mr kszen is vagyunk. rdemes az egrrel a Nested Loop fel tart vonalakra llni, mert megmutatja, melyik nylon hny sor s hny bjt jn. Bizony. Az indexbl jn 22 bjt, s tovbbi 66 bjt a tblbl. Egy dolgot azrt tisztzzunk: ebben a pldban a teljestmnyeltrs abbl addik a Table Scan javra, hogy van vagy t vevnk, teht a Table Scan biztosan olcsbb brminl, mert 1 darab 8k-s lapot kell megmozgatni. A Fejleszt Tvedse szindrmt lthatjuk teljes pompjban virtani. Minek ide index? Ja, hogy lesben majd nem t, hanem tvenezer kuncsaft lesz? Ki r r ezzel szembeslni? Haladjon a fejleszts, haladjon! Ha teht a Customers tblt megtolnnk pr ezer vevvel, hamar fordulna a kocka, s az indexelsKey Lookupols a maga 3 darab 8k-s lapjval kenterbe vern a Clustered Index Scant. De mg e pici tbla esetn is menthet a helyzet. Rossz tlet lenne az indexet rszgelni a lekrdezsre, azt mr lttuk. De mi lenne, ha engednnk egy picit az ignyeinkbl, s nem minden oszlopot krdeznnk le, hanem mondjuk csak az ID-t s a vezetknevet? Hagyjuk a csillagot bkn, annak az gen a helye, nem a lekrdezsnkben. Erre gondolok:
Hoh! Elkezdte hasznlni az indexet, st, a Lookup s a Nested Loop is eltnt! A jelensg oka az, hogy csak olyan adatot krdeztnk le, ami mr magban az indexben is megtallhat, teht nincs rtelme lefrni a tblba. Az ilyen helyzeteket fed (covering) lekrdezsnek, fed indexnek hvjuk, s sokkal tbbet r annl, mint amit nyilvnvalan mr most is hozott. A fed indexes lekrdezs ugyanis azltal, hogy nem megy le a tblhoz, garantltan nem akadlyozza a tbbi felhasznlt, klns tekintettel az adatmdostsokra. Garantltan nem akadlyozza az adatmdostsokat, hiszen ott sincs. Egy gyes fed indexszel megintcsak
66
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA tizenezerszeresre lehet nvelni egy alkalmazs (ltszlagos) teljestmnyt, pedig ebben az esetben csupn a vrakozsokat szmoljuk fel, ha gyesek vagyunk. Nem vletlen, hogy gyakran ksztnk tbbmezs indexeket, hogy minl fedbbek legyenek, illetve nem vletlen, hogy az indexekbe behelyezhetk gynevezett vendgoszlopok az INCLUDE kulcssz hasznlatval, amelyek a sorba rendezsben ugyan nem vesznek rszt, de legalbb fednek. Ha lemondunk a csillagrl. A hallcsillagrl.
A feds egybknt mg olyan esetekben is helyzetbe hoz indexeket, ha a sorrendjk ugyan rossz, de tartalmilag rendben vannak, mert ilyenkor az SQL Server elszeretettel csinl Table Scan-t magn az indexen, minitblnak tekintve azt. s igaza van. Mg egy a lekrdezs szempontjbl helytelen sorrend index sznkzsa is gazdasgosabb magnak a tblnak a vgigtekersnl, mivel egyrszt kisebb adathalmaz, msrszt ismt befigyel a msokat-nem-akadlyozunk jelensg.
7.6
Kezd tuningismereti ttekintsnkben vgezetl a balrl zrtsg fogalmval ismerkednk meg. Azt mr lthattuk, hogy egy sszetett index (vezetknv, keresztnv, telefonknyv) msodik tagja a teljes adathalmazra vettve kaotikus sorrendben van, avagy hol is van Jakab a telefonknyvben? Ugyanez a kosz kicsiben is megfigyelhet az egyes szveges indexek karakterein. rtelmesebben kifejtve: a vezetknv index legels karaktere bcrendben van. A msodik karaktere pedig az elshz kpesti ismtld kisbckben. A harmadik karakter a msodikhoz kpest mg kisebb bck garmadja. Ha azonban a bevezet karakterek nlkl, sszefggsbl kiragadva nzzk pldul a harmadik karaktert, mini bck ikszezerszer ismtldve, teht gyakorlatilag kaotikus sorrendben van. Avagy keresd ki a telefonknyvbl az sszes embert, akinek a vezetknevben a harmadik bet z! Az ilyen lekrdezsek vgrehajtsban az indexek csak annyiban tudnak segteni, hogy ha sorrendileg nem is, de fedknt rszt tudnak venni a keress gyorstsban. A LIKE utasts segtsgvel szoktuk leggyakrabban elkvetni a balrl nem zrt lekrdezseket, s noha ez nem az egyetlen j mdszer az indexekkel val kitolsra, de gyakorisgban ez viszi a prmet.
67
ADATKEZELS OTTHON S A FELHBEN Msik kzismert mdszer szveges mezkben (pldul termknevek, knyvcmek) bizonyos szavakra keresni, mert ott is az a helyzet, hogy az els sz mg balrl zrt kifejezsnek szmt, de a msodik mr nem. Fentebb mr lthattuk, hogyan nz ki egy szablyos indexhasznlat, ezt itt nem jelentem meg ismt. (Emlkeztetl: Index Seek, Kk Villm.) Most keressk ki azokat a vevinket, akiknek i bet van a nevben:
Amit ltunk, az maga a feds. Felhasznlja teht a LastNameIndexet, de annak a sorrendje a jelen lekrdezs vonatkozsban hulladk, viszont legalbb lefedi a krdses lekrdezst. A stratgia nem Seek, hanem Scan, kk villm nyilacska helyett kk L-bet nyilacska van. Az trtnik, hogy az indexnket mint minitblt sznkzza vgig, mert olcsbb ezen sznkzni, mint a tnyleges tbln. But thats it, ahogy a mvelt orosz mondan. Mindebbl az kvetkezik, hogy prbljuk elkerlni a balrl nyitott lekrdezseket? Ht, ez nem kvetkezhet, mivel ha egy alkalmazsnak erre van szksge, ezt fogja csinlni. A tanulsg inkbb az, hogy ilyen esetben az index hatkonysga tredke annak, mint amire szmtunk de mg gy is megri leindexelni ezt a mezt, mert a feds az mgiscsak feds. Akit pedig nem vert meg a magyar nyelvvel a sors, megprblkozat a Full Text Index bevetsvel, ami ugyan a karakterenknti balrl nyitottsg ellen nem vd, de ha egy szveges mezben keresnk egy szt, az is balrl nyitott kifejezs, az ellen pldul vd. Milyen kr, hogy kis haznk egy fehr folt s egy fekete lyuk egytt a Full Text Index trkpn. Ezrt ez utbbival most nem is foglalkozunk, majd taln 2016-ban. Ezzel a tuninglecknk els rsze vget rt, visszatrnk mg a tmra a tranzakciknl. Aki esetleg gy gondolja, most aztn jelents mlysgekbe kalauzoltam el, hadd lombozzam le: a felsznt karcolgattuk. Nem mondom, hogy ezzel a hrom lekrdezsi stratgival nem lehet okosakat mondani egy lekrdezsrl, de mi van a maradk 40 ikonkval? zelt a Books Online idevg fejezetbl, klns tekintettel a jobb oldali grdtsv elkesert mretre:
68
69
Mindezidig egy-kt szksges plda kivtelvel elkerltem az adatmdostsi utastsok krt. Ezt azrt tettem, mert az adatmdosts s felvitel egy msik vilg. Mg a SELECT lubickol a tbbfelhasznls vgrehajtsban, s a klnbz felhasznlk lekrdezsei gy szguldoznak egyms mellett, mint a heringek az rvnyben, az adatmdost utastsok gonosz boszorkk. Mindent maguk akarnak csinlni a sajt kis barlangjukban, lehetleg gy, hogy a piszkos tnykedskbe senki ne lsson bele, az tvltoztats trkkje csak az vk, a tid meg az eredmny, nesze.
Ennek termszetesen megvan a maga oka. Igen butn nzne ki, ha egy sort tbben egyszerre mdosthatnnak, mert miv lesz a vilg, ha egy termket egyszerre, egyidben eladunk A-nak is s B-nek is? Nem-nem! Amg az A mvelet vget nem rt, addig abba ne kontrkodjon bele senki! Ezt a fajta sztvlasztst az SQL Server zrolsi rendszere oldja meg, teljesen automatikusan. Mi csak nfeledten mdostgatunk, meg bezr, kinyit, megfog s elenged. A zrolsi rendszer ismerete az adatmdostsokkal kapcsolatos prhuzamossgi s egyb problmk elhrtsnak fontos eszkze. Aztn itt van a mdostsok mellkhatsa, a mdostsok mdostsa. A korbbi fejezetekben lazn szrtuk az indexeket, s nem trdtnk azzal, hogy ez a ksbbiekben milyen htrnyokkal jr esetleg. Merthogy a mdostsok bizony az indexeket is mdostjk. Ha egy adatot leindexelek, ezzel megduplzom, hisz belekerl az rtk az indexbe is, akkor ennek minden mdostsa dupla mdostst ignyel, hisz az nem engedhet meg, hogy a rekordban trolt rtket mdostom, az t elrhetv tv indexet viszont nem. Ez az okfejts azt sugallja, hogy ha egy adatbzisban tlnyomrszt mdostsok zajlanak, akkor azt ne indexeljk. Csudt! Ez a gondolatmenet a programoz alaptvedse cm tvedsgyjtemny szp kiegsztje. Minden UPDATE s DELETE mindaddig SELECT, amg meg nem talljuk a 70
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA mdostand sorokat, de utna tcsap valami egszen msba. A boszorkny hering htn rkezik, ha szabad egy klti kpzavarral lnem. Teht az okos monds inkbb az, hogy sszel indexeljnk ilyen esetben. Csodk nincsenek. Ha egy mdost utasts WHERE-felttelben szerepel egy mez, ami alapjn meg kell tallni a sort, de erre nincs index, akkor vajon hogyan fogja megtallni a clrekordot az SQL Server? Table Scan=Clustered Index Scan. Ennyi elmlkeds utn vegyk sorra az adatmdost utastsokat!
8.1
INSERT utasts
Az INSERT utastssal viszonylag gyorsan fogunk vgezni, mivel egyrszt mr korbban knytelenek voltunk hasznlni, msrszt meg annl sokkal tbbet nem is tud, mint amire mr hasznltuk. Van egysoros INSERT, tbbsoros INSERT, vannak egy tblban rhat s (ltalunk) rhatatlan mezk. Nem is a szintaxis itt a lnyeg, hanem az INSERT hasznlata les helyzetben. Mert van itt egy bkken. Alapesetben az INSERT utn zrjelben felsoroljuk azokat a mezket, amelyeknek rtket kvnunk adni akr a VALUES kulcssz utn, akr egy SELECT vagy egy trolt eljrs eredmnyhalmazbl. Mely mez(ke)t nem soroljuk fel? Ht pldul az IDENTITY, vagyis automatikusan nvekv mezket nem mi rjuk, hanem a rendszer. Ezrt adtunk hozz j vrost a Citieshez gy:
71
ADATKEZELS OTTHON S A FELHBEN kzl csak azt mutatom, amelyik a legkevesebb buktatt tartalmazza. Ez pedig a SCOPE_IDENTITY() fggvny, amit gy hasznlhatunk kzvetlenl az INSERT utn:
SELECT SCOPE_IDENTITY()
Ez az utasts pontosan az ltalunk legutoljra futtatott INSERT sorn kiadott IDENTITY rtkt adja vissza. A tudlkosabbak kedvrt megjegyzem, hogy tudom, hogy van @@IDENTITY, meg IDENT_CURRENT(), de ezekkel a kezdk mindig felborulnak, gyhogy hagyjuk, nincsenek. A harmadik lehetsg elsre egy picit jobb tletnek tnik, mrmint hogy az INSERT adja vissza az ID-t, mert akkor nem ll fenn az a veszly, hogy a beszrs s az azonost lekrdezse kz bekeldik valami ms utasts. Ezzel viszont az a baj, hogy olyan kliensalkalmazs is kell hozz, amelyik eltri, hogy az INSERT visszabeszl. Merthogy alapbl nma. gy tudjuk t szra brni:
72
8.2
A szekvenciaobjekum
Az SQL 2012-ben jelent meg jdonsgknt a szekvencia, ami nem ms, mint egy olyan szmll, amit nem a tbla kezel (ellenttben az IDENTITY-vel), hanem n, a programoz. Persze eddig is lehetett ilyesmit hzilag sszetkolni, s sokan ltek is ezzel a lehetsggel, a szekvencia azonban sok tekintetben tltesz a hzilag barkcsolt megoldsokon. Egyrszt beptetten kezeli a tbbfelhasznls (zrolsi) helyzeteket, msrszt gyorsttraz, harmadrszt lehetv teszi, hogy az alkalmazsok nagy blokkokban krjenek maguknak azonostkat, amiket aztn szabadon s az sszetkzs veszlye nlkl hasznlhatnak fel a ksbbiekben. Ez az eljrs a vonalkdok kiosztshoz hasonl, ott is minden felhasznl teljesen autonm mdon gazdlkodik egy elre kiosztott kszletbl. Hozzunk ltre egy szekvenciaobjektumot:
Ha megnyitjuk a tulajdonsglapjt, lthatjuk, hogy ez egy mi ez, s mi mindent llthattunk volna be rajta ltrehozskor.
73
Egyrszt be tudtuk volna lltani az adattpust mondjuk INT-re, merthogy most BIGINT. Msrszt bellthattunk volna neki egy kezdeti rtket, mert a mnusz vgtelenbl jn majd fel. Ami egybknt nem baj, hisz hatszz oldallal korban megegyeztnk, hogy az a j azonost, amelyiknek nincs sajt rtelme, akkor viszont mirt ne lenne j a -9223372036854775808? Be lehet lltani a nvekmnyt, a tlig hatrokat valamint a gyorsttrazst. Ez utbbi arra szolgl, hogy a szekvencia ne szaladgljon mindig a merevlemezhez, ha valaki j azonostt kr tle, hanem memribl adjon neki egyet. Egy INT tpus, egytl indul, egyesvel nveked szekvencia ltrehozsa gy nz ki:
74
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Az gy krt rtkek most elvesznek, mert nem csinlunk velk semmit. Egy INSERT-be gy tehetnnk be:
8.3
A kvetkez adatmdostsi utastsunk a DELETE. Azrt ezt vlasztottam, mert ez is, akrcsak az INSERT, komplett sorokkal dolgozik, merthogy fl sort trlni nem lehet. A DELETE az az utasts, amivel a rutintalan adatbzisgazda egyszer s mindenkorra megszabadul a vevtrzstl, mert elfelejtett WHERE felttelt rni a trlshez. Merthogy az alap szintaxis mindent visz az adott tblbl:
17
Kivve azt az esetet, amikor valaki bekapcsolja a vzessmveleteket az idegen kulcson, vagy jmagyarul: a kaszkdolst belltja a foreign keyen.
75
DELETE FROM Transactions FROM Transactions t JOIN Accounts a ON t.AccountID=a.AccountID JOIN Customers c ON a.CustomerID=c.CustomerID WHERE FirstName='Jakab'
A DELETE-utastsnak is van OUTPUT kulcsszava, ha esetleg valaki el akarja kapni, hogy miket is trlt pontosan. A msodik FROM el kell berni, valahogy gy:
DELETE FROM Transactions OUTPUT DELETED.* FROM Transactions t JOIN Accounts a ON t.AccountID=a.AccountID JOIN Customers c ON a.CustomerID=c.CustomerID WHERE FirstName='Jakab'
8.4
A mesterhrmas utols tagja az UPDATE, mely lehetv teszi sorok, azon bell pedig egyedi mezk mdostst. Alapkiptsben gy nz ki, ppen tnevezem Gipsz Jakabot K Elemrre:
76
UPDATE Transactions SET Amount=Amount*1.1 FROM Transactions t JOIN Accounts a ON t.AccountID=a.AccountID JOIN Customers c ON a.CustomerID=c.CustomerID JOIN Cities cc ON c.CityID=cc.CityID WHERE Name='Piripcs'
s ha mg a szoksos OUTPUT kulcsszval is felszereljk, mindent fog tudni. Korbban emltettem, hogy az UPDATE-nek kt memriatblja van, az eltte (DELETED) s az utna (INSERTED) tblk.
UPDATE Transactions SET Amount=Amount*1.1 OUTPUT DELETED.*, INSERTED.* FROM Transactions t JOIN Accounts a ON t.AccountID=a.AccountID JOIN Customers c ON a.CustomerID=c.CustomerID JOIN Cities cc ON c.CityID=cc.CityID WHERE Name='Piripcs'
Ha valaki szeretne rmisztt ltni, nzze meg ennek az utastsnak a vgrehajtsi tervt! Ersen kilg a kpernyrl!
8.5
TRUNCATE
Az adatmdost utastsok kz tartozik, gy a teljessg ignye rdekben megemltem a mi adatbzisunkban egybknt hasznlhatatlan gyorstrlst, a TRUNCATE-t. Abban klnbzik a DELETE-tl, hogy nincs WHERE-felttele, teht mindig mindent visz. Radsul a mveletrl naplbejegyzs sem kszl (lsd nhny bekezdssel lejjebb), gy gyors, mint a villm. Csak az az egy baja van, hogy nem lehet hasznlni olyan tblkon, amelyikre idegen kulcs mutat. s melyikre nem mutat?
8.6
Tranzakcinaplzs
Biztosan van az olvask kztt olyan, aki mg emlkszik a DBase/Clipperes vilgra (Clipper Summer 87!), s ha gy van, taln az is beugrik, hogy a Clipperes alkalmazsokban elkel helyet foglalt el a sztesett adatbzis helyrepofozsa vagy valami hasonl elnevezs menpont. Azok az adatbziskezelk rendszeresen maguk al csinltak. Vajon az SQL Serverrel nem fordulhat el ugyanez? Elmletileg igen, gyakorlatilag nem.
77
ADATKEZELS OTTHON S A FELHBEN Clipperknl az volt a baj, hogy minden mdosts sz nlkl nekiesett az les adatbzisnak, aztn ha a takart nni kirgta a kbelt, akkor a mdosts szpen flbemaradt. Az SQL Server gy vdekezik az ramkimaradsbl s egyb katasztrfkbl szrmaz adatvesztsek ellen, hogy soha, de soha nem rja egyenesen az les adatterletet, hanem ehelyett minden mdostsi mveletet az gynevezett tranzakcinapl fjlban rgzt, s ha ez sikerrel zrul, akkor fog nekiesni az les adatoknak. De ekkor mr nincs veszly, mert mg ha az ttermels flbe is marad, van egy 100%-ban lert vltozat a naplban, ami alapjn a megszakadt rsi mveletet folytatni lehet. Ha a naplrs flbeszakad, annyi baj legyen, az les adatterlet nem mdosult, a log meg csak log, van benne egy kis szemt s ksz. Ha azonban a naplrs sikeres, elbb-utbb az les adatterletre is tvezetsre kerl a mdosts, akrhogy kapldzik ellene a partvissal a takartn. gy is mondhatjuk, hogy az SQL Server mindent ktszer r, ktszer r. Ami persze teljestmnyvesztesggel jrna, ha a msodik rst is megvrnnk, mieltt az rs eredmnyt a felhasznlk lthatnk. De igazbl mr a naplrs sikeres lezrulsa utn elrhet az j adat, mert az SQL Server trkkzik az adatokkal a memriban. A mdostsok els fzisban, amikor a naplrs trtnik, akkor van bent a boszorkny a konyhjban, s a naplba irkafirkl. Ebbe ekkor mg senki nem lthat bele. Amint azonban a mdosts a naplban sikerrel zrult, a memriban azonnal az j vltozat lesz olvashat mindenki szmra, mg az les adatterlet fellrsa szp csendben megtrtnik a httrben. Hol rdekel ez minket?
8.7
Ht ott, hogy mr ltjuk, vannak bizonyos munkaegysgek, amelyek vagy egy az egyben megtrtnnek, vagy egyltaln nem. Flbehagys esetn nem trtnik vltozs az eredeti adatokon. Ezt a munkaegysget hvjuk tranzakcinak, s az SQL Server adatbzisok rsakor az az alaprtelmezett mkds, hogy a tranzakcikat elsknt a tranzakcinapl fjlba rjuk, s ha ott vgleges de most nmagamat ismtlem. Ezzel vertk agyon a DBase/Clipper hegemnit (no meg az adatbzismotorral). Szval van ez a bizonyos munkaegysg, a tranzakci. Amirl azrt rdemes tudni, mert br automatikusan mkdik az egyes adatmdost utastsokra (implicit tranzakci), valjban mi magunk is hasznt vehetjk ennek a mkdsnek azltal, hogy ssze tudunk fogni egy sereg egymssal sszefgg mdostst, s azt tudjuk krni az SQL Servertl, hogy ezeket lcci-lcci vagy egy az egyben csinld meg, vagy ha flbeszakad a mvelet, akkor trld, mintha semmit sem csinltunk volna. Teht ha lerunk egy akrmilyen adatmdost utastst, akkor ott lefut, s sikeresen zrdik is egy tranzakci? Igen, gy van. Minden egyes adatmdost utasts a httrben valjban gy fut le:
78
Csak ppen a BEGIN TRAN, COMMIT TRAN utastsokat nem kell kirni, azok alaprtelmezs szerint vannak. Implicite. Ha finoman szeretnnk szablyozni a tranzakcik elejt s vgt, akkor ki kell rnunk, s ez a mdja annak, hogy sok-sok utastst egy csomagba fogjunk ssze. Vegyk az albbi kereskedelmi szitucit:
BEGIN TRAN INSERT Szamlatetel(...) VALUES(...) UPDATE Raktarkeszlet SET Mennyiseg=Mennyiseg-1 WHERE... COMMIT TRAN
s ez mr valdi amg a vonat az llomson tartzkodik letrzs!
8.8
A nagyon okos adatbzisguruk azt szoktk mondani a tranzakcikrl, hogy savasak (ACID). Ez a kvetkez dolgokat jelenti a gyakorlatban:
79
ADATKEZELS OTTHON S A FELHBEN Atomic. Egy tranzakci attl atomi, hogy egy s oszthatatlan. A benne foglalt utastsok egytt rnek clba, vagy egytt hullanak a srba. Consistency. A konzisztencia itt azt jelenti, hogy a tranzakci az adatbzist egy korbbi, rvnyes llapotbl egy j, de szintn rvnyes, nellentmondsmentes llapotba viszi. Vagyis nem hagy flbehagyott alkatrszeket maga utn. Isolation. Az elzrtsg a boszorknykonyhra utal. Amg kotyvasztunk, addig abba msnak semmi beleszlni, beleszagolnivalja nincs. ket csak a ksztermk rdekelje! Durable. Tartssg. Ami megtrtnt, megtrtnt. Ami COMMIT paranccsal zrult, az kivtel nlkl vgleges mdosts.
8.9
Fentebb mr lttuk, hogyan lehet egy tranzakcit kzzel indtani (BEGIN TRAN), illetve sikeresen lezrni (COMMIT). Van azonban a sikertelen lezrsnak is hivatalos tja, ez pedig a ROLLBACK TRAN. Ha egy utastssorozat kells kzepn kiderl, hogy a tranzakci vglegestsnek felttelei nem adottak, mert mondjuk res a raktr, vagy pp piros h esik, a tranzakci kinyrhatja nmagt egy gyesen elhelyezett ROLLBACK utastssal. Ha valaki alaposan ismeri a tranzakcik bels feldolgozst, akkor ilyet nem csinl, mert a ROLLBACK iszony kltsges mvelet18. Az explicit tranzakcik kapcsn mg egy fontos tnyez a tranzakcik egymsba gyazsa. Ha egy BEGIN TRAN-ban elindtok egy BEGIN TRAN-t, akkor mr kt tranzakci dbrg egymsban, s ezeket ltszlag kln vissza tudom vonni, ha akarom. A valsg azonban ms. Az albbi kdrszlet rvilgt a valdi mkdsre, ahol a @@TRANCOUNT globlis vltoz mindig megmutatja, ppen hny tranzakci kupacoldott egymsra:
BEGIN TRAN SELECT @@TRANCOUNT --Egy BEGIN TRAN SELECT @@TRANCOUNT --Kett ROLLBACK SELECT @@TRANCOUNT --Nulla
Mint az lthat, egy darab ROLLBACK kinyrta mindkt tranzakcit. Egy nyisszantssal elvgta a torkukat. Ez gy mkdik, erre gy kell szmtani19. Ne menjenek el, a tranzakcik mkdsnek lveboncolst a msodik tuningfejezettel folytatjuk.
18
Merthogy technikailag ilyenkor nem az n tranzakcim grdl vissza, hanem az ltalam rintett 8k-s lapon mindegyik rekord idutazst szenved vissza a mltba, majd rajtam kvl mindenki ms elregurul, n meg gy maradok. Ebbl mr rthet, hogy minl tbben dolgoznak prhuzamosan, a ROLLBACK annl szrnybb teljestmnyt nyjt. 19 Geekeknek: igen, lehet ezzel mg tovbb knldni, SAVE TRAN meg ilyenek, de azt amgy a kutya sem hasznlja. Mert senki nem rti.
80
Az egyik legszebb teljestmnytuningols feladat, amivel szaki szembekerlhet, az ll SQL Server, melyen minden folyamat beragadt. A telefonok csrgnek, nem lehet szmlzni, ugyanakkor a processzorterheltsg 0%, a memria res, a hlzat csendes, a merevlemez nem forog. Na, ilyenkor mi a teend? Sok olyan cggel tallkozunk, ahol ebben a nyilvnval helyzetben vesznek egy nagyobb vasat. Az igaz, hogy az elz sem volt leterhelve, de ht llt az alkalmazs, nem? Akkor er kell al! Az egyik Kedves Vevnk odig fajult, hogy hrom hullmban vett nagyobb gpeket, mire elgondolkodott a jelensgen, s hozzrt tancst krte. Ha laborkrlmnyek kztt el tudnnk lltani ilyen helyzetet, knnyebben megrtennk, mi is zajlik ilyen esetben az SQL Server lelkben. J hrem van, el tudunk lltani, mgpedig igen knnyedn!
9.1
A most kvetkez ksrletekhez kt egyidej kapcsolatra lesz szksgnk. Nyissunk meg kt lekrdezablakot, majd zlsesen rendezzk ket egyms mell a Window/New Vertial Tab Group menpont segtsgvel! Valami ilyesmit kell ltnunk:
81
Ez a kt ablak fogja reprezentlni a sokezer prhuzamos kapcsolatot. A bal oldaliba rjuk be az albbi flksz tranzakcit, majd futtassuk le:
A lekrdezs teljestmnye nmi kvnnivalt hagy maga utn, noha csak egy tsoros tbln dolgozik. Jhet a mricskls, vajon mi kevs, s kiderl, hogy semmi sem kevs. Itt egy tipikus zrolsi problmval llunk szemben, a banya nem kompatibilis a hallal. Szakmai nyelven szlva a bal oldali tranzakci ltal a tbln (?) elhelyezett kizrlagos zr (exclusive lock) megakadlyozza, hogy az olvasst vgz mveletek flksz adatokat olvassanak. I, mint izolci. (ACID) Meddig ll fenn ez az llapot? Ameddig a bal oldali tranzakci vget nem r. Lehet, hogy ez rkig tart? Lehet. Lehet, hogy percekig? Az is lehet. s hnyszorosra gyorstja az a guru az alkalmazst, aki megsznteti a zrolsi tkzst? Akr vgtelenszeresre. Most persze mondhatnnk, hogy ilyen a valsgban nincs. Egyrszt igenis van, lteznek ennyire idita alkalmazsok, msrszt ez a ksrlet csupn modellezi, hogy mi trtnik, ha sok tzezer, egyenknt milliszekundumos tranzakci fekszik egy lekrdezs tjba. Ugyanez trtnik. Mirt nem lt egyetlen sort sem a lekrdezs, noha a tranzakci csupn egy sort mdost? Nos, azrt nem, mert az indexelsnk j ugyan, de iciri-piciri a tbla, ezrt pontosan ugyanazokrt a sorokrt
82
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA versengnk. les krnyezetben, sok adattal s sok felhasznlval azt ltnnk, hogy a lekrdezs dcgve fut le, de lefut. Meg-megakad az ppen mdostott sorok eltt, s teljesen kiszmthatatlan, mennyi id alatt r vget, de vgl csak lefut. A jelensg alaposabb megismershez a zrolsi rendszer ismerete visz kzelebb. Van egy j reg trolt eljrs, amit n a zrak kilistzsra hasznlok 1873 ta, gy hvjk, sp_lock. Tudom, van ennl modernebb dm ugyanennek a lekrdezsre, de az sp_lock olyan kis kompakt tblzatot tr elnk, hogy nem tudok leszokni rla. A bal oldai ablakunk l, ott futtassuk le!
tvenketteske s tvenhrmaska dolgozik vadul. A tblzatbl kiolvashat, hogy mindketten a hatos szm adatbzisban vannak fervel (ez az n Bank adatbzisom), emellett tvenhrmaska a Masterben is kavar valamit (egyes adatbzis), de ezt most nem elemezzk. Az Objid oszlop is elgg egysk, ami arra vall, hogy ugyanazt az objektumot macerljk, ami valjban a Cities tbla. A legutols oszlopban pedig ltszik a sok GRANT kztt egy WAIT. tvenketteske vrakozik egy S (Shared, technikailag Select) tpus zrra a SELECT megkezdshez az a2dce kezdet soron, de ugyanezen ll tvenhrmaska is, neki pedig egy X (exclusive) zrja van ugyanerre. A jelensget megnzhetjk az Activity Monitorban is.
83
Mit lehet ilyenkor tenni? Az Activity Monitorral pldul ki lehet lni a Head Blockert (=fbns), de akkor az tranzakcija megsemmisl. Valamint ki lehet vrni, hogy ez az igencsak hosszra nylt tranzakci befejezdjn. Adjunk ki a bal panelen egy ROLLBACK utastst, mire a jobb panel ott helyben megtltosodik. A naiv megkzeltsek (mg tbb RAM, mg tbb processzor) ebben az esetben nem vezetnek eredmnyre. Ez az alkalmazs kukra val. De azzal egytt is, hogy szemtre val, lehet, hogy csak ez jutott neknk, nincs cserelehetsg, teht tovbb kell nyomulnunk az esetleges megolds fel.
9.2
sszeakadgat alkalmazsok ellen tbbfle gygyr is alkalmazhat. A hagyomnyos megkzeltssel kezdjk, s onnan haladunk az ultraszuper megoldsok fel. Az els megkzelts lnyege, hogy benznk a boszorknykonyhba. Egyszeren beleolvasunk abba, ami mg ksz sincsen. s mivel nincs kszen, s lehet, hogy soha nem is lesz, ezt a technikt szemtolvassnak (dirty read) hvjk. Az eljrs lnyege, hogy a SELECT-nl felvesznk egy olyan optimizer hintet, ami a zrak figyelmen kvl hagysra sztnzi a lekrdezst.
84
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Ez szp s j (illetve rossz s csnya, nzpont krdse), de ha ezt minden dcgs lekrdezsbe bele kell rni, abba belehalunk. Nem beszlve azokrl a lekrdezsekrl, amelyek bele vannak getve a BANK.EXE-be, azokat hogyan rjuk t? Sehogy. De nem baj, van msiiik! Ugyanezt a hatst elrhetjk a kapcsolat izolcis szintjnek megvltoztatsval, anlkl, hogy a lekrdezst mdostanunk kellene.
20
85
10 Programozs
Mind ez ideig halmazokkal dolgoztunk, akr lekrdezsekrl, akr adatmdostsrl volt sz. A TSQLnyelv azonban ismeri a programozs fogalmt is, s bizony nem nehz olyan feladatba belefutni, ahol szksg lenne a lpsenknti futtatsra, ciklusra, elgazsra, vltozkra. Elg, ha valamilyen bonyolultabb zleti logikra gondolunk, amelyet nem lehet egy SELECT utastsban megvalstani, s mris a programozsnl vagyunk. Emellett ide tartozik az SQL terminolgija szerint minden trolt eljrs, fggvny s sok minden ms, amelyek az adatbzisunkban a Programmability gban cscslnek a fn.
10.1 Vltozk
A FLOAT-os vgtelen ciklusnl hasznltunk mr vltozt, gy most csak hivataloss teszem a megtrtnt esemnyeket. A vltozkat DECLARE kulcsszval vezetjk be, nevk eltt @ (kukac) karakter ll, adattpusukat tekintve pedig az sszes korbban felsorolt adattpust felvehetik, st tbbet, mert lehet kszteni tbla tpus vltozt is. Tipikus felhasznlsi terletk a ciklusvltoz, vagy valamilyen ms tmeneti adat trolsa, s szerepelhetnek fggvnyekben, trolt eljrsokban s sima scrpitekben. Mivel a hagyomnyos vltozk ltrehozsnak ponjt sok-sok oldallal korbban lelttem, itt s most egy tblatpus vltozt hozok ltre, adatok tmeneti trolsra.
DECLARE @t TABLE( ID INT PRIMARY KEY IDENTITY NOT NULL, Name NVARCHAR(88), BirthDate DATETIMEOFFSET NOT NULL DEFAULT '1999.11.11' )
Mint lthat, nem rdngssg, sima kvetkeztets segtsgvel ki lehet tallni a szintaxist, mivel megegyezik a CREATE TABLE szintaxisval. A deklarlst kveten pedig gy lehet hasznlni, mint egy tblt, melynek neve @t.
86
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Van egy msik hasonl konstrukci, az tmeneti (temp) tbla, ami ugyanez, de mgis ms. nem kukaccal kezddik, hanem sznyeggel (#), s nem deklarljuk, hanem CREATE TABLE kell hozz, s nem fstl el magtl a script vgn, hanem DROP TABLE utastssal kell ledobni. Ezek a szemmel lthat klnbsgek. me ugyanez a feladat temptblval:
CREATE TABLE #t( ID INT PRIMARY KEY IDENTITY NOT NULL, Name NVARCHAR(88), BirthDate DATETIMEOFFSET NOT NULL DEFAULT '1999.11.11' )
A vlasztst megknnyti, ha tudjuk, hogy - ha lehet ilyet mondani - a temptbla tblbb a tblatpus vltoznl. A temptbla pldul tranzakcionlt, indexelhet, s nagy adatmennyisgeknl sebessgtesztekben veri a tblatpus vltozt. A tblavltoz meg kicsi s gyes. Meg kell emltennk mg a globlis vltozkat, melyek neve kt kukaccal kezddik (@@), van a rendszerben vagy negyven ilyen (pldul @@TRANCOUNT), de mi magunk nem tudunk globlis vltozt ltrehozni. Aki azt lltja, ltre tud hozni globlis vltozt, mert berja a neve el a kt kukacot, s ksz, azoknak tetszeni fog ez a plda, mert n akkor ezek szerint csinltam nagyongloblis s hipergloblis vltozkat.
DECLARE @i INT SET @i=1000000 WHILE @i>0 BEGIN SET @i=@i-1 INSERT ... END
87
ADATKEZELS OTTHON S A FELHBEN Elgazsbl pedig itt van neknk a csacsi, reg IF, aki minden informatikusnak a knykn jn ki. Egy gyors plda a teljessg kedvrt, ennl rtelmesebb pldt majd a trolt eljrsoknl hasznlunk:
DECLARE @i INT SET @i=1000000 IF @i=1000000 BEGIN PRINT 'Egymilli' END ELSE BEGIN PRINT 'Nem egymilli' END
A CASE utasts mr rdekesebb. Merthogy ez nem csupn az, mint amire emlkszel a Commodore 64 BASIC alapjn. Ez nemcsak egy elgazs (br az is tud lenni), hanem kifejezsek helyn szerepelhet SQL-utastsokban, gy alkalmas pldul arra, hogy 0/1 rtkeket rptben kicserljen Frfi/Nre. Micimackval eljtszva ugyanezt
DECLARE @t TABLE( ID INT PRIMARY KEY IDENTITY NOT NULL, Name NVARCHAR(88), BirthDate DATETIMEOFFSET NOT NULL DEFAULT '1999.11.11', Female BIT ) INSERT @t(Name, BirthDate) VALUES('Micimack', '1926.04.17') SELECT Name, CASE Female WHEN 0 THEN 'Frfi' WHEN 1 THEN 'N' ELSE 'Plss' END AS Sex FROM @t
Nos, hsnk a plssllat nembe tartozik, mivel a nemi krdst egy nullozhat bitben oldottam meg, s nem tltttem ki az INSERT-nl, teht se nem 0, se nem 1.
88
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Szval gyors. Nagyon gyors. Lehet. (Ha az indexelssel s csillagos ts lekrdezsekkel al nem vgunk.) A trolt eljrs tetszleges szm Transact SQL utastst s tetszlegesen bonyolult kdot tartalmazhat. Meghvsakor bemeneti paramtereket adhatunk t neki, amit gyesen feldolgoz. Adatot visszajuttatni pedig a kvetkez mdokon tud (orrn-szjn): Szerepelhet benne SELECT, aminek az eredmnye a hv oldaln szpen felbukkan. Egynl tbb SELECT esetn egynl tbb eredmnyhalmazt kapunk, csak gyzzk feldolgozni! Van neki visszatrsi rtke, ami ugyan csak egy INT, de akkor is, egsz szmokkal jl lehet zengetni a hvnak. Tud cm szerinti paramtertadst, ami azt jelenti, hogy a bemeneti paramtereit trva a hvnl is megvltoznak az eredeti rtkek.
Paramterezhetsgvel megszgyenti a nzeteket, amelyeknl erre nincs lehetsg, azok csupn tblk, WHERE-felttellel. A paramterezhetsg egyben csapda is, a Programoz Legnagyobb Tvedsei gyjtemnybe val, mert ha valaki egy bemeneti paramterrel , inkbb lssunk egy pldt! Egy ROSSZ, de elterjedt pldt. Az albbi BETEG trolt eljrs a bemen paramternek fggvnyben vagy trl a Customers tblbl, vagy mdost a rekordon. A lusta programoz egyetlen trolt eljrssal szeretne minden funkcit megoldani egy tbln.
CREATE PROCEDURE CustomerDelMod @CustomerID INT, @Method INT, @LastName NVARCHAR(88) AS IF @Method=1 BEGIN DELETE Customers WHERE CustomerID=@CustomerID END ELSE BEGIN UPDATE Customers SET LastName=@Lastname WHERE CustomerID=@CustomerID END
A ksz trolt eljrs becscsl a fba:
A @Method bemeneti paramter vltoztatsval lehet a futst az egyik vagy a msik gra terelni. Ez a trolt eljrs akkora katasztrfa, hogy meg sem mutatom, hogyan kell meghvni, htha akkor nem rja meg gy senki. A hiba oka nem az, hogy a benne lv logika ne lenne j, mert az hibtlan. mde
89
ADATKEZELS OTTHON S A FELHBEN fentebb megllaptottuk, hogy a trolt eljrs az els futsakor rtkeldik ki, s kszl hozz vgrehajtsi terv s kd, ami bent marad a memriban, ksbbi futtats cljra. Igen m, de ha az els hvskor mondjuk trlnk, akkor a trlsre vonatkoz vgrehajtsi terv kszl s memorizldik, amellyel taln lehet sorokat mdostani is, de hogy milyen teljestmnnyel, azt jobb nem firtatni. Na j, csak elrulom, hogyan lehet megmenteni az ilyen hatlvet trolt eljrsokat. Egyszer! Csak el kell vetni a trolt eljrs legfbb elnyt, az elmentett vgrehajtsi tervet! Ha minden hvsnl mindig lefordtjuk, nincs kesselsi problma. Van viszont sok-sok fordtsunk, teht vgl ezzel a megoldssal nem nyernk semmit. A sima hvs gy fest:
CREATE PROCEDURE Evszak @Be DATETIME AS DECLARE @Honap INT SET @Honap=DATEPART(MONTH, @Be) IF @Honap>5 AND @Honap<9 BEGIN PRINT 'Nyr' RETURN 55 END IF @Honap<3 OR @Honap>10 BEGIN PRINT 'Tl' RETURN -77 END
90
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA TSQL-scriptbl a visszatrsi rtk kinyerse nem trivilis, el kell nyeletnnk egy INT tpus vltozval, amivel mr azt csinlunk, amit akarunk. Ugyanez egy kliensprogramban csupn a @RETURN vagy @RETURN_VALUE nev bemeneti (merthogy a paramterek kztt talljuk) paramter kiolvasst jelenti. TSQL-megolds a problmra:
91
ADATKEZELS OTTHON S A FELHBEN Most pedig ksztsnk valami komoly trolt eljrst a bankunkhoz! Egy olyan funkcit szemeltem ki, amit viszonylag ritkn, de kvetkezetesen s automatikusan kell lefuttatni, ez pedig a havi kamatszmts. Nagyon fontos ennl az eljrsnl, hogy valahogyan naplzni kell, kinek csinltuk mr meg a kamatszmtst s jvrst, hogy a folyamat a sokmilli gyfelnknl tetszleges ponton megszakthat, s adatveszts, valamint kamatnyeresg nlkl folytathat legyen. Ez a naplzs nem a tranzakcinaplt jelenti, hanem egy alkalmazsszint, ltalunk kezelt tblt, amiben vezetjk, hogy kinek, mikor, melyik szmljn szmoltuk ki a kamatot. Magt az sszeget pedig visszavezetjk az gyfl szmljra. Ha naplzs, akkor kzi tranzakcira is szksgnk lesz, mert micsoda naplzs az, amikor megcsinlom a kamatszmtst, jvrom az gyflnl a nyeresget, de a naplmba nem rom be? Dupla haszon az gyflnl, ami megengedhetetlen. Azt is elrebocstom, hogy lttam n mr hasonl trolt eljrst lben, s nem hrom paramtere volt, hanem tven. Aki esetleg gy gondolja, hogy az itt kvetkez trolt eljrs nem felel meg a valsg kvetelmnyeinek, annak sajnlattal bevallom, hogy igen, nem. Nem felel meg. De mg ez a leegyszerstett eljrs is olyan hossz lesz, hogy kivtelesen soronknt fogom kommentlni, elmagyarzni, hogy mi is trtnik pontosan. Elsknt megtervezzk s ltrehozzuk azt a tblt, amelyben vezetni fogjuk, hogy kinek, melyik szmljn, melyik idszakra szmoltunk ki kamatot. Ezzel nagyjbl ssze is foglaltam, milyen mezk kellenek bele. A CustomerID pldul nem, mert a szmlk egyrtelmen megmutatjk, kihez tartoznak. Az AccountID igen, valamint egy tlig dtumhatr. valahogy gy:
CREATE TABLE AccountInterestLog ( AccountInterestID INT PRIMARY KEY IDENTITY NOT NULL, AccountID INT FOREIGN KEY REFERENCES Accounts(AccountID), PeriodStart DATE NOT NULL, PeriodEnd DATE NOT NULL )
Ezt kveten jhet a trolt eljrs, melyet felksztnk tmeges kamatszmtsra. Ennek az lesz a mdja, hogy az a bemeneti paramtere, amelyik meghatrozza, kiken szmtson kamatot, tblatpus lesz, gy egynl tbb elemet, st rengeteget is tartalmazhat. A tblatpus azt is lehetv teszi, hogy egyedi kamatfeltteleket llaptsunk meg minden egyes gyflnek, hisz a bemeneti tblnak lehet tbb oszlopa. Ezzel a lpssel outsource-oljuk a kamatszintet, lltsa be a hv, hisz egy bankban ltalban sok tzezer paramtert vesznek figyelembe az adott szmla, adott gyfl, adott lekts aktulis kamatszintjnek meghatrozsnl. Trolt eljrsnl sajnos nem lehet rptben megadni a tblatpust, hanem elszr ltre kell azt hoznunk a CREATE TYPE utastssal, gy: CREATE TYPE AccountInterest AS TABLE(AccountID INT, InterestRate MONEY) Ritka eset, amikor sajt adattpussal ajndkozzuk meg magunkat, s lm, e komoly problma kapcsn pont belefutottunk egy ilyenbe. Itt cscsl a tblatpusunk:
92
Ezenfell megadunk kt dtumparamtert, ami azt hivatott ellenrizni, hogy ktszer ne lpjnk ugyanabba a folyba, amin mr elszmoltunk kamatot, azon most ne tegyk. sszessgben gy fest a trolt eljrs fejlce:
CREATE PROCEDURE InterestCalculator @Interests AccountInterest READONLY, @PeriodStart Date, @PeriodEnd Date AS
Itt az eddigiekhez kpest a READONLY szcska az egyetlen ismeretlen dolog, azt sem kell megrteni, csak be kell rni, ha tblartk bemeneti paramternk van, enlkl ugyanis hibazenetet kapunk. Ktelez orvossg. Az els utastsunk mindjrt egy erteljes BEGIN TRAN legyen, hogy brmi, amit csinlunk, ACID legyen, vagy egy az egyben trtnjen meg, vagy egyltaln ne!
BEGIN TRAN
Ezt kveten elllthatunk egy lepedt a bejv paramterek ltal meghatrozott szmlkon, melyben mr a kiszmtott kamat is benne van. Ez egy j nagy, ngytbls lekrdezs lesz, mert szksgnk lesz az Accountsra, a Transactionsra, a bemen tblavltozra, valamint az imnt ltrehozott napltblra. Ez utbbira oly mdon, hogy akkor van tallat, ha nincs tallat, vagyis mg nem csinltuk meg az adott kamatszmtst (OUTER JOIN). A lepedt megvalst lekrdezs gy nz ki: SELECT a.AccountID, Currency, SUM(Amount * i.InterestRate) as Interest
FROM Accounts a JOIN Transactions t ON a.AccountID=t.AccountID JOIN @Interests i ON a.AccountID=i.AccountID LEFT OUTER JOIN AccountInterestLog al ON a.AccountID=al.AccountID AND (a.CreationDate < @PeriodStart OR a.CreationDate > @PeriodEnd) WHERE al.AccountID IS NULL GROUP BY a.AccountID, Currency
Trkks! Figyeljk meg, hogy a dtumhatrokat nem a WHERE-felttelben adtam meg, hanem az utols, LEFT OUTER JOIN-hoz rtam hozz! Ennek kvetkeztben a dtumvlaszts is a JOIN-felttel
93
ADATKEZELS OTTHON S A FELHBEN rsze lett, gy ezekre is hat az OUTER JOIN, noha a vizsglt vltozk nem is a tblkban vannak, hanem bemeneti paramterek (@PeriodStart s @PeriodEnd). Ezzel a trkkel rtem el, hogy az OUTER JOIN legenerlja azokat a sorokat, amihez nincs AccountInterestLog az adott dtumhatrokon bell. Hogyan ksztsnk sorokat nemltez adatok alapjn? OUTER JOIN-nal! O.J. a nagy nullgenertor! Vgl neknk pont azok a sorok kellenek, ahol az AccountInterestLog tbla csupa NULL, a tbbit gy kivgom a WHERE-rsznl, mintha ott sem lett volna. Ha valakinek ez a trkks JOIN megfekdte a gyomrt, ne bsuljon, valsznleg SQL-es plyafutsom els tz vben nem tudtam volna egy lpsben lerni ezt a lekrdezst. Emellett egy csnya egyszerstssel az sszes tranzakcira (tartozik, kvetel des mindegy) pnznemenknt egy GROUP BY segtsgvel hibsan kiszmtjuk az adott idszakra vonatkoz kamatot. A hiba az, hogy nem vesszk figyelembe, az adott periduson bell mikor kerlt oda az a pnz, tovbb az aktulis egyenleggel sem trdnk, mert mg nem tartunk a triggereknl. A mi bankunkban nem kapsz kamatot azrt, ha ott trolod a pnzedet, ellenben buss, flreszmtott kamatot kapsz minden tranzakcirt, amelyet a periduson bell brmikor vgzel. Reklm: Helyezze el bettjt nlunk a kamatszmtst megelz msodpercben, majd vegye ki egy perccel ksbb, s mi bussan megjutalmazzuk ezrt! Ha valaki azt kveteli, csinljuk mr meg teljesen hibtlanul, az egyben azt is kveteli, hogy legyen ez a knyv dupla ilyen vastag, a pldk pedig legyenek tszr ekkork, oldalakon keresztl csak kd, kd s kd. Nem gy lesz. A hibinkkal egytt fogunk lni. Tudunk rluk. A leped alapjn kiszmtott rtkekre tbbszr is szksgnk lesz, mivel egyrszt jvrjuk a kamatokat az gyfeleknl, msrszt naplzzuk, hogy ki kapott kamatot, gy az adatokat beleirnytjuk egy tblavltozba, hogy meglegyen mindkt lpshez.
INSERT AccountInterestLog(AccountID, PeriodStart, PeriodEnd) SELECT DISTINCT AccountID, @PeriodStart, @PeriodEnd from @t
94
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Nagyjbl kszen is vagyunk, mg kell egy COMMIT.
COMMIT
Hogy meglegyen egyben is, itt a teljes trol eljrs mindenenestl:
CREATE PROCEDURE InterestCalculator @Interests AccountInterest READONLY, @PeriodStart Date, @PeriodEnd Date AS BEGIN TRAN DECLARE @t TABLE( AccountID INT, Currency CHAR(3), Interest MONEY ) INSERT @t SELECT a.AccountID, Currency, SUM(Amount * i.InterestRate) as Interest FROM Accounts a JOIN Transactions t ON a.AccountID=t.AccountID JOIN @Interests i ON a.AccountID=i.AccountID LEFT OUTER JOIN AccountInterestLog al ON a.AccountID=al.AccountID AND (a.CreationDate < @PeriodStart OR a.CreationDate > @PeriodEnd) WHERE al.AccountID IS NULL GROUP BY a.AccountID, Currency INSERT Transactions(AccountID, Currency, Amount, Partner) SELECT *, 'Idszakos kamat' FROM @t INSERT AccountInterestLog(AccountID, PeriodStart, PeriodEnd) SELECT DISTINCT AccountID, @PeriodStart, @PeriodEnd from @t COMMIT
Ha belegondolunk, hogy minden mveletet simn befedtnk egy-egy nem tl bonyolult SQLutastssal, azt kell mondjuk, az SQL-nyelvnl nincs hatkonyabb a vilgon. Szinte alig rtunk kdot. Szrstl-brstl, szmtsostul, hibakezelsestl, naplzsostul mindent meg tudtunk csinlni 8-10 utastssal! A hatodik hangszr az, aki megmondja, mirt rossz ez az egsz gy, ahogy van, termszetesen az eddig beismert hibkon fell. Vrok! Senki? Akkor elmondom. gyse lett volna j az a hatodik hangszr semmire sem. Tbbfelhasznls krnyezetben simn el tudunk indtani egymssal prhuzamosan ugyanarra a peridusra, ugyanazokra a bankszmlkra szinte akrhny kamatszmtst, s mindegyik nllan, autonm
95
ADATKEZELS OTTHON S A FELHBEN mdon szpen kiszmtja, hozzadja a kamatot, majd tisztessgesen naplz is. Mi meg csak nznk ki a fejnkbl, hogyan futhatott ez le tszr. Ht krem gy, hogy egyszerre. Nem mindig rm, ha valami nmagval prhuzamosan, sokszorosan le tud futni. Az a lps a hibs, amikor kivlasztjuk a nem naplzott Accountokat, mert ezt akrhny prhuzamos lekrdezs meg tudja tenni. Ez olyan eljrs, amelyiknl elejt kellene venni annak, hogy nmagval prhuzamosan fusson. Erre egy OPTIMIZER HINT-et vethetnk be. Egy jl irnyzott kizrlagos zrral (Exclusive Lock) elejt vehetjk a trolt eljrsunk prhuzamos futtatsnak. Soros feldolgozsv tehetjk a trolt eljrsunkat, ha az AccountInterestLog tblanv mg berjuk, hogy
96
10.5 Trigger
A trolt eljrsok egy msik tpusa a trigger, melyet a fenti pldtl eltren nem mi hvunk meg, hanem az SQL Server. Triggert ugyanis bizonyos esemnyekre rakhatunk, amelyek az esemny bekvetkeztekor automatikusan lefutnak. Ha automatikusan futnak le, abbl az kvetkezik, hogy a triggereknek nincs bemen paramterk, mert nincs, aki kitltse azokat. s mivel a httrben, rejtetten futnak, nem igazn j tlet adatokat visszaadniuk futs kzben (pl. SELECT, RETURN), mert erre nem szmt senki. Triggert egyrszt tranzakcis tblamveletekre lehet illeszteni (INSERT, UPDATE, DELETE), msrszt az SQL Serverben szerverszinten elkpeszten sok mindenre, loginok ltrehozsra, tbla mdostsra s gyakorlatilag mindenre, ami mozog. Ez utbbiakat hvjuk DDL-triggereknek, s rhagyjuk ezeket a rendszergazdkra. Mi a tblkhoz rendelt triggereket fogjuk eszmnyi cljainkhoz felhasznlni. Mieltt lernnk az els utastst, mg egy kis magyarzat. Tblra biggyeszthet triggerbl ktfle van, amely az albbi hrom:
97
ADATKEZELS OTTHON S A FELHBEN INSTEAD OF: helyettest trigger, egy mvelet eltrtsre, kivltsra val. Ha pldul ksztnk egy INSTEAD OF triggert egy trlsi mveletre, tbb nem a gyri, eredeti DELETEutasts fog lefutni trlsi mvelet esetn, hanem az ltalunk rt helyettestkd, amivel pldul tnyleges trls helyett logikai trlst valsthatunk meg, egy mezben tbillentve a sor trltsgnek llapott, vagy teljesen ki is iktathatjuk az adott mveletet. AFTER: az adatmdost mvelet utn(?) lefut kd. A neve teljesen flrevezet, mert nem a tranzakci utn fut le, hanem a kells kzepn, ezltal lehetsgnk van a mdostsi adatok figyelembevtelvel pldul korriglni az adatokat, vagy ppensggel visszavonni a tranzakcit (ROLLBACK). Mifle utna-trigger az, ami a mveletet meg nem trtntt tudja tenni? Semmifle. Ennek ez a neve, de csak azrt, hogy jl sszezavarja a kezd SQLprogramozt. FOR: egy adott mveletre vonatkoz trigger. Na krem, ez ugyanaz, mint az AFTER, a kt kulcssz csereszabatos. Hogy mirt? Ennek trtnelmi okai vannak, szrvek viszont nincsenek. Ezrt rhattam fentebb, hogy ez a kett az albbi hrom
Ha egy triggernek se bemeneti, se kimeneti rtke nincs, az nem olyan, mint a sketnma vak? Majdnem, de nem teljesen, mivel ms csatornkon mgiscsak hozzjutnak bemen adatokhoz. A tblamveletekhez rendelt triggerek (eltte, utna, helyette, mindegy) hozzfrnek az adott mvelethez tartoz adatokhoz, mgpedig a mr megismert INSERTED, DELETED pszeudotblk segtsgvel. Vajon mit lt egy INSERT trigger az INSERTED tblban? gy van, a beszrsra vr sorokat. s mit lt a DELETE trigger a DELETED tblban? No, egy hangszrrt? s vgl az UPDATE, amely a DELETED-ben ltja a mltat, az INSERTED-ben pedig a jvt. Ez legalbb kvetkezetes. Els feladatunk az egyes bankszmlkhoz tartoz egyenleg kiszmtsa s folyamatos karbantartsa lesz az Amount tblban. Ne feledjk, hogy az egyes tranzakcikbl kiszmtott egyenleg redundns adat, amit ha nem tartunk karban, hamis rtket fog mutatni21! Ehhez elsknt meg kell alkotni az Accounts tblban egy Balance nev mezt az sszegek trolsra:
21
A mi pldnkban gy is, gy is hamisat fog mutatni, mert most szpen elhanyagoljuk a pnznemeket, s lazn sszeadjuk az eurt a forinttal merthogy a korrekt megvalsts tovbbi tblkat, tovbbi kdot ignyelne.
98
CREATE TRIGGER Balance ON Transactions FOR INSERT AS UPDATE Accounts SET Balance=Balance+Amount FROM Accounts a JOIN INSERTED i on a.AccountID=i.AccountID
A triggerben egy UPDATE utasts cscsl, ami az Amount tblt sszekapcsolja az INSERTED tblval, s onnan az Amount-okat a megfelel Balance-ba szrja22. Ezzel bezemeltk a karbantartrutint. Jhet a sok-sok nulla kijavtsa. A meglv banki tranzakcik alapjn ksztnk egy sszegz lekrdezst, melyet rbortunk az Accounts tblra:
UPDATE Accounts SET Balance=ISNULL((SELECT SUM(Amount) FROM Transactions WHERE AccountID=a.AccountID), 0) FROM Accounts a
Az ISNULL()-fggvnyre azrt van szksg, mert 1.) az UPDATE nem viseli el a GROUP BY-t, ami kellett volna az sszegzshez, ezrt 2.) begyazott SELECT-et hasznltam, ami 3.) nem egy INNER JOIN, teht 4.) nem ltez Transactionok esetn is rinti az Account sort, s ott 5.) NULL-t ad vissza, ezt 6.) az ISNULL() visszacserli nullra. Csak hogy ne szlljon el. A kvetkez feladat, hogy ne lehessen a Transactions tbla sorait mdostani. Ezt el lehetne rni jogosultsg-belltsokkal is, de mi most triggerversenyben vagyunk, ezrt triggerrel fogjuk megoldani, mgpedig gy, hogy ha bejn egy UPDATE, mi visszabortjuk a tranzakcit:
CREATE TRIGGER NoUpdateTran ON Transactions FOR UPDATE AS PRINT 'Ezt a tblt tilos mdostani, regem' ROLLBACK TRAN
Ez a trigger llhatna akr egyetlen utastsbl is, de mi jlneveltek vagyunk, ezrt runk valamit a kimenetre, mieltt lecsapnnk a tranzakcit, mint a taxirt.
22
Taln mr megszokhattuk, de ez a trigger is hibs. (Az egyszerstsnek ra van.) Ha valaki az T. Olvask kzl meg tudja mondani, mi rossz rajta, nem egy hangszrt, de egy Tr Rudit kap ajndkba!
99
Most akadlyozzuk meg a trlst is! Ezttal hasznljunk INSTEAD OF triggert, ami az eredeti DELETE mvelet helyett az ltalunk megadott kdot futtatja le, ami lehet pldul egy naplzs, hogy ki, mikor ksrelte meg a trlst! Maga a trls azonban nem fut le:
CREATE TRIGGER NoDeleteTran ON Transactions INSTEAD OF DELETE AS INSERT LogTable(Username, CreationDate) VALUES(SUSER_SNAME(), GETUTCDATE())
Ez a trigger a LogTable nev (nem ltez) tblba rja a trlsi ksrleteket (teht elszll ) de nem trl. Vegyk szre, hogy a jogosultsgokkal szemben most mindenki szmra megszntettk a mdosts, trls lehetsgt, Adminka sem tud trlni, mdostani a triggerek lelvse nlkl, ami viszont nagy knyelmetlensggel s rizikval jr, teht nem fogja ket kikapcsolni.
Az egyetlen lehetsg a futtatson kvl, hogy a trolt eljrs eredmnyhalmazt bele lehet lkni egy INSERTutastsba.
100
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA ben nem fogja tudni felhasznlni. Ezt a hinyossgot ptoljk a fggvnyek, amelyekbl 2005-ben egyszerre kaptunk vagy negyedtucatot! Az els fggvnytpus a skalris fggvny, ami nagyjbl annyit jelent, hogy a fggvny egy darab rtket ad vissza. Az egyrtk fggvnyek felhasznlsa a legszlesebb kr, mert mindenhol szerepelhetnek, ahol egy SQL-utastsban kifejezs llhat: mezlista, WHERE-felttel, HAVING stb. A msodik tpus az egysoros tblafggvny, ami leginkbb egy paramterezhet nzet. Milyen j is lenne, ha a nzeteinknek bemen paramtert adhatnnk! Adhatunk, csak akkor az mr fggvny. Egysorosnak azrt nevezzk, mert a nzetekhez hasonlan egy darab SELECT lehet bennk s ksz. Persze a bemeneti paramtereket ez a lekrdezs felhasznlhatja. Az egysoros tblafggvny mindenhol szerepelhet, ahol tbla szerepelhet, teht FROM zradkban, virtulis tblaknt! A harmadik tpus pedig az ereszd-el-a-hajamat tblafggvny, amiben tetszleges bonyolultsg rutin akr soronknt pakol ssze egy tblt, s a vgn boldogan visszatr. Ennek eredmnye is egy tblaknt felhasznlhat valamicsoda. Kezdjk az egyszerbbekkel, s onnan haladjunk a bonyolultabbak fel! Ksztsk el a kamatos kamat fggvnyt, mely egy kamatrta s egy futamid segtsgvel kiszmtja egy bemen sszeg x v mlva esedkes rtkt! Maga a kamatos kamat borzaszt egyszer dolog, az alapsszeget meg kell szorozni a kamat annyiadik hatvnyval, ahny vnyi kamatozsrl beszlnk. Lssuk a fggvnyt!
CREATE FUNCTION KamatosKamat(@Alap MONEY, @Kamat MONEY, @Ev FLOAT) RETURNS MONEY AS BEGIN RETURN @Alap * POWER(@Kamat, @Ev) END
Itt mr ktttebb a szintaxis, mint a trolt eljrsoknl, ami nem is csoda, hiszen vagy tz vvel ksbb szletett. Nem lehet eltrehnykodni pldul a fggvny elejt s vgt (BEGIN, END), amit a trolt eljrsoknl mg lazn elhagyhattunk. A paramterek zrjelben vannak, ahogy ez egy rendes fggvnytl elvrhat, s meg kell adni a visszatrsi rtk adattpust is (RETURNS kulcssz). A tbbi remlem nmagyarz. jdonslt fggvnynket akr trt vekkel is hasznlhatjuk:
Hat s fl v mlva a hrom petkunkbl 12%-os ves kamattal szmolva 6,33 petk lesz. Most tegyk bele a fggvnyt egy lekrdezsbe, krdezzk le a kuncsaftjaink egyenlegt 6%-os kamattal, tz vre!
101
FROM Accounts
Ezt tudjk a skalris fggvnyek. Egysoros tblafggvnyknt pedig ksztsnk egy fggvnyt, ami egy bemen paramter mentn vlogatja le a tranzakcikat! Ez most nem annyira j plda, mert ezt egy nzettel is simn meg lehet csinlni, de a bonyolultabb tblafggvny fel vezet ton egy szksges lps.
CREATE FUNCTION EgysorosTabla(@Kuszob MONEY) RETURNS TABLE AS RETURN SELECT AccountID, Balance FROM Accounts WHERE Balance > @Kuszob
Ebben az egyszer esetben a fggvny trzst alkot SELECT hatrozza meg a visszaadott tbla szerkezett, ezrt a tbladefincival nem kell kln foglalkoznunk. A bemeneti paramtert a WHEREfelttelben ltjuk viszont. Fggvnynk tblartk, teht FROM zradkban szerepelhet tblaknt, gy:
CREATE FUNCTION Hoeleje(@Honapok INT) RETURNS @t TABLE(FirstDay DATETIME) --tbladefinci AS BEGIN WHILE @Honapok > 0 BEGIN INSERT @t VALUES (DATEADD(DAY, 1, DATEADD(MONTH, @Honapok1, EOMONTH(GETDATE())))) SET @Honapok-=1 --ciklusvltoz cskkentse END RETURN --a ksz tbla visszaadsa END
Akinek a dtumszmts rsz nem mkdik, az ismt lebukott, hogy nem SQL 2012-t hasznl, mert az EOMONTH() fggvny 2012-es jdonsg, s ahogy a neve is sugallja, egy dtum alapjn ellltja a hnap utols napjt. Ezzel tl egyszer lett volna a feladat, ezrt dntttem a hnap els napja mellett.
102
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA rdemes megfigyelni, hogy semennyit sem trdtem a legenerlt helejk sorrendjvel (konkrtan fejjel lefel generlom ket), hisz a vgeredmnynk egy tbla, amit majd a felhasznlja gy rendez sorba, ahogy akar:
103
11 Spci adattpusok
Az SQL Serverben van egy-kt olyan adattpus, aminek a puszta ltvnytl felll a kezdk htn a szr. Ilyen az XML, a HierarchyID, a Geometry-Geography s ltalban azok az adattpusok, amelyek plusz funkcikkal rendelkeznek. Az INT, a DATETIME, a FLOAT s a tbbiek buta adattpusok, nmagukban nem tudnak semmit. Egy XML-adattpusnak azonban nemcsak lelke, de metdusai vannak, amelyekkel objektumorientlt mdon lehet s kell zsonglrkdnnk. Nemcsak rtkk van, mint egy INT-nek, hanem programlogika is tartozik hozzjuk. Mirt ilyen faramuci adattpusok ezek? Azrt, mert ezek mind .net-ben vannak megvalstva (kls DLL-ek), vagyis minden egyes ilyen adattpus egy-egy dotnet-osztly pldnya. s mivel az, ami, tartoznak hozz dotnetes propertik s metdusok. Ha dotnetesek, akkor pldul mindegyiknek van ToString() metdusa, ami a benne rejl binris adatot stringformtumban vissza tudja adni neknk. St, a dolog fordtva is mkdik, mert ezeknek a jszgoknak van Parse() metdusuk, teht ha stringet tmkdnk beljk, fel fogjk dolgozni! Klnsebb elmagyarzat nlkl nzzk pldul ezt a kis aranyos HierarchyID-t, amibe ostobn beletltnk egy nulla rtket (hexa nulla kell neki, nem INT, ezrt a 0x), majd visszakrjk string formtumban:
Ez biztat, ennek valami kze lehet az tvonalakhoz! Most fordtsuk meg, vegynk egy msik dotnetes adattpust, s tmjnk bele stringet, mire megynk vele?
Ami a lnyeges, hogy valami biztosan trtnt, mert lett egy olyan flnk, hogy Spatial results, ahol ugyan a pontunk nem ltszik, mert tl pici, de a koordintk valamifle 10, 10 bigy kzelben llnak, teht beletrafltunk!
104
Megllapodhatunk teht abban, hogy a dotnetes adattpusok ugyan a mgia terletre tartoznak, de kapcsolatot tudunk velk teremteni, ha mskpp nem, ht fstjelekkel s stringzenetekkel. Remlem, ettl mindenkinek elszllt a flelme s/vagy undora, megjtt a btorsga, gyhogy megvizsglhatjuk ezeket a csodabogarakat egyesvel, rszletesen is.
11.1 Az XML-adattpus
XML-formtumra ltalban akkor van szksgnk, ha az adatainkat kls rendszer szmra szeretnnk tadhat, elfogadhat llapotra hozni. Az SQL Server igen gazdag SQL-formzsi lehetsggel rendelkezik, melynek hasznlata a pofonnl is egyszerbb. Ha le szeretnnk krdezni mondjuk a tranzakciinkat XML-formtumban, egyszeren a lekrdezs vgre kell rni, hogy FOR XML AUTO, s a dolog le van tudva, gy:
SELECT
AccountID AS 'alatta', CustomerID AS 'alatta/meglejjebb', AccountNumber AS 'alatta/mellette', Balance AS 'masik/agon/ul/egy/vereb' FROM Accounts FOR XML PATH
Az eredmny:
105
A FOR XML zradk egybknt mg kismilli formzsi lehetsget tartalmaz, a gykrelem megadstl az XML-smk hasznlatig. Ha valakinek ennyire specilis XML-es feladata akad, nzzen utna! A kvetkez mutatvny egy XML-ben megkapott adathalmaz beolvassa, tblzatt alaktsa. Az sem bonyolultabb, csak tudni kell a nyitjt, ami nem ms, mint egy tblaforrsknt hasznlhat fggvny, az OPENXML. Ennek van egy kezdknek sznt vltozata, ami gy mkdik, hogy az XMLdokumentumban egy adott SQL-tbla mezneveit automatikusan megkeresi, s az rtkeket tblzatos formra hozza. Ha teht az XML-doksiban szerepel AccountID s CustomerID tag, mint az albbi pldban is, az OPENXML automatikusan kiguberlja az rtkeket, mivel megadtuk neki, hogy az Accounts tbla szerkezett keresse az adatokban. Sajnos a kd ttekinthetetlensge rdekben foglalkoznunk kell azzal a cseklysggel is, hogy az OPENXML nem magt az XML-szveget, hanem annak feldolgozott, memriabeli reprezentcijt vrja bemenetknt, amit egy INT tpus kezeln (Handle) keresztl rnk el. Emiatt van szksg a @docHandle vltozra s az sp_xml_preparedocument trolt eljrsra. Kezdknek
DECLARE @doksi XML='<akarmi><AccountNumber>23</AccountNumber><CustomerID>21323</Cus tomerID></akarmi>' DECLARE @docHandle INT EXEC sp_xml_preparedocument @dochandle OUTPUT, @doksi SELECT * FROM OPENXML(@docHandle, '/akarmi', 2) WITH Accounts
106
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA A harmadik mutatvny pedig maga az XML-adattpus. Mint a fenti pldban lthat, loklis vltoznak, de egybknt tbla mezjnek is adhatjuk ezt a tpust, ami innentl lehetv teszi, hogy ha minden rekordunkhoz tartozik egy XML-doksi, akkor azt a rekordban magban troljuk, ne kelljen a fjlrendszerben idtlen nev egyedi fjlok rengetegvel knldni. Az XML-adattpus pedig llam az llamban, vagy csepp a tengerben, kinek hogy tetszik, mert maga ott bent a rekordban egy dokumentum, amiben pldul keresni lehet. A fenti pldt felhasznlva lssuk, hogyan lehet egy XML-adattpusbl kiszedni egy bizonyos rtket! Ht a Query() metdus felhasznlsval!
SELECT @doksi.query('/akarmi/AccountNumber')
Ez a lekrdezs kiszedi a hivatkozott XML-tpus vltozbl, vagy mezbl az /akarmi/AccountNumber tvonalon tallhat XML-elemet. Ha pedig nem az elemre, hanem annak rtkre lenne szksgnk, a value() metdus lesz a mi bartunk:
ALTER TABLE Employees ADD Hierarchy HierarchyID ALTER TABLE Employees ADD Path AS Hierarchy.ToString()
Az tvonal kiszmtsa nem ll msbl, mint a ToString() metdus meghvsbl. Ha most elkezdjk feltlteni a Hierarchy mezt, az tvonal automatikusan kiszmtdik. Szerencsre a HierarchyID mezbe kzvetlenl belerhatjuk a Path-okat, abbl majd ellltja a binris rtket. Mr csak
107
ADATKEZELS OTTHON S A FELHBEN annyit kell tudni, hogy a hierarchia (s az tvonal) szmokbl pl fel. Ezen informci birtokban kitlthetjk a hierarchiamezt, gy:
Ltszlag a Hierarchy s a Path mez kztt nincs klnbsg, de ez csak a szerkesztfellet okossgnak ksznhet. Egy sima SELECT ezt mutatja, teht szksges a Path mez is:
Innentl a BossID meztl meg is szabadulhatunk. A HierarchyID is dotnetes adattpus, teht neki is van egy sereg metdusa. A fontosabbak: GetDescendant() csinlj nekem gyermeket! GetAncestor() apu! GetLevel() hnyadik mlysgben vagyok? IsDescendantOf() ez a bizonyos valaki az apm? GetReparentedValue csaldfa tportolsa msik s al
108
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA tfedst, tvolsgt stb. anlkl, hogy trdnnk kellene a mrtkekkel. Hogy miben szmolunk? Azt az alkalmazs fejlesztje rendeli hozz. Mter? Millimter? Egyre megy. Ha valaki trkpen brzoland dolgokat szeretne kezelni s trolni, neki a Geometry val. Minl nagyobb s tvolabbi objektumokrl van sz (pldul: vrosok), annl fontosabb, hogy a tvolsgokat ne skban, hanem a fldgmb felletn rtelmezze a rendszer. gy is teszi. Els alkalmazsunk elszakadva a banktl egy raktri alkalmazs lesz. Beszrunk a raktrba klnbz alakzatokat, aztn megnzzk, befr-e oda mg egy zongora. Na j, ezt nem nzzk meg, mert rmiszten sok kdot ignyelne, de ms rdekessgeket igen. Hozzunk ltre egy Raktar nev tblt, ebbe fognak kerlni a trgyak:
INSERT Raktar VALUES('Mkszem', 'POINT(5 35)') INSERT Raktar VALUES('Horgszbot', 'LINESTRING(10 10, 25 35)') INSERT Raktar VALUES('Asztal', 'POLYGON((15 18, 35 18, 35 28, 15 28, 15 18))') INSERT Raktar VALUES('szgumi', 'CURVEPOLYGON(CIRCULARSTRING(0 4, 4 0, 8 4, 4 8, 0 4), CIRCULARSTRING(2 4, 4 2, 6 4, 4 6, 2 4))')
Felhasznlt alakzatok: pont (POINT), vonal (LINESTRING), zrt alakzat (POLYGON), grbe (CIRCULARSTRING). Minden zrt alakzat (POLYGON) tartalmazhat lyukakat, gy kszlt az szgumi is, a kls krbl kiveszi a belst. Mrtkegysget nem rtelmeznk, a szmok ppgy jelenthetnek mtert, mint rft. A raktrunkban a sarokban van egy szgumi, keresztben egy pecabot, s mg egy asztal is ll a trben. A mkszemrl nem is beszlve. Lekrdezve a raktr tartalmt, ezt ltjuk:
109
Mivel mlysgi informci nincs, nem tudjuk eldnteni, hogy a horgszbot az asztalon vagy az asztal lba alatt helyezkedik el. Most jn a lnyeg! Szmtsuk ki a trgyak ltal elfoglalt helyet! Dotnetes adattpusrl lvn sz, mr meg sem lepdnk, hogy metdushvsokkal lhetnk. E kt adattpusnl j, ha megjegyezzk, hogy a metdusok neve ST betkkel kezddik, ST, mint standard. A terlet kiszmtsra az STArea() metdus hasznlhat, gy:
A raktrunk terlete egybknt 40 x 40, mg ha vonallal is vettem krl, gy egyszer kivonssal megllapthat, hogy mekkora szabad terletnk van. Persze ez csalka, ha a trgyak egyms hegyn-htn vannak, de szerencsre ezt is le lehet krdezni a STCrosses() metdussal. Nzzk meg, hogy mi metszi az rasztalt:
SELECT *, Helye.STCrosses('POLYGON((15 18, 35 18, 35 28, 15 28, 15 18))') AS Belelog FROM Raktar
A horgszbot lg bele:
110
A geometry adattpus metduslistja tbb mint 40 elembl ll, ezrt ezt nem fejtem ki itt bvebben. Elg annyit tudni, hogy brmilyen krdsre megadhat a vlasz a megfelel metdus meghvsval. Metszi? Kzel van? Magban foglalja? stb. A Geometry s Geography adattpusok destestvrek. Minden, amit a raktras pldban lttunk, gyakorlatilag mdosts nlkl mkdik trkpszeti esetben is. A klnbsg a szmtsok mdjban, a gmbfellet figyelembevtelben rejlik. A jelensg megismershez kiegsztjk a Cities tblnkat az adott vros koordintival:
111
INSERT Cities(Name, Location) VALUES('Budapest', 'POINT(19.0648193359375 47.5062217712402)') INSERT Cities(Name, Location) VALUES('London', 'POINT(-0.127140000462532 51.5063209533691)') INSERT Cities(Name, Location) VALUES('Moszkva', 'POINT(37.6150093078613 55.7569808959961)') INSERT Cities(Name, Location) VALUES('Athn', 'POINT(23.7364101409912 37.9761505126953)') INSERT Cities(Name, Location) VALUES('New York', 'POINT(-74.0071182250977 40.7145500183105)') INSERT Cities(Name, Location) VALUES('Fokvros', 'POINT(18.421989440918 -33.9190902709961)')
Amelyek gy festenek a trkpen:
Kt vros tvolsgt a - kitallhat nev STDistance() fggvnnyel lehet lekrdezni. A trkpszeti alkalmazsok ksztsnek csak a fantzink szab hatrt.
112
12 Az SQL Azure
Az elz fejezetben az SQL Server-rel, annak tulajdonsgaival s kezelsvel ismerkedhettnk meg. Most a Microsoft SQL Azure-t fogjuk kzelebbrl szemgyre venni. Az SQL Azure egy felh alap relcis adatbzis-kezel rendszer. Ez egy magas rendelkezsre lls, sklzhat, multi-tenant (tbb-brls) szolgltats, amit a Microsoft biztost szmunkra a felh megoldsban. A fejlesztknek s az zemeltetknek mostantl nem kell gondoskodniuk a teleptsrl, a belltsokrl, patchekrl s a menedzselsrl, gy a fizikai adminisztrci megsznik, s kizrlag a logikai adminisztrci marad az adatbzis adminisztrtorok szmra. Ha mr van egy meglv adatbzisunk, s azt mi fel szeretnnk tenni a felhbe, akkor mirt ne hasznlnnk a meglv technolgikat s a tudsunkat? Az SQL Azure ebben segt neknk, hisz fejlesztsi szempontbl minimlis j tudsra kell szert tennnk ahhoz, hogy a hagyomnyos SQL Server-es (on-premises24) megolds helyett SQL Azure-t hasznljunk. Azoknak a cgeknek, amelyek egy internet alap szolgltatst akarnak nyjtani, sokfle kihvssal kell szembenznik. A felhasznlk ugyanis az adataikat el szeretnk rni akr tbbfle kszlkrl vagy platformrl. Az adatbzis mrettl, annak rendelkezsre llstl elg sokfle problmt kell lekzdennk. Ha a hagyomnyos modellt tekintjk alapul azaz, hogy a fizikai szerver s vele egytt az SQL Server is a mi fennhatsgunk alatt van, akkor tbb problmra is figyelnnk kell. Egyfell szksgnk lesz egy vagy tbb szerverre, opercis rendszerre, adott termkek licenszre, trhelyre, hlzatra stb. A rendszergazdknak figyelnik kell a rendszer llapott, teljestmnyt, rendelkezsre llst, s ha valami problma van, akkor be kell avatkozniuk. A rendszernknek termszetesen problma esetn is vlaszkpesnek kell lennie. Nem engedhetjk meg, hogy egy-egy karbantarts esetn a felhasznlk ne rjk el a szolgltatsokat. Ha belegondolunk abba, hogy egy ilyen tpus rendszer megptse s zemeltetse mennyi munkarba s pnzbe kerl, rjvnk, hogy ez nem egy kltsghatkony megolds. Akkor, hogy lehetne megoldani ezt a problmt kltsghatkony mdon? Hisz gondoljuk csak bele, mennyibe kerl egy szerver beszerzse, s ha hibatr rendszert akarunk, akkor nem egy, hanem tbb szervert kell vsrolnunk. A licenszek sem olcsk, s mg nem beszltnk a rendszergazdk brezsrl s a bevezets kltsgeirl. Ez gy nagyon soknak tnik. Viszont ha mr egy meglv hibatr infrastruktra, akkor mirt ne vsrolhatnnk erforrst anlkl, hogy pnz hegyeket pazarolnnk el egy sajt megolds kivitelezsre. Ha kltsghatkonyabbak szeretnnk lenni ilyen tren, akkor a Microsoft SQL Azure erre kitn megolds! Radsul ugyanazokkal az eszkzkkel dolgozhatunk, mint eddig, hisz az SQL Azure az eszkzeink nagy rszt tmogatja. Fejlesztsi szempontbl pedig ugyanaz a T-SQL, mint az on-premises SQL Server esetn, nhny aprbb klnbsg van a kt vltozat kztt.
24
113
ADATKEZELS OTTHON S A FELHBEN Az SQL Azure tulajdonkppen egy mdostott SQL Server motor, amely kiemelkeden magas rendelkezsre llst s hibatrst biztost a felhasznlknak. Nzzk meg, milyen elnyei vannak annak, hogy az adatbzisunk a felhben van: Nincs szksg hardware-re. Nincs fizikai telepts. Licenszeket nem kell beszereznnk s/vagy megvsrolnunk. Patchek s frisstsek teleptse automatikusan trtnik. Magas rendelkezsre lls s hibatr a rendszer. Az adatbzisok mrete rugalmas, egyszeren cskkenthet vagy pp nvelhet az zleti ignyeknek megfelelen. A meglv SQL Server-es eszkzkkel kezelhet (pl. SSMS). T-SQL tmogats. Annyit fizetnk rte, amennyit hasznljuk. Knny kltsgelszmols. Fontos megjegyeznnk, hogy az SQL Azure adatbzisokat nemcsak Windows Azure-ban hosztolt alkalmazsbl tudjuk elrni. Akr a vilg tvoli pontjrl is ugyangy hasznlni tudjuk az adatbzist. Viszont azzal tisztban kell lennnk, hogy az SQL Azure funkcionalitsban bizonyos tren kevesebbet tud, mint az on-premises SQL Server. Pldul: Analysis service vagy Online Analytical Processing (OLAP) mg nem rhet el az SQL Azure jelenlegi vltozatban. De korbban is voltak olyan funkcik, amik az els vltozatba nem kerltek bele, ksbb viszont elrhetv vltak. Ilyen pldul az SQL Azure Reporting. Ma mr ez a funkci elrhet, s mivel ez online platform, ezrt a frissts is egyszeren trtnik. Az albbi lista az SQL Azure fontosabb hinyossgokat sorolja fel. Abban az esetben, ha szmunkra ezek nlklzhetetlen funkcik, akkor ne vlasszuk az SQL Azure-t! Elosztott tranzakcik Elosztott lekrdezsek FILESTREAM Data Beptett Full-Text Search CLR Service Broker Fizikai szerver s katalgus Adatbzis Mirroring Extended Stored Procedures Tbla particionls
114
Tovbbi hinyossgok ezen az oldalon tallhatk. Az SQL Azure rugalmas, sklzhat s biztonsgos rendszer. Mit is jelent ez? Az egyrtelm, hogy rugalmas s sklzhat, hiszen az ignyeinknek megfelelen vltoztathatjuk az adatbzisaink mrett, s annak fggvnyben fizetnk, amennyit felhasznltunk. De mitl biztonsgos a rendszer? Az SQL Azure-ban minden adatbzisrl kett darab replika kszl. Abban az esetben, ha az egyik kiesik, annak szerept a kvetkez tveszi. Ekkor ismt kszl egy replika, hogy mindenkppen hrom pldny legyen az adott adatbzisbl. gy ha hiba trtnik, az adataink mindig rendelkezsre llnak. Gyakran merl fel viszont a krds, hogy hogyan tudunk biztonsgi mentst kszteni az adatbzisunkbl. Hisz az on-premise megoldsoknl ez trivilis dolog. Az SQL Azure esetben jelenleg mg nincs erre beptett lehetsg. Persze sajt megoldst kszthetnk, amivel lekrdezzk az adatbzis tartalmt, majd azt eltroljuk egy fjlban, de az mgse ugyanaz, mint egy bak fjl.
12.1 razs
Az SQL Azure-nak nagyon kedvez djszabsa van. Az els vltozat razsa nagyon egyszer volt, hisz minden gigabjt 9.99$ volt. Teht egy 5 gigabjtos adatbzis havi szint fenntartsa 49.95$-be kerlt, egy 150 gigabjtos adatbzis pedig 499.95$ volt. Ez sem volt drga megoldsnak tekinthet, de az rak 2012 februrjban drasztikus cskkensen mentek keresztl. Bizonyos csomagok esetn 75%-kal is olcsbb lett az SQL Azure adatbzisok hasznlata, mint korbban. Az albbi tblzat a rgi s az j adatbzis rakat mutatja be.25 Trterlet 5 10 25 50 100 150
25
Fontos megjegyezni, hogy SQL Azure adatbzisok ra vltozhat, vsrls eltt mindig tjkozdjunk az aktulis rakrl a http://windows.azure.com oldalon!
115
ADATKEZELS OTTHON S A FELHBEN A 2012. februri frisstsben ezenkvl bevezetsre kerlt egy extra kicsi adatbzis is. Ha szeretnnk, immr 100 megabjtos adatbzis is a rendelkezsnkre llhat, radsul nem is akrhogy. Ugyanis az adatbzis ltrehozsnl ltni fogjuk, hogy a web edition-nl nincs 100 megabjtos opci, de ha a ltrehozott adatbzisban 100 megabjtnl kevesebb adatot trolunk, akkor a havidj a 9.99$ helyett csak 5$ lesz. Abban az esetben, ha meghaladjuk a 100 megabjtos korltot, akkor az 1 gigabjtos csomag rai lesznek rvnyesek. Ez egy rendkvl j s kltsghatkony megolds. tlagos kis s kzepes projekteknl nem szoktak 1 gigabjtnl nagyobb adatbzisokat hasznlni. Gondoljunk bele, hogy szksgnk volna a projektnkhz egy adatbzisra, ami mindig rendelkezsre ll, hibatr, s ha kell, akkor sklzhat! Ma mr havi 9.99$ -rt (vagy kevesebbrt) kaphatunk egy ilyen adatbzist. Ha ezt a sajt cgnknek kellene zemeltetni a mai rak mellett, a szerver ramfogyasztsa is drgbb lenne. Nem szmolva a hardver, licenszek, patchek s egyb zemeltetsi kltsgeket. Most, hogy tudjuk, mi az az SQL Azure, s milyen kltsgei vannak, nzzk meg, hogy hogyan is kell hasznlni azt!
116
3. Kvetkez lpsknt kattintsunk az oldal aljn tallhat Add gombra! Ekkor felugrik a New SQL Database ablak.
117
ADATKEZELS OTTHON S A FELHBEN 4. A megjelen ablakban adjuk meg az adatbzisunk nevt (Name)! Ezt kveten vlasszuk ki, hogy mekkora legyen az adatbzisunk mrete! Ktfle vltozat ltezik, amelyek csak a kivlaszthat adatbzis mretben klnbznek. Ltezik egy Web Edition a kis adatbzisok szmra, valamint van egy Business Edition a nagyobb adatbzisok szmra. A Web edition-ben 1 gigabjtos s 5 gigabjtos adatbzisok kzl vlaszthatunk. (Ne feledjk, ha 100 megabjtnl kevesebbet hasznlunk, akkor csak 5$-t kell fizetnnk!) A Business edition-ben jelenleg 10 150 gigabjtos adatbzisok kzl vlaszthatunk. A Collation-nl bellthatjuk, hogy milyen karakterkdolst hasznljunk az adatbzisnl. Mivel most magyar nyelvterleten vagyunk, az alaprtelmezett j lesz a szmunkra. Ezt kveten kivlaszthatjuk, hogy melyik elfizetshez szeretnnk az adatbzist rendelni. Ha tbb van, vlaszthatunk kzttk. A Server menpont alatt kivlaszthatjuk, hogy egy j adatbzis szerveren szeretnnk ezt az adatbzis ltrehozni, vagy egy mr meglv adatbzis szerverhez szeretnnk hozzadni. Mi most j adatbzist szeretnnk ltrehozni, gy vlasszuk ki a New SQL Database Server-t a lenyl listbl, majd kattintsunk a tovbb gombra! (Balra nyl) 5. Ebben a pillanatban megjelenik a Database server settings ablak. Itt elszr meg kell adnunk az adminisztrtori felhasznlnevnket s jelszavunkat. Fontos: nem lehet a felhasznlnv: sa, admin, administrator, root, guest, dbmanager s loginmanager! Figyeljnk arra is, hogy ers jelszt hatrozzunk meg! 6. Ezt kveten vlasszuk ki a szmunkra megfelel rgit. ltalban a hozznk kzelebb es rgit clszer vlasztani. A rgi kivlasztst jl fontoljuk meg, ugyanis ezt megvltoztatni ksbb nem lehet!
A rgi kivlasztsa a dtumot is befolysolja! Pldul: Ha van egy adatbzisunk a West Europe adatkzpontban s meghvjuk a 118
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA GETDATE() fggvnyt, akkor az adatkzpont helyi idejt adja meg, ami 2 ra eltrst eredmnyez szmunka, akik Magyarorszgrl hasznlnk az adatbzist. A dtumokat clszer UTC-ben trolni. 7. Az utols menpont egy checkbox, ami alapveten be van kapcsolva. Itt befolysolhatjuk, hogy az ltalunk ltrehozott adatbzist el lehessen rni egy tetszleges azure szolgltatsbl, belertve a sajt szolgltatsunkat is. 8. Ha ezekkel a lpsekkel megvagyunk, kattintsunk a Finish (pipa) gombra, s nhny msodpercen bell az ltalunk konfigurlt adatbzis szerver s adatbzis el fog kszlni.
9. Ezt kveten a Management Portlon lthatjuk az j SQL Azure szervernket. Az SQL szervernk kap egy vletlen nevet, ami ebben az esetben az e7m4zvqafx. Ezt az adatbzis szervert majd az e7m4zvqafx.database.windows.net cmen rhetjk el. Egy adatbzis szerveren 149 darab adatbzis hozhat ltre. r szempontjbl mindegy, hogy egy j adatbzis szerveren hozunk ltre egy j adatbzist, vagy egy szerveren tbb adatbzist trolunk. Mindig csak az adatbzisokrt fizetnk, nem pedig az adatbzis szerverekrt. Fontos megjegyezni tovbb, hogy csak az ltalunk ltrehozott adatbzisrt kell fizetnnk, a master adatbzisrt, valamint a log fjlokrt nem kell kln fizetnnk.
13.1 Tzfalszablyok
Az elksztett adatbzist jelenleg mg nem tudnnk elrni. Ahhoz, hogy az elksztett adatbzist hasznljuk, meg kell mondanunk, hogy az SQL Azure szervernket milyen IP cm tartomnybl rhetjk majd el. Megadhatunk egy IP cmet vagy akr IP cm tartomnyt is. Nzzk meg, hogyan! 1. A baloldalon tallhat navigcis svon kattintsunk az SQL DATABASES menpontra! 2. Az SQL Databases ablakban megjelennek az adatbzisaink. A Server oszlop alatt lthatjuk, hogy az adott adatbzis melyik szerverhez tartozik. 3. Ahhoz, hogy tzfalszablyt hatrozzunk meg, kattintsunk az ltalunk kivlasztott szerver linkjre!
4. A megjelen oldalon vlasszuk ki a CONFIGURE menpontot! 5. Az oldalon meg kell adnunk a tzfalszably nevt, ez a nv tetszleges lehet. Jelen esetben a DevOffice nevet adtuk meg a szablyunk szmra. Ezenkvl kell egy IP tartomnyt is megadnunk, amelybl az adatbzist elrhetjk. Ez lehet egy IP cm
119
ADATKEZELS OTTHON S A FELHBEN tartomny, de lehet akr csak egy IP cm is. Ebben az esetben a start ip address megegyezik az end ip address rtkvel. Ha azt akarjuk, hogy a vilg brmely pontjrl elrhet legyen az adatbzisunk, akkor a start ip address-nek 1.1.1.1 es, mg az end ip address-nek a 255.255.255.255 ip cmet kell megadnunk. Termszetesen tbb szablyt is ltre tudunk hozni.
Az, hogy megadtunk egy IP cm tartomnyt, ahonnan elrhetjk az adatbzist, mg nem jelenti azt, hogy az Azure alkalmazsokbl is el tudjuk rni. Ahhoz, hogy az azure alkalmazs is elrje ezt az adatbzist, az Allow services menpontnak engedlyezve kell lennie. Ezt az adatbzis ltrehozsnl is megadhatjuk.
A tzfalszablyokat a ksbbiek folyamn brmikor mdosthatjuk vagy trlhetjk. Nemcsak a Management Portlrl tudjuk a tzfalszablyainkat mdostani, lehetsgnk van akr PowerShellbl is j szablyokat meghatrozni vagy a meglvket szerkeszteni, trlni. Ehhez le kell tltennk a Windows Azure PowerShell Cmdlets szkriptet a http://wappowershell.codeplex.com oldalrl.
120
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA 1. A bal oldalon tallhat navigcis svon kattintsunk az SQL DATABASES menpontra! 2. Ahhoz, hogy az adatbzisunk mrett vltoztassuk, kattintsunk az ltalunk kivlasztott adatbzis nevre!
3. A megjelen oldalon a kivlasztott adatbzis Dashboardjt lthatjuk, ahol a felhasznlt trterletet, valamint az ehhez kapcsold rszletes adatokat vehetjk szemgyre. 4. Ezen az oldalon kattintsunk a Scale menpontra! 5. Itt lltsuk be, hogy mi legyen az j mrete az adatbzisnak!
6. Ha kivlasztottuk a megfelel mretet, kattintsunk a Save gombra! A folyamat nhny msodpercet vesz ignybe. Ha most visszatrnk a Dashboard-ra, lthatjuk az adatbzis kihasznltsgnl, hogy nem 1 gigabjtnyi, hanem 10 gigabjtnyi trterlet ll a rendelkezsnkre.
121
14 Adatbzisok elrse
Ksz az adatbzisunk, gy ht itt az ideje elrni s hasznlatba venni. Ehhez a mr megszokott eszkzket is alkalmazhatjuk, pldul elrhetjk az SQL Azure adatbzis szervernket az SQL Server Management Studio 2008 R2 vel is. Indtsuk el az SQL Server Management Studio 2008 R2-t alkalmazst!
(Amennyiben nincs teleptve, legegyszerbben a Web Platform Installer-rel telepthetjk http://www.microsoft.com/web/downloads/platform.aspx). 1. Az alkalmazs indulsakor felugrik a Connect to Server ablak. Ebben az ablakban a Server name-hez meg kell adnunk az SQL Azure szervernk cmt. Ez a cm mindig a szerver neve <servername>.database.windows.net cmen rhet el. A <servername> a szervernk egyedi nevt jelli, ami ebben a pldban az e7m4zvqafx. 2. Az Authentication-t lltsuk t SQL Server Authentication-re, majd adjuk meg a felhasznlnevnket s jelszavunkat. A Windows Authentikci nem tmogatott!
FONTOS! Mindig figyeljnk oda a tzfalszablyokra! Abban az esetben, ha helytelenl vannak belltva, az SQL Azure szervernket nem tudjuk elrni! Ebben az esetben a 40615 hibazenetet fogunk kapni.
3. Ha kszen vagyunk, kattintsunk a Connect gombra! Ha sikerlt a kapcsolds, akkor az Object Explorerben a meglv adatbzisunk fogad.
122
Innentl kezdve az Object Explorerbl gy kezeljk az adatainkat, mint amit az SQL Servernl megszoktunk. Arra viszont figyeljnk, hogy ilyenkor az SQL Server Management Studink kisebb funkcionalitssal br! Pldul, ha tblt szeretnnk ltrehozni, azt jelenleg csak szkriptbl tehetjk meg. Nincsenek csillog varzslink, mint az on-primese SQL Server-nl.
Abban az esetben, ha nem megfelel mrettel szeretnnk lefuttatni a szkriptet, hibt kapnnk. Pldul: Ha 1 gigabjt helyett 2 gigabjtot rnnk, ami a Web Edition-ben nem tallhat, az albbi hibazenetet kapnnk:
The edition 'web' does not support the database max size '2 GB'.
123
ADATKEZELS OTTHON S A FELHBEN Viszont ha nem adunk meg paramtereket, akkor alaprtelmezetten egy Web Edition-s 1 gigabjtos adatbzist hozunk ltre.
CREATE DATABASE DevTest
Ha mdostani szeretnnk az adatbzisunk mrett s/vagy tpust, akkor azt az ALTER DATABASE paranccsal tehetjk meg. Az albbi pldban a mr korbban ltrehozott DevTest adatbzis mrett mdostjuk 1 gigabjtrl 5 gigabjtra.
ALTER DATABASE DevTest MODIFY (MAXSIZE=5GB, EDITION='web')
Abban az esetben, ha tovbb mr nincs szksgnk egy adatbzisra, akkor a DROP DATABASE paranccsal trlhetjk az adatbzisunkat. Az albbi pldban a DevTest adatbzist trljk (dbmanagerek trlhetik az adatbzist).
DROP DATABASE DevTest;
Ha meg szeretnnk nzni a rendelkezsre ll adatbzisainkat, akkor a master sys.databases nzett kell lekrdeznnk.
SELECT * FROM sys.databases;
Mint lthatjuk, az adatbzis menedzsmentben nem sok jdonsg van az on-primeses megoldsokhoz kpest. Nhny aprsggal rdemes tisztban lenni, de aki mr otthonosan mozog az SQL Server vilgban, annak az SQL Azure hasznlata nem jelent j kihvsokat.
Ezzel egy szerver szint felhasznlt hoztunk ltre. Ha viszont adatbzis szint felhasznlt szeretnnk ltrehozni, akkor a CREATE USER parancs lesz a segtsgnkre. Minden logint a master adatbzisba kell ltrehoznunk, de ahhoz, hogy csatlakozni tudjunk egy meghatrozott
124
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA adatbzishoz, ezt adatbzis szinten kell megtennnk. Figyeljnk arra, hogy a DevTest adatbzison futtassuk le az albbi parancsot!
CREATE USER DevUser FROM LOGIN Attila
Ezt kveten a DevTest adatbzishoz (s csakis ahhoz) csatlakozhat az Attila nev felhasznl. Meghatrozhatjuk, hogy az adott felhasznl fik milyen elemekhez frhet hozz. Ehhez az sp_addrolemember trolt eljrs lesz a segtsgnkre. Ebben az esetben a DevUser-t hozzadjuk a db_datareader szerepkrhz.
exec sp_addrolemember 'db_datareader', 'DevUser';
Az ALTER LOGIN paranccsal mdosthatunk egy mr meglv logint, melyet a master adatbzison kell lefuttatnunk. Az albbiakban az Attila nev felhasznl jelszavt cserljk le.
ALTER LOGIN Attila WITH PASSWORD = 'newPassword1' OLD_PASSWORD = 'Password1';
Ha egy logint trlni szeretnnk, akkor a DROP LOGIN paranccsal tehetjk meg. Ezt a parancsot is a master-en kell futtatnunk. Ha szerver szinten trlnk, akkor az asszocilt adatbzis szint felhasznli fikok is trldnek.
DROP LOGIN Attila
Ha meg akarjuk nzni, hogy milyen loginjaink vannak, a sys.sql_logins segtsgvel lekrdezhetjk a rendszerben lv sszes logint. futtatnunk.
SELECT * FROM sys.sql_logins
Az eredmny:
125
Ezzel a szkripttel egy baj van: mgpedig az, hogy nem fog mkdni. Ltszlag minden rendben van, de mgsem. A tblt ugyan ltrehozzuk, de a szkript az insert-nl elhasal az albbi hibval:
Msg 40054, Level 16, State 1, Line 2 Tables without a clustered index are not supported in this version of SQL Server. Please create a clustered index and try again.
Ez azrt van, mert mindenkpp szksgnk van egy clustered index-re. rdemes kihasznlnunk, hogy az SQL Azure (akrcsak az Sql Server) alaprtelmezetten ltrehoz egy clustered indexet az elsdleges kulcsra. Mdostsuk a szkriptnket az albbiak szerint:
CREATE TABLE Developers(ID INT PRIMARY KEY, Name VARCHAR(20)) INSERT INTO Developers VALUES(1, 'Attila')
Ebben az esetben a tblnk szintn elkszl, s az insert is le fog futni. A Select, Insert, Update mveletekben nagy vltozs nincs. adatmdostsok a mr megszokott mdon trtnnek.
SELECT * FROM Developers;
A lekrdezsek s az
126
Ne feledjk engedlyezni azt, hogy az adatbzist azure szolgltatsok is elrhessk! 3. Egy Metro UI-os webes adatbzis menedzser fogad. Ez az SQL Server Management Studio kistestvre, amit brmikor, brhonnan elrhetnk (Tzfalszablyoknak megfelelen). Fontosabb funkcikat errl a felletrl is el tudunk rni. 4. Nzzk meg, mire j ez a fellet! Ha a kapcsoldsnl nem hatroztunk meg adatbzist, s rendszer szint felhasznlk vagyunk, akkor a bal fels sarokban kivlaszthatjuk, hogy melyik adatbzissal szeretnnk dolgozni. Most vlasszunk ki egy adatbzist, legyen a Northwind!
127
Lthat az is, hogy egy keress mez is rendelkezsnkre ll, hogy gyorsabban megtalljuk a szksges adatbzisunkat. Ez fleg nagy adatbzis szmnl jhet jl. 5. Amint kivlasztottuk az adatbzist, egy sszegz nzet jelenik meg.
Itt lthatunk minden fontosabb informcit az adatbzisunkrl. Mikor ksztettk, mi a Collation belltsa, hny aktv kapcsolat van vagy mekkora az adatbzis maximlis s felhasznlt mrete. 6. A fels mensorban a legfontosabb funkcikat talljuk. j lekrdezseket rhatunk, betlthetnk sql szkripteket, vagy akr j adatbzist is kszthetnk.
7. A New Query gombra kattintva betltdik egy szkript szerkeszt. Ide rhatjuk sajt lekrdezseinket, termszetesen ez a fellet is rendelkezik kdkiemelssel.
128
Nemcsak lekrdezseket fogalmazhatunk meg az SQL Azure Management felletn, hanem akr j adatbzist is kszthetnk, s tblkat is menedzselhetnk, st akr Data-Tier alkalmazsokat is feltlthetnk. 1. Kattintsunk a bal als sarokban az Administration menpontra, majd a megjelen oldalon a Create gombra! 2. A megjelen ablakban meg kell adnunk az adatbzisunk nevt, mrett s collation belltst. Ha ezt megtettk, kattintsunk a Submit gombra!
3. Nhny msodperc alatt elkszl az adatbzisunk. Itt nemcsak elkszthetjk, de akr a tblkat is megszerkeszthetjk. Kattintsunk a bal als sarokban a Design menpontra!
4. Itt tblt, nzetet, valamint trolt eljrst is ltrehozhatunk. Mi most egy egyszer tblt fogunk ltrehozni, kattintsunk a New table menpontra! 5. A megjelen ablakban adjuk meg a tbla nevt, ami most Administrators lesz! Hrom mez lesz benne: egy ID, ami elsdleges kulcs, az Is Identity kapcsolja true, valamint egy Name mez, illetve egy City mez amelyek nvarchar tpusak. (Mretk lnyegtelen.)
129
6. Ha megvagyunk, kattintsunk a Save gombra! 7. A tblnkat ltrehoztuk, de ez a tbla mg res. Ha mdostani vagy j adatot szeretnnk hozzadni, kattintsunk a Data menpontra! Az Add row gomb megnyomsval j rekordokat adhatunk a tblnkhoz. Adjunk nhny rekordot a tblnkhoz. A ments csak akkor kvetkezik be, ha a Save gombra kattintottunk. Nem ment automatikusan a rendszer.
Lthatjuk, hogy a fontosabb mveleteket elrhetjk webrl is. Nem kell hozz kliensalkalmazst telepteni. Hasznlata knny s gyors. Ez egy j s szp eszkz, de sszetettebb feladatokra az SQL Server Management Studio ajnlott.
130
131
ADATKEZELS OTTHON S A FELHBEN 1. Indtsuk el az alkalmazst (SQLAzureMW.exe)! 2. A megjelen ablakban most vlasszuk ki az Analyze / Migrate menpontbl az SQL Database-t, majd kattintsunk a Next gombra!
3. A megjelen Connect to Server ablakban adjuk meg a helyi/hlzati SQL Servernk elrhethsgt! Ez ebben az esetben a .\SQLEXPRESS, valamint hatrozzuk meg, hogy melyik adatbzist szeretnnk migrlni!
Ha ezzel megvagyunk, kattintsunk a Next gombra! 4. A megjelen ablakban kivlaszthatjuk, hogy mely objektumokat szeretnnk migrlni. Ezek a belltsok most jk szmunkra. Tovbbi belltsi lehetsgeink vannak az Advanced menpont alatt. Itt llthatjuk be pldul azt is, hogy csak a smt, csak az adatot, vagy a tbla smt s az adatot egytt szeretnnk migrlni. Kattintsunk a Next gombra! 5. Egy Scirpt Wizard Summary fogad minket. sszegzi, hogy mit s hogyan szeretnnk migrlni. Ha ez megfelel szmunkra, kattintsunk a Next gombra!
132
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA 6. Ezt kveten elindul az talakts. Ez az adatbzis mrettl fggen nhny msodperctl kezdve akr tbb percig is eltarthat. Ha sikeres volt az talakts, kattintsunk a Next gombra! (Az eredmnyt kimenthetjk *.rtf-be illetve *.sql-be is.)
7. Majd felugrik a Connect to Server ablak. Itt viszont most az SQL Azure-hoz kell kapcsoldnunk. Adjuk meg az SQL Azure kapcsoldsi belltsait, a szerver nevt, hozzfrsi adatait, az adatbzis nevt, majd kattintsunk a Connect gombra!
8. Ha
mindennel
megvagyunk,
kattintsunk
Next
gombra.
Megjelenik
egy
figyelmeztet ablak, ahol a Yes re kattintva elindul a szkript az SQL Azure-os adatbzisunkon. A folyamat az adatbzis mrettl fggen nhny percig is eltarthat. Ha sikerlt, s minden rendben zajlott, akkor az albbi kperny fogad:
133
9. Ha most megnzzk az adatbzisunkat, lthatjuk, hogy minden lehetsges adatot tmigrltunk az SQL Azure adatbzisba. szrevehetjk, hogy meglv adatbzisainkat nhny egyszer lps segtsgvel
tmozgathatjuk az SQL Azure-os adatbzisba. De ne feledjk, nemcsak SQL Serverbl lehet migrlni, lehetsgnk van SQL Azure-bl SQL Server-re, st akr SQL Azure s SQL Azure kztt is. Ezeket a lpseket SQL Server Management Studival is megtehetjk, csak nem segt annyit neknk, mint az SQL Azure Migration Wizard. SSMS esetben szkriptet kell generlnunk az adatbzisunkbl (meg kell adnunk, hogy SQL Azure kompatibilis szktipet ksztsen), majd az talaktott szkriptet az SQL Azure adatbzis szervern le kell futtatnunk. Termszetesen nemcsak SQL Server s SQL Azure kztt migrlhatunk. Lteznek klnbz eszkzk, amelyek elsegtik a migrlst akr nem Microsoft-os adatbzisokbl is. Ilyen pldaul az SSMA for MySQL, amely a MySQL adatbzis migrlst teszi lehetv SQL Azureba, vagy az SSMA for Access, amely az Access adatbzisokat migrlja az SQL Azure adatbzisunkba. Ezek Microsoft ltal tmogatott eszkzk!
134
135
ADATKEZELS OTTHON S A FELHBEN } } } } A pldban az egyszersg s az tlthatsg kedvrt a Connecton string-et begetjk a forrskdba. Ezt egy les alkalmazsnl clszer egy kls konfigurcis fjlban elhelyezni (App.config, web.config stb.). Ha a helyi SQL Server Express pldnyt szeretnnk elrni, akkor a Connection String az albbiak szerint nzne ki: @"Server=.\SQLEXPRESS;Database=Northwind;Trusted_Connection=Yes"; Lthat, hogy ez klasszikus connection string, ahol megadjuk az adatbzis szerver elrhetsgt, az adatbzis nevt, valamint a hitelest adatokat, ami ebben az esetben megegyezik a Windows rendszerbe bejelentkezett felhasznlval. SQL Azure esetn nem lehet Trusted_Connection-t hasznlni, csakis kizrlag felhasznlnv jelsz prossal tudjuk hitelesteni magunkat. Ha a fentebbi connection string-et lecserljk az albbira, akkor mr nem a helyi sql szerverbl fogja lekrdezni az adatokat, hanem az SQL Azure adatbzisunkbl. Ebben az esetben a connection string az albbiak szerint mdosul: "Server=e7m4zvqafx.database.windows.net;Database=Northwind;User ID=TuroczyX;Password=myPassword1"; Figyeljk meg, hogy ebben az esetben megadtuk az SQL Azure szervernk teljes elrsi tvonalt,, ami jelenleg az e7m4zvqafx.database.windows.net! A Database ugyanaz, mint a helyi pldny esetn. Itt hatrozzuk meg, hogy az adott adatbzis szerveren melyik adatbzist szeretnnk elrni, jelen esetben a Northwind-et. Az authentikci ebben az esetben csak felhasznlnv s jelsz birtokban trtnhet. Windows authentikcira nincs lehetsg. Ez ugyangy trtnik, mintha a helyi SQL serverbe authentiklnnk. Teht amit ltnunk kell, hogy csak az adatbzis cmt, valamint a hitelestsi adatainkat kell mdostani. Korbban a connection string valamivel sszetettebb volt. Pldul a Server neve eltt egy tcp: prefixum volt, valamint a felhasznlnevet is csak gy adhattuk meg, hogy kiegsztjk a szerver nevvel az albbi mdon: TuroczyX@e7m4zvqafx. Mra ez egyszersdtt, de nzzk meg ugyanezt a pldt a rgebbi connection string megadsval! "Server=tcp:e7m4zvqafx.database.windows.net;Database=Northwind;User ID=TuroczyX@e7m4zvqafx;Password=myPassword1"; Mind a ktfle megadsi mdszert alkalmazhatjuk, az SQL Azure elfogadja. Ha Entity Frameworkot hasznlunk, akkor a connection string az albbiak szerint mdosul: metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provide r=System.Data.SqlClient;provider connection string="data source=e7m4zvqafx.database.windows.net;initial catalog=Northwind;user id=TuroczyX;password=myPassword1;" Mint lthatjuk, csak a szerver cme klnleges, minden ms megegyezik a korbbi connection stringgel. 136
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA Figyeljnk arra, hogy ebben az esetben az adatbzisunkhoz tartoz connection string egy XML fjlban lesz letrolva! Mivel csak SQL Authentikcit tmogat az SQL Azure, ezrt ebben a fjlban szabadon olvashat mdon benne lesz a felhasznlnevnk-jelszavunk. Ezt termszetesen titkosthatjuk. Az albbi oldalon tovbbi informcikat tallhat errl: http://msdn.microsoft.com/en-us/library/89211k9b(v=vs.80).aspx.
137
7. A megjelen ablakban adjuk meg a Sync Group nevt! Ennek a nvnek egyedinek kell lennie! Mi most a SyncDemo nevet adjuk neki.
138
A MICROSOFT SQL SERVER 2012 S A MICROSOFT SQL AZURE ALKALMAZSA 8. A jobb oldalon megjelen Configuration vezrlnl bellthatjuk, hogy a szinkronizci milyen idkznknt trtnjen meg. Ezt mi most 10 percre lltjuk. A legkisebb bellthat szinkronizcis id 5 perc, a legnagyobb a maximum 1 hnap lehet. Itt llthatjuk be azt is, hogy konfliktus esetn a kliens (Helyi SQL Sever) vagy a HUB (SQL Azure) nyerjen. Ez a bellts projektfgg, de ennl a pldnl mi a Hub-ot rszestjk elnyben.
9. Ha belltottuk a neknk megfelel belltsokat, kattintsunk a kvetkez lps gombra! Msodik lpsknt meg kell adnunk a helyi SQL Server belltsait, amihez szinkronizlni szeretnnk. Kattintsunk a Click to add a SQL Server database menpontra!
10. Megjelenik az Add Database to Sync Group ablak. Az ablak als rszben van a Sync Direction bellts. Itt llthatjuk be a szinkronizci irnyt. Megadhatjuk, hogy csak a Hubra szinkronizljunk (Sync to the Hub), megadhatjuk, hogy csak a Hubrl szinkronizljunk a kliens fel (Sync fron the Hub) vagy pedig azt, hogy a szinkronizci ktirny legyen (Bi-directional). Mi most a ktirny szinkronizcit fogjuk vlasztani. Konfliktus esetn a Configuration vezrlnl megadott szablyok rvnyeslnek. A Database elemen bell vlasszuk ki az Add a new SQL Server database to the sync group menpontot! Ez akkor kell, ha ezeltt mg nem adtunk hozz ilyen csoportot a Sync Grouphoz. Ellenkez esetben akr ki is vlaszthatnnk a felajnlott listbl (Select from the existing sync member databases). Ha kivlasztottuk a neknk megfelel menpontot, kattintsunk a Next/Finish gombra!
139
11. A kvetkez ablakban meg kell hatroznunk, hogy van-e mr Client Sync Agentnk vagy sem. Amennyiben elszr hasznljuk ezt a Sync Groupot, nem lesz. Kattintsunk az Install a new Agent re, majd kattintsunk a Next gombra!
Ez az Agent egy kis alkalmazs, ami a szinkronizcit vgzi a helyi SQL Server s az Azure kztt. Ez az alkalmazs http protokollon keresztl kommunikl a felhvel. gy nem szksges semmilyen tzfa belltst mdostani a szmra. Ha a bngszbl elrjk ezt az oldalt, akkor az Agentnek is mkdnie kell. 12. A megjelen ablakban els lpsknt tltsk le az SQL Azure Data Sync Agent-et! (Jelenleg Preview vltozat rhet el!) Ezt az albbi cmrl is elrhetjk http://go.microsoft.com/fwlink/?LinkID=226849. 13. Miutn letltttk, teleptsk az alkalmazst! Az alkalmazs teleptse egyszer, mindssze egy fontos krdst tesz fel, mgpedig azt, hogy mi legyen annak a felhasznlnak a neve s jelszava, akinek a nevben a szinkronizcis szolgltats mkdni fog! Ennek a felhasznlnak el kell tudni rni az SQL Servert is!
140
14. Ha sikerlt a telepts, indtsuk el a Microsoft SQL Azure Data Sync Agent et! Ehhez rendszergazdai jogosultsgok kellenek! 15. Az alkalmazs elindulst kveten kattintsunk a Submit Agent Key menpontra! A megjelen ablakban egy Agent Key-t vr. Ezt az Agent Key-t a Windows Azure Management portlon talljuk.
16. Trjnk vissza a portlra, s az Install a New Agent ablakban a Step 2 -nl hatrozzuk meg az Agent nevt! Ez ltalban a gpnk hosztneve szokott lenni, de lehet ms is. Majd kattintsunk a Generate Agent Key menpontra! Ha sikerlt legenerlnia, msoljuk ki a kulcsot, s illesszk be a Microsoft SQL Azure Data Sync Agent-be, majd kattintsunk az OK gombra!
17. Ha ezzel megvagyunk, kattintsunk a Register menpontra! Ekkor felugrik az SQL Server Configuration ablak. Itt adhatjuk meg az SQL Servernk elrhetsgt. A Servernl az SQL Szerver cmt s szksg esetn pldnyt kell megadnunk. Ez jelen esetben a .\SQLEXPRESS, azaz a loklis gp SQLEXPRESS pldnya. A Database-nl azt az adatbzist kell megadnunk, amit szinkronizlni szeretnnk. Ebben a pldban ez a
141
ADATKEZELS OTTHON S A FELHBEN Northwind. Ha Windows Authentication-t vlasztunk, nem kell hitelestsi
informcikat megadni. SQL Authentikcinl az adott SQL Serverhez s/vagy adatbzishoz tartoz hitelestsi adatokat kell megadnunk.
18. Kattintsunk a Test Connection menpontra! Ha sikerl kapcsoldnia, akkor kattintsunk a Save gombra! Ekkor a felhasznli felleten megjelenik az az adatbzis, amit elzleg hozzadtunk.
19. Trjnk vissza a Management portalra, s az Install a New Agent ablakban kattintsunk a Next gombra! 20. Az Add Database to Sync Group ablakban kattintsunk a Get Database List gombra! Ekkor letlti az sszes adatbzis fejlcet, amit a kliensben hozzadtunk. Jelen esetben csak a Northwindes adatbzis fog megjelenni a lenyl listban. 21. Vlasszuk ki a szmunkra szksges adatbzist! (Jelen esetben azt az egyet, amit elzleg hozzadtunk.)
142
22. Ha ezzel megvagyunk, akkor kattintsunk a Finish gombra! 23. Meghatroztuk a kliens gpnk belltsait. Most mr csak a cl SQL Azure szerver belltsait kell megadnunk. Kattintsunk a Click to add a Windows Azure SQL databases as the Sync Hub gombra!
24. A megjelen ablakban meg kell hatroznunk az SQL Azure szervernk elrhetsgi adatait. Ezt kveten kattintsunk az Add gombra!
25. A varzsl ekkor ismt a konfliktuskezelst krdezi meg tlnk. Ugyanazt, amit korbban mr meghatroztunk. Ha nem akarunk ezen vltoztatni, kattintsunk a tovbb szimblumra!
143
ADATKEZELS OTTHON S A FELHBEN 26. Elrkeztnk az egyik legrdekesebb rszhez, a Dataset kezelshez. A megjelen ablakban kattintsunk az Edit Dataset gombra! 27. Felugrik a Define Dataset for Syncronization ablak. Itt hatrozhatjuk meg, hogy mely tblkat szeretnnk szinkronizlni. Mi most vlasszuk ki a Customers tblt! Azt is meghatrozhatjuk, hogy melyik oszlopot szinkronizljuk. Majd kattintsunk az OK gombra!
28. Amint visszatrtnk a f oldalra, lthatjuk az sszegzst. Majd kattintsunk a Deploy gombra!
Most mr minden lpst elvgeztnk. Ha most vltoztatunk valamit a helyi SQL Serveren, akkor az a kvetkez frisststl mr az SQL Azure-ban is ltszani fog. Abban az esetben, ha az SQL Azure adatbzisban trtnik vltozs, a loklis szerver is megkapja az j adatokat a kvetkez frisstskor. Ne feledjk, most a frissts ktirny (bi-directional)! Ha pedig tkzs van, a belltsaink szerint a HUB azaz az SQL Azure adatbzis fog nyerni.
144