Monthly Archives: Maj 2013
DataGridView – płynne przewijanie zawartości
2013-05-19
Przy dużych zbiorach danych prezentowanych w kontrolce DataGridView może pojawić się problem z płynnością ich przewijania. Sposobem na wyeliminowanie tego efektu jest ustawienie właściwości DoubleBuffered na true. Jest to właściwość protected więc mamy dwie możliwości: stworzyć własną klasę dziedziczącą po DataGridView i w niej ustawić wartość właściwości DoubleBuffered lub stworzyć metodę rozszerzającą, która przy użyciu refleksji odwoła się do omawianej właściwości i ustawi jej wartość. Poniżej znajduje się implementacja drugiego z wymienionych sposobów:
public static class DataGridViewExtensions { public static void DoubleBuffered(this DataGridView dgv, bool setting) { Type dgvType = dgv.GetType(); PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); pi.SetValue(dgv, setting, null); } }
Użycie powyższej metody:
dataGridView1.DoubleBuffered(true);
Dzięki właściwości DoubleBuffered jesteśmy w stanie wyeliminować problemy z brakiem płynności oraz odświeżaniem kontrolki DataGridView podczas przewijania jej zawartości.
T-SQL – kilka przykładów zastosowania tabeli liczb całkowitych
2013-05-09
W poprzednim wpisie pokazałem kilka sposobów na wygenerowanie zbioru kolejnych liczb całkowitych. Dzisiaj zaprezentuję wykorzystanie tych danych w kilku przypadkach. Zacznijmy od przygotowania tabeli zawierającej 100 liczb, będzie ona używana w każdym z prezentowanych przykładów:
declare @Numbers table (N int); with Numbers as ( select 1 as Number union all select Number + 1 from Numbers where Number < 100 ) insert into @Numbers(N) select Number from Numbers option (maxrecursion 100)
Generowanie dat
Poniższe zapytanie zwraca daty oraz informację o dniu tygodnia dla wszystkich dni znajdujących się pomiędzy dwoma datami:
set datefirst 1 declare @beginDate date = '20130501', @endDate date = '20130731' select DateAdd(dd, N - 1, @beginDate) as [Date], case DatePart(dw, DateAdd(dd, N - 1, @beginDate)) when 1 then 'Pn' when 2 then 'Wt' when 3 then 'Śr' when 4 then 'Cz' when 5 then 'Pi' when 6 then 'So' when 7 then 'Ni' end as [WeekDay] from @Numbers where DateAdd(dd, N - 1, @beginDate) <= @endDate
Luki w numeracji
Załóżmy, że mamy tabelę zawierającą określone wartości liczbowe:
declare @Values table (value int) insert into @Values (value) values (1),(3),(4),(5),(8),(10) select * from @Values
Poniżej znajduje się zapytanie zwracające luki w numeracji:
declare @minValue int, @maxValue int select @minValue = min(value), @maxValue = max(value) from @Values select N as Value from @Numbers n left join @Values v on v.value = n.N where n.N between @minValue and @maxValue and v.value is null
Pozycje występowania danego znaku w tekście
Zapytanie zwraca numery pozycji w tekście, na których znajduje się określony znak:
declare @text varchar(100) = 'to jest przykładowy tekst' declare @char char(1) = 't' select N as [CharIndex] from @Numbers where SubString(@text, N, 1) = @char and N <= Len(@text)
Litery występujące w tekście
Poniższe zapytanie zwraca wszystkie litery z podanego tekstu wraz z kodami Ascii oraz liczbą wystąpień:
declare @text varchar(100) = 'to jest przykładowy tekst' select SubString(@text, N, 1) as [Char], Ascii(SubString(@text, N, 1)) as [Ascii], Count(*) as [Count] from @Numbers where N <= Len(@text) group by SubString(@text, N, 1)
Podział tekstu na wyrazy
Zapytanie zwraca wszystkie fragmenty danego tekstu rozdzielone określonym znakiem:
declare @text varchar(100) = 'to jest przykładowy tekst' declare @char char(1) = ' ' set @text = @char + @text + @char select SubString(@text, N + 1, CharIndex(@char, @text, N + 1) - N - 1) as [Words] from @Numbers where SubString(@text, N, 1) = @char and N < Len(@text)
T-SQL – generowanie zbioru kolejnych liczb całkowitych
2013-05-08
Często podczas programowania w T-SQL pojawia się potrzeba skorzystania ze zbioru kolejnych liczb całkowitych z określonego zakresu. SQL Server nie posiada gotowej tabeli zawierającej takie dane, pozostaje opracowanie własnego rozwiązania. Poniżej znajdują się trzy przykłady kodu generującego zbiór kolejnych liczb całkowitych z zakresu od 1 do 195. Skrypty nie korzystają z żadnych obiektów bazy danych (tabele systemowe, widoki), nie opierają się również na pętli while co jest częstym ale mało wydajnym podejściem.
Skrypt 1:
with Numbers as ( select 1 as Number union all select Number + 1 from Numbers where Number < 195 ) select Number from Numbers option (maxrecursion 195)
Skrypt 2:
select top 195 (a * 10 + b) as Number from ( values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10), (11),(12),(13),(14),(15),(16),(17),(18),(19) ) as A(a), ( values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10) ) as B(b) order by 1
Skrypt 3:
with Numbers as ( select a from ( values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10) ) as A(a) ) select top 195 row_number() over(order by @@spid) as Number from Numbers as a, Numbers as b, Numbers as c
W kolejnym wpisie pokażę kilka przykładów zastosowania wygenerowanego w ten sposób zbioru liczb do rozwiązania określonych problemów.