Archive for October, 2010

[PL] Only the good die young…

VN:F [1.7.9_1023]
Rating: 0.0/5 (0 votes cast)

imageNiestety, po raz kolejny okazało się, że nie znamy dnia ni godziny. W dniu dzisiejszym dotarła do mnie szokująca wiadomość. Zmarł Piotr Dobrowolski, założyciel i jeden z liderów Krakowskiej Grupy Deweloperów .NET, swego czasu Microsoft MVP, pierwszy polski Mistrz .NET (2004), ekspert w dziedzinie programowania, prelegent na licznych konferencjach o tematyce programistycznej, prywatnie mąż, ojciec i dobry człowiek. Piotr zmarł po ciężkiej walce z chorobą nowotworową. Trudno znaleźć słowa, gdy odchodzi ktoś, kogo miało się okazję poznać osobiście, zwłaszcza ktoś tak młody (Piotr przeżył nieco ponad 30 lat). Dlatego po prostu uczczę odejście Piotra tym wpisem, chwilą modlitwy i minutą ciszy. Na zawsze pozostanie w mojej pamięci.

PS. O nierównej walce Piotra z chorobą można poczytać na blogu: http://itsyouormenow.blogspot.com.

[PL] SQL Server–Obejście problemu z xp_cmdshell

VN:F [1.7.9_1023]
Rating: 0.0/5 (0 votes cast)

Procedura rozszerzona xp_cmdshell  dostępna w SQL Server bywa przedmiotem dyskusji na temat bezpieczeństwa i tego, czy system zarządzania bazami danych powinien mocno integrować się z systemem operacyjnym. Domyślnie procedura ta jest wyłączona dzięki jednej z opcji serwera, ale często jest włączana i wykorzystywana, głównie do uruchamiania zewnętrznych aplikacji z poziomu kodu T-SQL.

Ostatnio natknąłem się na problem, którego rozwiązanie zajęło mi chwilę. I postanowiłem, że swoim rozwiązaniem się podzielę.

Na początek włączamy xp_cmdshell na instancji SQL Servera:

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
GO
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
GO

Próba uruchomienia xp_cmdshell:

EXEC master.dbo.xp_cmdshell 'dir "C:\Program Files"';
GO

Wynikiem jest lista katalogów i plików z folderu Program Files na dysku C:. Warto tu zwrócić uwagę na fakt, że parametr polecenia dir (listowanie plików i katalogów w systemie Windows) został otoczony cudzysłowami, ponieważ zawierał spację (gdyby cudzysłowów nie dać, napis zostałby potraktowany jako dwa parametry).

Problem pojawia się, gdy chcemy uruchomić zewnętrzną aplikację / wsad (.bat lub .cmd), do której ścieżka zawiera spacje z parametrem, w którym spacje również występują. Przykład:

EXEC master.dbo.xp_cmdshell '"D:\SQL Server\ProcessCube.bat" "My DB" "My Cube"';
GO

Próba wykonania powyższego kodu, przy założeniu, że wsad ProcessCube.bat naprawdę istnieje w lokalizacji D:\SQL Server, zakończy się komunikatem:

Nazwa ‘D:\SQL’ nie jest rozpoznawana jako polecenie wewnętrzne lub zewnętrzne, program wykonywalny lub plik wsadowy.

Szczerze mówiąc, nie wiem, jaka jest przyczyna problemu, ale obstawiam jakiś błąd w xp_cmdshell.

Obejście problemu jest dość proste:

EXEC master.dbo.xp_cmdshell 'call "D:\SQL Server\ProcessCube.bat" "My DB" "My Cube"';
GO

Trzeba zapewnić, że pierwsze w ciągu znaków podawanym jako parametr procedury xp_cmdshell będzie polecenie systemowe (do którego nie potrzeba podawać pełnej ścieżki). Może to być, jak powyżej, polecenie CALL (uruchamianie wsadu z innego wsadu – tak naprawdę można w ten sposób uruchamiać także wsady z konsoli).

Ot, czym czasem musi zajmować się konsultant Business Intelligence ;-)

[PL] Wydarzenie – O mitach na spotkaniu PLSSUG

VN:F [1.7.9_1023]
Rating: 0.0/5 (0 votes cast)

Z wielką przyjemnością zapraszam na moją prezentację poświęconą mitom w SQL Server. Prezentacja będzie jedną z dwóch sesji w ramach 49. spotkania warszawskiego oddziału Polskiej Grupy Użytkowników SQL Server (PLSSUG). Spotkanie odbędzie się 4 listopada (czwartek) w warszawskiej siedzibie firmy Microsoft (Al. Jerozolimskie 195A). Rozpocznie się o godzinie 18:00. Wstęp na spotkanie wolny (link do rejestracji na stronie wydarzenia).

Moja sesja będzie bazowała na dokumencie przygotowanym przez znanego eksperta – Paula S. Randala. Drugą prezentację w czasie spotkania poprowadzi Mariusz Koprowski (temat – VS nie tylko dla programistów .NET).

Zapraszam!

[PL] SQL Server – Migracja usługi Database Mail

VN:F [1.7.9_1023]
Rating: 0.0/5 (0 votes cast)

Jakiś czas temu na forum portalu WSS.pl padło pytanie, czy można przenieść konfigurację usługi Database Mail na SQL Server 2005 / 2008 / 2008 R2. Odpowiedziałem wówczas, że pewnie można to zrobić skryptując dane z tabel w bazie msdb. Postanowiłem, że napiszę kod do takiego skryptowania. Oto on:

set nocount on;
print '-- *** Enabling DBMail ***

