sqlcmd mint SSMS light

Itt ülök az MVP summiton, és kiderült, hogy még itt is van olyan ember, aki nem tudja, hogy az sqlcmd nagyon sokoldalú. Valaki felvetette az igényt egy SSMS lightra, ahogy ő fogalmazott,

“egy Notepad, ami tud SQL lekérdezést futtatni”.

Megmutattam neki, hogy ez már létezik. Úgy hívják, hogy sqlcmd. Ez az osql utódja, a command-line interface SQL Serverhez. Ha még nem tudná valaki, CLI-mániám van, pedig Windows-on szocializálódtam. Szóval nézzük a varázslatot: Nyissunk egy parancssort (cmd.exe vagy powershell), és pötyögjünk:

Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Erik>sqlcmd -E -S .\mysql
1> :ed
'edit.com' is not recognized as an internal or external command,
operable program or batch file.
1> exit

C:\Users\Erik>SET SQLCMDEDITOR=notepad

C:\Users\Erik>sqlcmd -E -S .\mysql
1> :ed
1> select top 3 name, database_id, recovery_model_desc
2> from
3> sys.databases
4> GO
name
         database_id recovery_model_desc
------------------------------------------------------------------------------------------------------------------------
-------- ----------- ------------------------------------------------------------
master
                   1 SIMPLE
tempdb
                   2 SIMPLE
model
                   3 FULL

(21 rows affected)
1> :ed
1> select top 3 cast(name as varchar(30)) name, database_id, recovery_model_desc
2> from
3> sys.databases
4> GO
name                           database_id recovery_model_desc
------------------------------ ----------- ------------------------------------------------------------
master                                   1 SIMPLE
tempdb                                   2 SIMPLE
model                                    3 FULL

(3 rows affected)
1> 

Mi történt? Létrehoztam egy kapcsolatot az SQL Serverhez (igen, mysql az instancename, mert én használom), majd megpróbáltam szerkeszteni egyet az :ed paranccsal, de hibát kaptam, mivel az edit.com nem volt elérhető a gépemen. Erre kiléptem, beállítottam a SQLCMDEDITOR környezeti változóban a Notepad nevű szövegszerkesztőt, majd megint nekiugrottam. Ami sajnos így nem látszik, az az, hogy a 13. sornál kinyílt a notepad egy üres fájllal. Belegépeltem a 14-16. sort, majd bezártam a notepadot, és elmentettem a fájlt, amikor kérdezte, hogy mi legyen. Erre a fájl tartalma megjelent a sqlcmd-ben. utánaírtam, hogy GO, aztán lefutott. Mivel az adatbázisnév sysname, ami 128 karakter hosszú, ezért rondán nézett ki a kimenet, úgyhogy megint azt mondtam, hogy :ed. Erre megjelent az előzőleg végrehajtott batch a notepadban, és átírtam a megfelelő 1 sort, hogy ne legyen beláthatatlanul hosszú az output. Bezár-ment, enter, ott az eredmény.

Konklúzió: ez az egyik legnagyobb találmány.

Windows klónozás és SID duplikáció – monkeys and bananas

Az egyszeri történet szerint a céges szabályzatok a következőképpen készülnek: egyszer egy csoport majmot bezártak egy ketrecbe, ahol felakasztottak egy banánt. Akárhányszor az egyik majom hozzányúlt a banánhoz, mindegyik állat hidegzuhanyt kapott. Hamar leszokott mindenki a banán piszkálásáról. Egy idő után megszűnt a víz, a majmok már nem is próbálkoztak. Aztán kicserélték az egyik majmot, és az új fiú rögtön rápróbált a banánra, de alig ért a közelébe, a többiek elverték. Lassan rájött, hogy a banán tabu. Aztán kicserélték az összes majmot, és mindet megtanította az aktuális csoport, hogy ne próbálkozzon a banánnal. Végül nem volt egy majom sem a ketrecben, aki látta volna a zuhanyt, de a banánhoz senki sem nyúlt.

