set datefirst 1 -- pierwszy dzien tygodnia poniedzialek set nocount on -- wylaczenie prezentowania liczby wierszy go if object_id('dbo.mgDatyStworzDate') is not null drop function dbo.mgDatyStworzDate go create function dbo.mgDatyStworzDate (@rok smallint, @miesiac tinyint, @dzien tinyint) returns datetime as begin declare @data char(8) select @data = x.rok+x.mie+x.dzien from ( select cast(@rok as char(4)) as rok, mie = case len(cast(@miesiac as char(2))) when 1 then '0'+rtrim(cast(@miesiac as char(2))) else cast(@miesiac as char(2)) end, dzien = case len(cast(@dzien as char(2))) when 1 then '0'+rtrim(cast(@dzien as char(2))) else cast(@dzien as char(2)) end) x return cast(@data as datetime) end go if object_id('dbo.mgDatyPobierzWielkanoc') is not null drop function dbo.mgDatyPobierzWielkanoc go create function dbo.mgDatyPobierzWielkanoc (@rok int) returns datetime as begin /* http://pl.wikipedia.org/wiki/Wielkanoc#Metoda__Meeusa.2FJonesa.2FButchera Dzielimy liczbe roku na 19 i wyznaczamy reszte a. Dzielimy liczbe roku przez 100, wynik zaokraglamy w dol (odcinamy czesc ulamkowa) i otrzymujemy cyfre b. Dzielimy liczbe roku przez 100 i otrzymujemy reszte c. Dzielimy b przez 4, wynik zaokraglamy w dol i otrzymujemy cyfre d. Dzielimy b przez 4 i wyznaczamy reszte e. Liczymy: (b + 8) : 25. Wynik zaokraglamy w dol i otrzymujemy liczbe f. Liczymy: (b - f + 1) : 3. Wynik zaokraglamy w dol i otrzymujemy liczbe g. Dzielimy (19 x a + b - d - g + 15) przez 30 i wyznaczamy reszte h. Dzielimy c przez 4, wynik zaokraglamy w dol i otrzymujemy cyfre i. Dzielimy c przez 4 i wyznaczamy reszte k. Dzielimy: (32 + 2 x e + 2 x i - h - k) przez 7 i otrzymujemy reszte l. Liczymy: (a + 11 x h + 22 x l) : 451. Wynik zaokraglamy w dol i otrzymujemy liczbe m. Dzielimy (h + l - 7 x m + 114) przez 31 i otrzymujemy reszte p. Dzien Wielkanocy = p + 1. Miesiac = Zaokraglenie w dol dzielenia (h + l - 7 x m + 114) przez 31. */ declare @a int, @b int, @c int, @d int, @e int, @f int, @g int, @h int, @i int, @k int, @l int, @m int, @p int set @a = @rok % 19 set @b = @rok / 100 set @c = @rok % 100 set @d = @b / 4 set @e = @b % 4 set @f = (@b + 8) / 25 set @g = (@b - @f + 1) / 3 set @h = (19 * @a + @b - @d - @g + 15) % 30 set @i = @c / 4 set @k = @c % 4 set @l = (32 + 2 * @e + 2 * @i - @h - @k) % 7 set @m = (@a + 11 * @h + 22 * @l) / 451 set @p = (@h + @l - 7 * @m + 114) % 31 declare @miesiac int = (@h + @l - 7 * @m + 114) / 31 declare @dzien int = @p+1 return dbo.mgDatyStworzDate(@rok,@miesiac,@dzien) end go if object_id('dbo.mgDatyCzyRokPrzestepny') is not null drop function dbo.mgDatyCzyRokPrzestepny go create function dbo.mgDatyCzyRokPrzestepny(@rok smallint) returns tinyint as begin -- warunki przestepnosci roku if ((@rok % 4 = 0) and (@rok % 100 != 0)) or (@rok % 400 = 0) begin return 1 end return 0 end go if object_id('dbo.mgDatyKalendarz') is not null drop table dbo.mgDatyKalendarz go create table dbo.mgDatyKalendarz ( data datetime primary key, rok smallint, rok_przestepny tinyint default (0), kwartal_roku tinyint, miesiac_roku tinyint, tydzien_roku tinyint, dzien_roku smallint, dzien_miesiaca tinyint, dzien_miesiaca_ostatni tinyint default (0), dzien_tygodnia tinyint, dzien_wolny tinyint default(0), uwagi varchar(128) null ) go if object_id('dbo.mgDatyWypelnij') is not null drop procedure dbo.mgDatyWypelnij go create procedure dbo.mgDatyWypelnij(@DataPoczatkowa datetime, @DataKoncowa datetime) as begin declare @data datetime set @data = @DataPoczatkowa declare @trancount int; set @trancount = @@trancount; begin try if @trancount = 0 begin transaction else save transaction mgDatyWypelnij; while @data <= @DataKoncowa begin insert into dbo.mgDatyKalendarz (data, rok,rok_przestepny, kwartal_roku, miesiac_roku, tydzien_roku, dzien_roku,dzien_miesiaca,dzien_tygodnia) values (@data, DATEPART(year,@data), dbo.mgDatyCzyRokPrzestepny(DATEPART(year,@data)), DATEPART(quarter,@data), DATEPART(month,@data), DATEPART(week,@data), DATEPART(DAYOFYEAR,@data), DATEPART(day,@data), DATEPART(weekday,@data)) set @data = dateadd(dd,1,@data) end /* 1 stycznia – Nowy Rok pierwszy dzien Wielkiej Nocy (tj. Niedziela Wielkanocna, swieto ruchome) drugi dzien Wielkiej Nocy (tj. Poniedzialek Wielkanocny, swieto ruchome) 1 maja – swieto Panstwowe (ustawa nie nazywa tego dnia "swietem Pracy") 3 maja – swieto Narodowe Trzeciego Maja pierwszy[1] dzien Zielonych swiatek (tj. liturgiczne Zeslanie Ducha swietego, swieto ruchome — zawsze przypada ono w niedziele, ale ustawa wymienia Zielone swiatki z osobna; ma to znaczenie, jezeli przepisy np. zakazuja pracy w swieta) dzien Bozego Ciala (tj. liturgiczna uroczystosc Najswietszego Ciala i Krwi Panskiej, swieto ruchome) 15 sierpnia – Wniebowziecie Najswietszej Maryi Panny (to swieto liturgiczne wymienia ustawa; data ta jest zbiezna z wprowadzonym w 1992 r. swietem Wojska Polskiego) 1 listopada – Wszystkich swietych 11 listopada – Narodowe swieto Niepodleglosci 25 grudnia – pierwszy dzien Bozego Narodzenia 26 grudnia – drugi dzien Bozego Narodzenia */ update dbo.mgDatyKalendarz set dzien_wolny = 1 where (miesiac_roku = 1 and dzien_miesiaca = 1) or (miesiac_roku = 5 and (dzien_miesiaca = 1 or dzien_miesiaca = 3)) or (miesiac_roku = 8 and dzien_miesiaca = 15) or (miesiac_roku = 11 and dzien_miesiaca = 11) or (miesiac_roku = 12 and (dzien_miesiaca = 25 or dzien_miesiaca = 26)) declare @rok int = datepart(year,@DataPoczatkowa) declare @wielkanoc datetime while (@rok <= datepart(year,@DataKoncowa)) begin set @wielkanoc = dbo.mgDatyPobierzWielkanoc(@rok) update dbo.mgDatyKalendarz set dzien_wolny = 1 where data in (@wielkanoc, @wielkanoc+1, @wielkanoc+49, @wielkanoc+60) set @rok = @rok + 1 end if @trancount = 0 commit; end try begin catch declare @error int, @message varchar(4000), @xstate int; select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE(); if @xstate = -1 rollback; if @xstate = 1 and @trancount = 0 rollback if @xstate = 1 and @trancount > 0 rollback transaction mgDatyWypelnij; raiserror ('mgDatyWypelnij: %d: %s', 16, 1, @error, @message) ; return 0; end catch return 1 end go exec dbo.mgDatyWypelnij '20000101','20200101' go select top 100 * from dbo.mgDatyKalendarz