';
print 'EXEC sp_configure ''show advanced options'', 1;
RECONFIGURE;
GO
EXEC sp_configure ''Database Mail XPs'', 1;
RECONFIGURE;
GO

';
print '-- *** Configuration ***';
select 'EXEC msdb.dbo.sysmail_configure_sp
  @parameter_name = ' + QUOTENAME(paramname, '''') + ',
  @parameter_value = ' + QUOTENAME(paramvalue, '''') + ',
  @description = ' + ISNULL(QUOTENAME(description, ''''),'NULL') + ';'
from msdb.dbo.sysmail_configuration;
print '-- *** Profiles ***';
select 'EXEC msdb.dbo.sysmail_add_profile_sp
  @profile_name = ' + QUOTENAME(name, '''') + ',
  @description = ' + ISNULL(QUOTENAME(description, ''''),'NULL') + ';'
from msdb.dbo.sysmail_profile;
print '-- *** Accounts ***';
select
  'EXEC msdb.dbo.sysmail_add_account_sp
  @account_name = ' + QUOTENAME(a.name, '''') + ',
  @description = ' +  ISNULL(QUOTENAME(a.description, ''''),'NULL') + ',
  @email_address = ' + QUOTENAME(a.email_address, '''') + ',
  @replyto_address = ' + ISNULL(QUOTENAME(a.replyto_address, ''''),'NULL') + ',
  @display_name = ' + ISNULL(QUOTENAME(a.display_name, ''''),'NULL') + ',
  @mailserver_name = ' + QUOTENAME(s.servername, '''') + ',
  @mailserver_type = ' + QUOTENAME(s.servertype, '''') + ',
  @port = ' + CONVERT(varchar(20), s.port) + ',
  @username = ''<ACCOUNT ' + a.name + ' - USERNAME,,>'',
  @password = ''<ACCOUNT ' + a.name + ' - PASSWORD,,>'',
  @use_default_credentials = ' + CONVERT(char(1), s.use_default_credentials) + ',
  @enable_ssl = ' + CONVERT(char(1), s.enable_ssl) + ',
  @account_id = ' + CONVERT(char(1), s.account_id) + ';'
from msdb.dbo.sysmail_account a
inner join msdb.dbo.sysmail_server s
on a.account_id = s.account_id;
print '-- *** Add accounts to profiles ***';
select
  'EXECUTE msdb.dbo.sysmail_add_profileaccount_sp
  @profile_name = ' + QUOTENAME(p.name, '''') + ',
  @account_name = ' + QUOTENAME(a.name, '''') + ',
  @sequence_number = ' + CONVERT(varchar(20), pa.sequence_number) + ';'