Az informatikában így születnek a csontvázak, amikről senki sem tudja, hogy miért vannak ott és úgy, de senki nem meri megmozdítani. Hogy ezt miért mesélem most el? Mert a múltkor tesztkörnyezetet építettem, és miközben a SID-eket ütögettem át a Sysinternals NewSID.exe programjával, azon gondolkoztam, hogy miért is kell pontosan átütni őket… Valami rémlett ,hogy amikor belépnek a domainbe, akkor jön a gubanc, meg amikor egymással beszélgetnek, de hogy pontosan mi, azt nem tudtam. Úgyhogy elkezdtem túrni a netet, és belefutottam Mark Russinovich friss blogbejegyzésébe: a NewSID.exe megszűnik. Mark a Windows lelkivilágának nagy ismerője, a Sysinternalsos progik (többek között a newsid.exe) fő szerzője. De miért szűnik meg ez a kütyü?

Az úgy kezdődött, hogy Mark kapott pár visszajelzést, amikor a newsid.exe gubancot okozott. Ezeket próbálta kibogozni, és arra gondolt, hogy jó lenne tudni, milyen gubancot előz meg a progi. Elment tehát a Windows fejlesztőkhöz, hogy pontosan milyen problémák fakadnak a duplikált SID-ből. És a fejlesztők némi töprengés meg kód átnézés után azt mondták: Semmilyen.

Apró öröm, hogy Mark pont előttem egy héttel gondolkozott el ezen a témán, de az eredmény így is mellbevágó. Remélem most már mindenki érti a majmokat.

T-SQL kütyü: a ROW_NUMBER()

Kedves mindenki! A menedzserkedés gépszíja rendesen berántott, de örömmel jelentem, hogy visszatértem, szebben, mint valaha. És őszebben is, de ez most mindegy. A közelmúltban még jobban rákattantam a Transact-SQL-re, az MSSQL programnyelvére, mrt rájöttem, hogy egy csomó dolgot tud, amivel én szívok szorgosan, mert nem olvasom el az asztalomon álló könyvet a SQL 2008 T-SQL kincsesbányájáról (by Itzik Ben-Gan, természetesen). Úgyhogy most T-SQL ömlengek.

A Transact-SQL nem kényeztette el azokat az embereket, akik szerettek volna olyanokat kérdezni, mint a második tíz legnagyobb ügyfél vagy csak egyszerűen minden harmadik alkalmazott, azaz olyat, ahol a recordsethez saját sorszámozás kellett. Ezt vagy nyakatekeréssel vagy temptáblába beleválogatósan, arra identity ráhelyezésesen (vagyis nyakatekeréssel) lehetett megoldani. De ez már a múlt ködös homályába vész, hiszen SQL 2005-ben megjelent a ROW_NUMBER() függvény, mely végre kiváló tulajdonságokkal vértezi fel az MSSQL-t, és kivesz egy érvet az ellendrukkerek táborában üldögélő Oracle (rownum) és MySQL (LIMIT) rajongók kezéből. Sőt.

A ROW_NUMBER() egy elég kemény eszköz, ami amellett, hogy képes sorszámot adni az egyes rekordokhoz, végre kényelmesen ÉS hatékonyan megoldhatóvá teszi az egyik visszatérő problémámat: válogassuk ki mondjuk egy értékesítés táblából minden értékesítő három legnagyobb összegű üzletkötését. Ez SQL 2000-ben tudott és akart rondán kinézni (megpróbáltam megírni, de annyira randa volt, hogy biztos elrontottam, úgyhogy nem merem felrakni), ellenben ROW_NUMBER() használatával elég átlátható lesz:

SELECT e.* FROM dbo.Ertekesites e
JOIN (SELECT id, ROW_NUMBER() OVER (PARTITION BY ErtekesitoID ORDER BY Vegosszeg DESC) AS Rangsor from dbo.Ertekesites) e2
ON e.id = e2.id
WHERE e2.rangsor < =3

A lényegi rész ez: ROW_NUMBER() OVER (PARTITION BY ErtekesitoID ORDER BY Vegosszeg DESC), illetve főleg az over utáni rész. A PARTITION BY ErtekesitoID azt mondja, hogy szedjük a rekordokat csoportokba ErtekesitoID szerint, mint a GROUP BY, de ne gyúrjuk egybe a rekordokat, hanem az egyes csoportokon belül sorszámozzuk őket, tehát pontosan annyi 1 értéket fogunk látni, ahány különböző ErtekesitoID van a táblában. A sorszámozás alapja pedig a Vegosszeg oszlop lesz, amint azt az ORDER BY clause (magyarosan klóz) mutatja, mégpedig csökkenő sorrendben. A záró WHERE feltételben jelezzük, hogy csak a három legjobbat szeretnénk látni mindenkitől.

Akinek ez megtetszett, az még cifrábbakat is talál ebben a témában, a Ranking Functions cím alatt a BOL-ban. Az NTILE() segítségével a rekordokat csoportosíthatjuk azonos vagy majdnem azonos méretű halmazokba, a RANK() rangsorol, úgy, mint az olimpián: ha két első van egyforma eredménnyel, nincs második, csak harmadik; a DENSE_RANK() pedig kedvesebben, nem hagy szünetet a számsorban: ha volt két első, akkor a harmadik a második lesz, vagyis 1,1,2 jön vissza (a RANK() 1,1,3-at ad).

Az SQLCMD

Az SQL 2005 egyik legpompásabb találmánya számomra kliensoldalon az SQLCMD vagy sqlcmd, attól függ, hol nézzük. Mostanában nagyon sok olyan munkát végzek, amit próbálok automatizálni, de még így is nagyon sok marad belőle (ezért nem írok blogot, mert gyakorlatilag másfél műszakban dolgozom). Ennek kapcsán kezdtem el jobban használni, kihasználni a sqlcmd lehetőségeit.

Sok Windows-on szocializálódott ember idegenkedik a karakteres képernyőtől, mert nehézkes meg nem lehet kattogtatni benne. Én meg szeretem, mert könnyebb félrekattintani, mint elgépelni (aki nem hiszi, az gondolja végig, hogy dobott-e már be egy foldert egy másikba tervei ellenére grafikus felületen, csak mert megcsúszott az egér). De kezdjük a hibrid oldalon: a Management Studio tud olyat, hogy a query window-t SQLCMD módban futtatja.


Continue reading ‘Az SQLCMD’ »

Deprecation warningok

(mostanság nem volt időm írni, mivel dolgozom :), ha nem a munkahelyemen, akkor pedig egy menedzsment adatbázist reszelek, ami reményeim szerint tök kényelmessé teszi a DBA életét)

Az SQL 2005 profilerben megjelent egy érdekes eseménycsalád, a Deprecation, azaz elavulás. Ez mutatja meg, hogy milyen dolgokat használunk az SQL Serverben azokból, amik meg lesznek szüntetve. Két esemény van benne: a Deprecation Announcement, ami azt mondja, hogy vigyázz, mert ezt rátettük a halállistára, és a Deprecation Final Support, ami azt mondja, hogy ez a lista tetején van, és a következő major release-ben már kiveszik. A következő major release SQL 2005-nél a 2008, 2008-nál pedig a 2008 R2.

Könnyű kipróbálni: indítsunk el egy profilert a Deprecation eseményekre (ha bepipáljuk a show all events boxot, akkor biztos meglesz), és nyissunk egy query window-t a profilerezett SQL szerveren! (Amennyiben a szervert használjuk másra is, mint játékra, akkor szűrjük le a profilert a query window spidjére, amit a status baron megtalálunk a felhasználónevünk után zárójelben.) Abba pedig írjuk bele a következőt:

SELECT name FROM msdb.dbo.sysjobs (NOLOCK)

Majd nézzük meg a profilert!

Specifying table hints without using a WITH keyword is a deprecated feature and will be removed in a future version.

Tehát működik. A haszna nyilvánvaló: migráció előtt látja az ember, hogy mivel lehet probléma, de én egy kicsit továbbmegyek ennél: éppen most készülök bedobni azt, hogy nem veszünk át olyan adatbázist vagy módosítást, ahol deprecation warning van. Javítsák ki most, ne legyen még egy csontváz a szekrényben, az már így is tele van…

Szerintem érdemes időnként futtatni egy kicsit, és megnézni, hogy miket kap el. Nálam a master, msdb és AdventureWorks adatbázisokat :) Szóval érdemes szűrni felhasználói adatbázisokra (databaseid > 4) éles üzemben, a Microsoft meg majd rendet tesz a rendszeradatbázisokban.