from msdb.dbo.sysmail_profileaccount pa
inner join msdb.dbo.sysmail_account a
on pa.account_id = a.account_id
inner join msdb.dbo.sysmail_profile p
on pa.profile_id = p.profile_id
print '-- *** Grant access to the profile to the DBMailUsers role ***';
select
  'EXECUTE msdb.dbo.sysmail_add_principalprofile_sp
  @profile_name = ' + QUOTENAME(pr.name, '''') + ',
  @principal_id = ' + CONVERT(varchar(20), p.principal_id) + ',
  @is_default = ' + CONVERT(char(1), s.is_default) + ';'
from msdb.dbo.sysmail_principalprofile s
inner join msdb.sys.database_principals p
on s.principal_sid = p.sid
inner join msdb.dbo.sysmail_profile pr
on s.profile_id = pr.profile_id;

Po kolei:

  • na początek skryptuję wywołanie procedury sp_configure i włączenie samej usługi Database Mail,
  • następnie skryptuję serię wywołań procedury msdb.dbo.sysmail_configure_sp, która ustawia opcje Database Mail’a,
  • w kolejnym kroku skryptowane są kolejno: profile (wywołania msdb.dbo.sysmail_add_profile_sp), konta (msdb.dbo.sysmail_add_account_sp) oraz przypisania kont do profili (wywołania msdb.dbo.sysmail_add_profileaccount_sp),
  • na sam koniec skryptowane jest dodawanie odpowiednich użytkowników do roli DBMailUsers (wywołania msdb.dbo.sysmail_add_principalprofile_sp).

Użycie kodu wygląda następująco:

  1. Używając Management Studio uruchom kod na instancji, z której ustawienia Database Mail chcesz zeskryptować. Wynik zapisuj do tekstu.
  2. Skopiuj wynik zapytania do nowego okna skryptu w Management Studio.
  3. Zastąp niezbędne parametry (wciskając Ctrl+Shift+M i wypełniając kolumnę Value) odpowiednimi nazwami użytkowników oraz hasłami (danych wrażliwych, takich jak hasła, oczywiście nie trzymamy w skryptach).
  4. Uruchom uzupełniony kod na instancji docelowej.
  5. Sprawdź, czy działa wysyłanie wiadomości e-mail z wykorzystaniem usługi Database Mail.

Jak dotąd powyższy kod się sprawdzał. Od jakiegoś czasu używam go produkcyjnie. W razie problemów, proszę o kontakt.

[PL] Moim zdaniem – Certyfikaty zawodowe w branży IT

VN:F [1.7.9_1023]
Rating: 5.0/5 (1 vote cast)

Tytułem wstępu

Po sporym powodzeniu wpisu dotyczącego pracy i licznych głosach nakłaniających mnie do pisania na temat moich przemyśleń niekoniecznie związanych z technologiami postanowiłem, że na stałe zawita na moim blogu nowa seria pod zbiorczym tytułem “Moim zdaniem”. Tytuł serii najlepiej oddaje, jak powinny być traktowane wpisy w jej ramach publikowane – jako moje własne, niekoniecznie obiektywne, przemyślenia.

Certyfikaty – i o co tyle hałasu?

MCSE, MCP, CCNA i tym podobne trzy- i czteroliterowe skróty istnieją od dawna. Początkowo nie zaistniały w świadomości ludzi z branży IT, ale dzisiaj stały się nieodłącznym elementem naszego życia. Certyfikaty w IT zdobywamy na ogół po zdaniu jednego lub więcej egzaminów przy komputerze. Na ogół egzaminy te mają formę testu z ograniczoną liczbą gotowych odpowiedzi, a zadaniem zdającego jest wskazanie odpowiedzi poprawnych. Brzmi banalnie i czasem jest dość łatwo taki egzamin zdać. Z tego powodu i kilku jeszcze innych padają liczne pytania o sens zdobywania certyfikatów. Ale o tym później.

Po co producenci oprogramowania, jak na przykład firma Microsoft, przeznaczają pokaźne budżety na rozwój ścieżek certyfikacyjnych (ktoś musi opracować pytania, ktoś inny musi je zweryfikować, jeszcze ktoś musi do tego wszystkiego dorobić ideologię i marketing…)? Przecież na pewno jedynym powodem nie jest chęć wyłuskania z rzeszy specjalistów IT tych osób, które biegle posługują się danym systemem czy narzędziem. Odpowiedź wydaje się oczywista. Odpowiednio “nakręcony” rynek certyfikatów to jeszcze jeden sposób zwiększenia sprzedaży oprogramowania. Na przykład, większa liczba specjalistów w zakresie systemu SQL Server może przełożyć się na popularność tegoż produktu w firmach.

To pass or not to pass…

Podstawowe pytania, jakie zadaje sobie specjalista IT, brzmią: “Czy powinienem/powinnam zdawać egzaminy certyfikacyjne?” oraz “Jakie certyfikaty powinny znaleźć się w mojej ścieżce rozwoju?”.

Z jednej strony można przeczytać o spektakularnych karierach ludzi, których CV są naszpikowane “papierami”. Z drugiej strony padają głosy, że certyfikat może dzisiaj zdobyć każdy, bo większość egzaminów nie jest trudna do zdania, a w sieci aż roi się od wszelkich “pomocy”, nie zawsze legalnych, które jeszcze zwiększają szanse zdającego. A więc? Warto, czy nie?

Moim zdaniem, warto. Być może jest to pójście z prądem (“bo zdają inni”), być może egzaminy nie są trudne, być może dzisiaj każdy może zostać MCSE. Ale… to samo można powiedzieć o klasycznej edukacji wyższej. Teoretycznie każdy może iść na studia i zostać dyplomowanym informatykiem, elektrykiem czy socjologiem. Studia wymagają oczywiście nakładów finansowych i czasu poświęconego na naukę przedmiotów niekoniecznie przydatnych w życiu zawodowym. A zatem studia to swoista inwestycja w siebie. Poza tym, na studiach człowiek nabywa pewne cenne umiejętności (zdolność negocjacji z wykładowcami ;-), asertywność – imprezować z kumplami czy uczyć się do egzaminu?). I podobnie jest z certyfikatami w IT. Trzeba zainwestować pieniądze w egzaminy i poświęcić czas na naukę wiedząc, że nie wszystko, czego uczymy się do egzaminów, przyda nam się w pracy (w zasadzie można śmiało założyć, że przyda nam się marny procent…). Natomiast trzeba pamiętać, że tak, jak często na rozmowach o pracę kandydat jest eliminowany z dalszych etapów na skutek braków w wykształceniu (tak, tak, czasem ten nieszczęsny magister w CV może robić dużą różnicę), tak samo w pewnych sytuacjach czy środowiskach może się zdarzyć, że to właśnie certyfikat zawodowy, a właściwie jego brak, będzie przyczyną fiaska naszych starań o pracę. Widziałem już polskie firmy, które nie rozmawiały z kandydatami bez stosownego certyfikatu. Papierek był przepustką do rozmowy kwalifikacyjnej. Co ciekawe, zdarzają się na krajowym rynku firmy i organizacje, które w przetargach na grube miliony wymagają od firm w nich startujących, by w zespole miały osoby z konkretnymi certyfikatami.

Oczywiście, sam certyfikat nie jest gwarancją tego, że dana osoba posiada niezbędną wiedzę i doświadczenie. Znam przypadki, gdy delikwent na rozmowie kwalifikacyjnej świecił w CV listą certyfikatów, a brakowało mu podstawowej wiedzy. Życie brutalnie weryfikuje, kto w jaki sposób i po co zdobywa papierowe potwierdzenie swoich kwalifikacji. I niestety, certyfikowany po takiej wpadce zalicza zawsze większego “buraka”  niż ten, kto certyfikatów w resume nie ma :-)

Jakie certyfikaty są dla Ciebie? Na to pytanie ja odpowiedzi Ci nie udzielę. Każdy producent, który ma swój program certyfikacyjny, na ogół w dość czytelny sposób informuje o tym, dla kogo przeznaczone są poszczególne certyfikaty. Ja na przykład skupiam się obecnie na certyfikatach dokumentujących moją wiedzę z zakresu systemu Microsoft SQL Server. Z tym systemem pracuję, w nim się specjalizuję. I zdecydowanie najlepiej właśnie w ten sposób wyznaczać swoje cele w zakresie certyfikacji zawodowej – idź za swoją specjalizacją. Odradzam zdawanie “wszystkiego, co się rusza”. Niezręcznie potem tłumaczy się komuś w czasie rozmowy kwalifikacyjnej, że ten i tamten certyfikat mamy, bo… jakoś tak wyszło. Sam to przerabiałem, ponieważ w ośrodkach szkoleniowych (pracowałem dawniej jako szkoleniowiec) często nowe kompetencje firmy są uzależnione od uzyskanych przez pracowników certyfikatów, więc trenerzy są zobligowani do zdawania egzaminów nieco odbiegających tematycznie od ich zainteresowań.

Sumienie a sprawa certyfikatów

Wspomniałem o tym, że niektórzy zdają egzaminy certyfikacyjne korzystając z nielegalnych pomocy (pytania są wynoszone z sal egzaminacyjnych i powstaje z nich kompilacja, tzw. braindump). Często czytam na różnych forach, jak bardzo ludzie są oburzeni tym faktem. Ale nikt jakoś nie jest oburzony faktem, że co roku uczelnie wyższe opuszcza duże X tysięcy absolwentów, z których zapewne pokaźny procent “przejechał” przez studia na sporym szczęściu i dobrze wykorzystanych ściągawkach :-) Nie pochwalam rzecz jasna nielegalnych pomocy. Uważam, że zdane przy ich pomocy egzaminy to prosta droga do obniżenia wartości certyfikatów. Natomiast koniec końców to sprawa sumienia zdających. Oszukujesz na egzaminach? Najbardziej oszukujesz samego siebie. Jaki z Ciebie będzie specjalista po zdaniu tych paru egzaminów? Być może przydałby się w zestawie certyfikatów Microsoftu (najpopularniejsze egzaminy, więc do nich jest najwięcej nielegalnych pomocy) jeszcze jeden certyfikat – MCBDM (Microsoft Certified Braindump Memorizer) ;-) Inna sprawa, że czasem mam wrażenie, że firmy IT, które prowadzą swoje własne systemy certyfikacji, nie dokładają wszelkich możliwych starań do tego, by zdanie egzaminu wyłącznie na “braindumpach” było niemożliwe (przecież wystarczy duża losowość pytań i odpowiedzi czy stosownie duża pula pytań). Czyżby obawa, że im trudniejsze do zdania egzaminy, tym mniejsze z nich wpływy? :-)

Certyfikat a wiedza ekspercka

Czasem spotykam się ze stwierdzeniem, że certyfikaty są dla ludzi, którzy w danej technologii posiedli “czarny pas”. Nic bardziej mylnego. Przecież nie da się sprawdzić w kilkudziesięciu pytaniach, czy osoba zdająca egzamin ma produkt czy technologię w małym palcu. Nie czarujmy się, egzaminy są dla ludzi! Zdawać może każdy i faktycznie pobudki zdających są bardzo różne. A to zdają dlatego, bo “w firmie kazali”, a to dlatego, bo znalazł się darmowy voucher ze zniżką 100%. Szczerze? Żaden powód nie jest zły. Byleby uczciwie podejść do tematu i zapoznać się z zagadnieniami wymaganymi na egzaminie. Tak zdobyta wiedza (laby, książki, szkolenia) różni się od tej, którą zdobywamy na projektach / wdrożeniach. To prawda. Ale trzeba też pamiętać, że najczęściej zakres wiedzy wymagany na egzaminie jest tak szeroki, że praktycznie nie sposób wszystkich rzeczy “dotknąć” w życiu zawodowym. Stąd nie należy z politowaniem patrzeć na osoby, które idą na egzamin po przetrenowaniu nowego systemu na maszynie wirtualnej. Taka osoba, o ile poważnie podeszła do sprawy i “przeklikała” porządnie system, dysponuje teoretyczną wiedzą, która może okazać się nieoceniona w rzeczywistych problemach stawianych “na produkcji”. A więc certyfikat a wiedza ekspercka to dwie różne sprawy. Oczywiście, wyjątek stanowią te certyfikaty, do których wymagania stawiane są na naprawdę wysokim poziomie, a egzaminy przypominają bardziej pranie mózgu (np. Microsoft Certified Master).

Społeczności osób certyfikowanych

Nie bez znaczenia dla popularności certyfikatów są z pewnością wszelkie społeczności, które powstają wśród osób legitymujących się tym samym certyfikatem. Przykładami takich społeczności są chociażby nie tak żywy już dzisiaj SEClub czy świeżo powstały twór – MCT Europe. Takie inicjatywy znakomicie komponują się z programami certyfikacyjnymi i powinny być solidnie wspierane przez firmy prowadzące owe programy. Ludzie należący do takich społeczności upatrują w tego typu zrzeszeniach wielu szans – czy to na zdobycie cennych kontaktów, czy – być może w dalszej perspektywie – na ciekawą pracę. Ja właśnie zgłosiłem chęć przynależenia do grupy MCT Europe, która zrzesza certyfikowanych trenerów Microsoft ze starego kontynentu. Grupa daje wiele w kontaktach z wieloma instytucjami i firmami. Na przykład założycielom MCT Europe udało się porozumieć z siecią hoteli, dzięki czemu trenerzy należący do organizacji otrzymują zniżki na noclegi. Takich “marchewek” w społecznościach powstałych wokół certyfikatów może być dowolnie wiele – wszystko zależy od osób tworzących daną grupę.

Certyfikat certyfikatem…

… a w pracy i tak liczą się najczęściej zupełnie inne umiejętności. Na przykład umiejętności interpersonalne, zdolności miękkie (negocjacje z klientem – tu raczej nie przyda Ci się żaden papier…). I – najważniejsze – profesjonalizm. A profesjonalizmu nie zapiszesz w CV i nie zdobędziesz na szkoleniach. To po prostu Twoje podejście do pracy i ludzi, z którymi przyszło Ci pracować / współpracować. A certyfikaty? Mogą się przydać i na pewno trzeba rozważyć ich uzyskanie, jeżeli nie chcesz, by Twoje CV decydowało za Ciebie o Twojej przyszłości ;-)

PS. A co do moich planów a propos certyfikatów – szykuję się właśnie do zdania pierwszego z dwóch egzaminów wymaganych do uzyskania tytułu Microsoft Certified IT Professional: Business Intelligence Developer 2008. Trzymajcie kciuki ;-)

[PL] Konkurs T-SQL – Wyniki

VN:F [1.7.9_1023]
Rating: 5.0/5 (1 vote cast)

Po długich testach pora na ogłoszenie wyników konkursu T-SQL “Liga piłkarska”. W konkursie wzięło udział 17 osób, które nadesłały ponad 60 rozwiązań. Rekordzista – Leszek Gniadkowski – nadesłał 15 rozwiązań. Ale zdarzały się też osoby, które nadesłały jedno, ale za to całkiem nieźle wypadające w testach zapytanie.

Na początek słowo o teście finałowym skierowane głównie do finalistów. Polegał on na uruchamianiu Waszych skryptów na trzech zestawach danych – 20, 50 i 100 drużyn. Dwa z finałowych rozwiązań musiałem wykluczyć z testów już po pierwszym podejściu do zestawu 20 drużyn, ponieważ nie mogłem doczekać się wyników… Pozostałe zostały poddane testom wielokrotnym (na każdym zestawie puszczałem skrypty w pętli po 10 razy, a same pętle były puszczone po 5 razy – czyli w sumie każdy skrypt był uruchomiony 50 razy na każdym zestawie danych). Przed każdym uruchomieniem skryptu czyściłem bufor danych i plan cache, żeby uniknąć przypadkowości. Całość testu przeprowadziłem na laptopie o parametrach: Core 2 Duo (ale tylko jeden procesor używany przez SQL Server) + 4 GB RAM (1 GB przydzielony na bufor danych). Zapytania były monitorowane przez SQL Trace, z którego następnie wyciągałem średnie wartości czterech kryteriów (duration, CPU, reads, writes) dla poszczególnych testów (“20”, “50” i “100”). Dla każdego testu robiłem osobną tabelę. Oto owe tabele:

Test “20”

Lp Rozwiązanie D C R W RD RC RR RW T
1 Gniadkowski_Leszek_v15.sql 42602 41 22 0 1 1 1 1 4
2 Gniadkowski_Leszek_v10.sql 52062 45,2 25 0 2 2 2 1 7
3 Gniadkowski_Leszek_v12.sql 52642 45,8 25 0 3 3 2 1 9
4 Nowakowski_Marcin_v04.sql 121766 108,4 161 0 4 4 9 1 18
5 Powichrowski_Marek_v12.sql 177409,4 146,8 37 0 7 7 4 1 19
6 Przeliorz_Tomek_v02.sql 156648,2 135,6 325 0 6 6 11 1 24
7 Zmuda_Katarzyna_v01.sql 125126,2 113,6 633 0 5 5 14 1 25
8 Nowakowski_Marcin_v03.sql 255193,6 226,8 314 0 8 11 10 1 30
8 Sliwa_Krzysiek_v02.sql 262054 223,6 126 0 11 10 8 1 30
10 Pater_Rafal_v03.sql 278655,4 251,6 84 0 12 13 5 1 31
11 Poniatowski_Aleksander_v01.sql 282295,2 241,4 120 0 13 12 7 1 33
12 Pater_Rafal_v04.sql 300416,4 257,8 84 0 14 14 5 1 34
13 Powichrowski_Marek_v13.sql 261114 213,2 1123 0 10 9 17 1 37
14 Przeliorz_Tomek_v01.sql 258753,8 212,6 4771 0 9 8 20 1 38
15 Gailard_Pawel_v02.sql 423823,2 389,8 581 0 15 15 13 1 44
16 Pakulski_Maciej_v03.sql 1207088,2 998,2 578 0 17 18 12 1 48
17 Kulczynski_Przemyslaw_v04.sql 1109802,6 942,6 3066 0 16 16 18 1 51
18 Kulczynski_Przemyslaw_v01.sql 1225069,2 983 3120 0 18 17 19 1 55
19 Grabowska_Katarzyna_v04.sql 1680515,2 1327,6 1092 0 20 19 16 1 56
20 Pakulski_Maciej_v02.sql 3367231,6 2823,8 694 0 22 22 15 1 60
21 Sowa_Piotr_v10.sql 1901548 1603 6652 0 21 21 21 1 64
22 Cerekwicki_Cezary_v01.sql 1677855 1425 64485,8 2,8 19 20 22 22 83
23 Waluszko_Bartlomiej_v02.sql - - - - - - - - -
24 Jacewicz_Lukasz_v02.sql - - - - - - - - -

Legenda:

D – średnie duration
C – średnie CPU
R – średnie reads
W – średnie writes
RD – miejsce w kryterium duration
RC – miejsce w kryterium CPU
RR – miejsce w kryterium reads
RW – miejsce w kryterium writes
T – suma miejsc z wszystkich kryteriów (im mniejsza, tym lepiej)

Test “50”

Lp Rozwiązanie D C R W RD RC RR RW T
1 Gniadkowski_Leszek_v15.sql 71823,2 64,2 40 0 1 1 1 1 4
2 Gniadkowski_Leszek_v10.sql 78343,8 69,8 49 0 2 2 2 1 7
3 Gniadkowski_Leszek_v12.sql 78464 73,8 49 0 3 3 2 1 9
4 Nowakowski_Marcin_v04.sql 179449,6 160,4 85 0 4 4 4 1 13
5 Sliwa_Krzysiek_v02.sql 317637,4 293,2 121 0 6 6 6 1 19
6 Poniatowski_Aleksander_v01.sql 332818,2 295,4 103 0 7 7 5 1 20
7 Przeliorz_Tomek_v02.sql 201770,8 181,4 925 0 5 5 13 1 24
8 Zmuda_Katarzyna_v01.sql 414422,8 386,2 135 0 8 8 9 1 26
9 Pater_Rafal_v03.sql 604693,6 544,2 132 0 11 11 7 1 30
10 Nowakowski_Marcin_v03.sql 450784,6 404,4 733 0 9 9 12 1 31
11 Gailard_Pawel_v02.sql 499387,8 459 366 0 10 10 11 1 32
11 Pater_Rafal_v04.sql 605213,6 570,2 132 0 12 12 7 1 32
13 Grabowska_Katarzyna_v04.sql 2113640 1714,6 254,2 0 15 15 10 1 41
13 Powichrowski_Marek_v12.sql 753222 589,4 1597 0 13 13 14 1 41
15 Powichrowski_Marek_v13.sql 1063860 877 5019 0 14 14 15 1 44
16 Przeliorz_Tomek_v01.sql 2205305 1838,8 34441 0 16 16 17 1 50
17 Pakulski_Maciej_v03.sql 7804265,2 6686,8 27196 0 19 19 16 1 55
18 Pakulski_Maciej_v02.sql 39569582,4 36671,4 199326 0 22 22 21 1 66
19 Sowa_Piotr_v10.sql 6398825 5377,8 56028 39,8 17 17 18 20 72
20 Kulczynski_Przemyslaw_v01.sql 11576081,4 10360 133432 29,6 20 20 19 19 78
21 Cerekwicki_Cezary_v01.sql 7629655,6 6561,2 598566,4 409,6 18 18 22 22 80
22 Kulczynski_Przemyslaw_v04.sql 11873518,2 10476 152408 41,8 21 21 20 21 83
23 Waluszko_Bartlomiej_v02.sql - - - - - - - - -
24 Jacewicz_Lukasz_v02.sql - - - - - - - - -

Test “100”

Lp Rozwiązanie D C R W RD RC RR RW T
1 Gniadkowski_Leszek_v15.sql 169068,6 153,4 112 0 1 1 1 1 4
2 Gniadkowski_Leszek_v10.sql 192850,2 158,8 145 0 2 2 2 1 7
3 Gniadkowski_Leszek_v12.sql 202850,6 165,4 145 0 3 3 2 1 9
4 Nowakowski_Marcin_v04.sql 364540 316,8 277 0 4 4 4 1 13
5 Poniatowski_Aleksander_v01.sql 548570,2 446,6 343 0 7 6 7 1 21
6 Sliwa_Krzysiek_v02.sql 497087,6 456,4 409 0 6 7 8 1 22
7 Przeliorz_Tomek_v02.sql 411842,6 368,2 3165 0 5 5 14 1 25
8 Pater_Rafal_v03.sql 1078200,8 928,2 324 0 11 11 5 1 28
9 Gailard_Pawel_v02.sql 834646,8 767,4 673 0 9 9 11 1 30
9 Pater_Rafal_v04.sql 1123663,2 949,6 324 0 12 12 5 1 30
9 Zmuda_Katarzyna_v01.sql 909931 813,6 423 0 10 10 9 1 30
12 Nowakowski_Marcin_v03.sql 804165 530,4 464,2 0,2 8 8 10 13 39
13 Grabowska_Katarzyna_v04.sql 3773755 3151,2 734,4 0 16 16 12 1 45
14 Pakulski_Maciej_v03.sql 1716357,2 1425,4 736,8 0,6 13 13 13 14 53
15 Powichrowski_Marek_v12.sql 1990753 1704,4 23022 32 14 15 15 15 59
16 Powichrowski_Marek_v13.sql 2326372,4 1690,6 23814,6 32 15 14 16 15 60
17 Przeliorz_Tomek_v01.sql 12467972,4 11131,4 266163 78 17 17 18 18 70
18 Sowa_Piotr_v10.sql 27219956 25120,2 304784 411,8 18 18 19 20 75
19 Pakulski_Maciej_v02.sql 72426161,8 68060,4 522223 52 20 20 21 17 78
20 Kulczynski_Przemyslaw_v01.sql 73221107 68773,2 239710,4 308,2 22 22 17 19 80
21 Cerekwicki_Cezary_v01.sql 40562959,2 37802,4 2496637,8 3024 19 19 22 22 82
22 Kulczynski_Przemyslaw_v04.sql 73103680,2 68496,4 322134,4 458,6 21 21 20 21 83
23 Waluszko_Bartlomiej_v02.sql - - - - - - - - -
24 Jacewicz_Lukasz_v02.sql - - - - - - - - -

Dla każdego rozwiązania przy każdym teście uzyskałem sumę pozycji w poszczególnych kryteriach (ostatnia kolumna wg której ustalałem kolejność rozwiązań w powyższych tabelach wynikowych dla poszczególnych testów). Do uzyskania pozycji w końcowej tabeli wynikowej zsumowałem te wartości ze wszystkich trzech testów i tak wyszła mi tabela końcowa konkursu:

Lp Rozwiązanie T20 T50 T100 Total
1 Gniadkowski_Leszek_v15.sql 4 4 4 12
2 Gniadkowski_Leszek_v10.sql 7 7 7 21
3 Gniadkowski_Leszek_v12.sql 9 9 9 27
4 Nowakowski_Marcin_v04.sql 18 13 13 44
5 Sliwa_Krzysiek_v02.sql 30 19 22 71
6 Przeliorz_Tomek_v02.sql 24 24 25 73
7 Poniatowski_Aleksander_v01.sql 33 20 21 74
8 Zmuda_Katarzyna_v01.sql 25 26 30 81
9 Pater_Rafal_v03.sql 31 30 28 89
10 Pater_Rafal_v04.sql 34 32 30 96
11 Nowakowski_Marcin_v03.sql 30 31 39 100
12 Gailard_Pawel_v02.sql 44 32 30 106
13 Powichrowski_Marek_v12.sql 19 41 59 119
14 Powichrowski_Marek_v13.sql 37 44 60 141
15 Grabowska_Katarzyna_v04.sql 56 41 45 142
16 Pakulski_Maciej_v03.sql 48 55 53 156
17 Przeliorz_Tomek_v01.sql 38 50 70 158
18 Pakulski_Maciej_v02.sql 60 66 78 204
19 Sowa_Piotr_v10.sql 64 72 75 211
20 Kulczynski_Przemyslaw_v01.sql 55 78 80 213
21 Kulczynski_Przemyslaw_v04.sql 51 83 83 217
22 Cerekwicki_Cezary_v01.sql 83 80 82 245
23 Waluszko_Bartlomiej_v02.sql - - - -
24 Jacewicz_Lukasz_v02.sql - - - -

Legenda:

T20 – suma miejsc z testu “20”
T50 – suma miejsc z testu “50”
T100 – suma miejsc z testu “100”
Total – suma miejsc ze wszystkich testów

A zatem… Jednogłośnym zwycięzcą konkursu ogłaszam Leszka Gniadkowskiego. Drugie miejsce wśród uczestników (choć Leszek zdominował konkurs totalnie) zajął Marcin Nowakowski, a trzecie – Krzysztof Śliwa. Postanowiłem też nagrodzić miejsca 4. i 5. – a więc Tomka Przeliorza oraz Aleksandra Poniatowskiego. Ze zwycięzcami będę kontaktował się indywidualnie drogą mailową.

Dziękuję wszystkim, którzy wzięli udział w moim konkursie. Wszyscy, którzy zakwalifikowali się do finału oprócz słów uznania otrzymają ode mnie mały prezent (szczegóły niebawem w mailu). Szczególnie gratuluję zwycięzcom. Dobra SQL-owa robota :-)

Tym samym konkurs uznaję za zamknięty. Dla wytrwałych i ciekawskich publikuję pełen zestaw rozwiązań finałowych w pliku ZIP.

Pobierz wszystkie rozwiązania finałowe (ZIP, 21 KB)

[PL] SQL Server – Debugowanie z użyciem RAISERROR

VN:F [1.7.9_1023]
Rating: 5.0/5 (1 vote cast)

Ostatnio na forum portalu CodeGuru.pl brałem udział w dyskusji na temat metod prostego debugowania kodu T-SQL z wykorzystaniem polecenia PRINT. W wątku użytkownik szogun.krepa podał metodę obejścia problemu z poleceniem PRINT, które wysyła komunikat informacyjny (w przypadku aplikacji SQL Server Management Studio komunikat ten pojawia się w zakładce Messages) z opóźnieniami wynikającymi z długich czasów wykonania poleceń znajdujących się w tym samym wsadzie T-SQL.

Czy jest zatem PRINT działający bez opóźnień? Tak, takim odpowiednikiem jest odpowiednio wywołane polecenie RAISERROR. Odpowiednio to znaczy – z poziomem błędu ustawionym na 10 (poziomy od 1 do 9 też oznaczają informację, ale oprócz komunikatu pojawia się nagłówek błędu i już nie jest to działanie analogiczne z PRINT) oraz z przełącznikiem WITH NOWAIT. Porównajmy dwa wsady:

PRINT 'test 1';
WAITFOR DELAY '00:00:05';
GO
RAISERROR('test 2',10,1) WITH NOWAIT;
WAITFOR DELAY '00:00:05';
GO

W pierwszym przypadku komunikat “test 1” pojawia się po 5 sekundach i nie jest to efekt pożądany. W drugim przypadku komunikat “test 2” pojawia się natychmiast.

Ok, wszystko pięknie. Czy są zatem jakiekolwiek problemy, które możemy napotkać używając RAISERROR(…, 10, …) WITH NOWAIT? Zobaczmy taki kod:

DECLARE @zmienna varchar(10);
SET @zmienna = 'jakiś błąd';
RAISERROR('Komunikat: ' + @zmienna,10,1) WITH NOWAIT;
WAITFOR DELAY '00:00:05';
GO

-- Msg 102, Level 15, State 1, Line 3
-- Incorrect syntax near '+'.
-- Msg 319, Level 15, State 1, Line 3
-- Incorrect syntax near the keyword 'with'. If this statement is a common table
-- expression, an xmlnamespaces clause or a change tracking context clause,
-- the previous statement must be terminated with a semicolon.

Tak, w RAISERROR nie można generować komunikatu błędu wyrażeniem (albo literał, albo zmienna, ale nie wyrażenie). A zatem, zamiast powyższego można wykorzystać jeden z poniższych wariantów:

DECLARE
  @zmienna varchar(10),
  @komunikat varchar(255);
SET @zmienna = 'jakiś błąd';
SET @komunikat = 'Komunikat: ' + @zmienna;
RAISERROR(@komunikat,10,1) WITH NOWAIT;
WAITFOR DELAY '00:00:05';
GO

DECLARE @zmienna varchar(10);
SET @zmienna = 'jakiś błąd';
RAISERROR('Komunikat: %s',10,1, @zmienna) WITH NOWAIT;
WAITFOR DELAY '00:00:05';
GO

W pierwszym przypadku budujemy komunikat i zapisujemy go do jednej zmiennej (@komunikat), którą podstawiamy w wywołaniu polecenia RAISERROR jako pierwszy parametr.

W drugim przypadku korzystamy z parametryzowanego komunikatu (%s oznacza parametr tekstowy, wartości parametru pojawiają się kolejno jako czwarty i następne parametry polecenia RAISERRROR; więcej o parametryzowaniu RAISERROR do poczytania w Books Online).

Jak widać RAISERROR nadaje się do takiego natychmiastowego zwracania komunikatów, ale pod warunkiem, że będziemy pamiętać o wspomnianym powyżej ograniczeniu.

[PL] Konkurs T-SQL – Lista finalistów

VN:F [1.7.9_1023]
Rating: 5.0/5 (2 votes cast)

Parę minut temu zamknąłem listę finalistów konkursu T-SQL “Liga piłkarska”. Do finału dostały się poniższe rozwiązania:

Cerekwicki_Cezary_v01.sql
Gailard_Pawel_v02.sql
Gniadkowski_Leszek_v10.sql
Gniadkowski_Leszek_v12.sql
Gniadkowski_Leszek_v15.sql
Grabowska_Katarzyna_v04.sql
Jacewicz_Lukasz_v02.sql
Kulczynski_Przemyslaw_v01.sql
Kulczynski_Przemyslaw_v04.sql
Nowakowski_Marcin_v03.sql
Nowakowski_Marcin_v04.sql
Pakulski_Maciej_v02.sql
Pakulski_Maciej_v03.sql
Pater_Rafal_v03.sql
Pater_Rafal_v04.sql
Poniatowski_Aleksander_v01.sql
Powichrowski_Marek_v12.sql
Powichrowski_Marek_v13.sql
Przeliorz_Tomek_v01.sql
Przeliorz_Tomek_v02.sql
Sliwa_Krzysiek_v02.sql
Sowa_Piotr_v10.sql
Waluszko_Bartlomiej_v02.sql
Zmuda_Katarzyna_v01.sql

Gratuluję finalistom i dziękuję wszystkim osobom, które wzięły udział w konkursie. Najdalej w środę wieczór powinny ukazać się wyniki konkursu, o czym poinformuję też uczestników drogą mailową.

[PL] SQL Server – Pierwsza impresja na temat SQL Server 2008 SP2

VN:F [1.7.9_1023]
Rating: 0.0/5 (0 votes cast)

Dzisiaj ukazała się aktualizacja Service Pack 2 dla SQL Servera 2008. Rzuciłem się na nią wygłodzony :-) Powód był dość oczywisty. Otóż pracując w poprzedniej  firmie (Asseco Business Solutions S.A.) zgłaszałem w ramach swojej pracy błąd, który bardzo przeszkadzał w implementacji mechanizmu wprowadzania zmian we własnych typach danych (patrz wpis na moim blogu: http://sqlgeek.pl/2010/01/04/en-call-for-voting-alter-type-in-sql-server/). Zatem pierwsze kroki w nowym buildzie (SQL Server 2008 SP2 otrzymał okrągły numerek 10.0.4000) skierowałem właśnie ku sprawdzeniu, czy nie występuje błąd opisany tu: Deadlock occurs when creating user-defined data type and objects that use it.

Okazało się, że prawie to naprawiono… A że prawie robi wielką różnicę, postanowiłem opisać, na czym polega owo “prawie”.

Co działa?

begin tran
create type a from int null
go 
create function b ()
returns int
as
begin
  declare @t table (c a null)
  return 1
end
go
commit

Przed SP2 taki kod zwracał komunikat mówiący o wystąpieniu zakleszczenia (deadlocka).

Świetnie! Good work, Microsoft! Niestety, moja euforia zgasła chwilę po tym, jak uruchomiłem powyższy kod. Marek Adamczuk podesłał mi informację, że u niego po zainstalowaniu SP2 błąd nadal występuje. Cytując klasyka, ale o so chosi?

Ano, rozchodzi się o to, że istnieje cała klasa podobnych problemów i nie o wszystkich przypadkach pomyślano w Redmond :-) Zobaczmy taki kod:

begin tran
create type a from int null
go
declare @t table (c a null)
go
commit

Wstawienie do transakcji zmiennej tabelarycznej wykorzystującej typ danych tworzony w tej samej transakcji spowoduje dokładnie ten sam błąd, co w opisywanym powyżej przypadku. Do przetestowania jest jeszcze kilka innych problemów, ale już teraz widać, jak trudno naprawić wszystkie problemy z transakcyjnością, jeżeli już pojawią się takowe w silniku bazodanowym (naprawienie takich błędów może implikować powstanie następnych, jako że są to zmiany wprowadzane niskopoziomowo w samym silniku).

Wypada jedynie testować dokładnie swój kod i liczyć, że Microsoft nadal będzie reagował na nasze zgłoszenia. W tym przypadku należy się cieszyć, bo jednak reakcja jest prawidłowa (wyeliminowano błąd opisany przeze mnie w zgłoszeniu). Nie wyeliminowano błędu analogicznego, ale nie zgłoszonego na portalu connect.microsoft.com. No cóż, trzeba zakasać rękawy i opisać i ten przypadek, by programiści mogli pogłówkować, czy warto ów błąd naprawiać i, ewentualnie, jak to zrobić :-)