[Modélisation] Table calendrier
Bonjour,
J'utilise SQL Server 2014 CTP2 Express et non 2012. Je ne sais pas si cela peut avoir une incidence.
Devant mettre en place une application qui travaille intensivement sur des intervales de dates, j'ai créé une table calendrier.
Et là, je me pose une question.
Je n'ai, pour le moment tout du moins, pas besoin de colonnes autres que le jour. Pas de notion de vacances, trimerstre ou autre. Juste les jours.
J'étais donc parti sur une telle modélisation :
Code:
1 2 3 4 5 6
|
create table Calendar
(
id int identity not null primary key,
[day] date not null unique
); |
Que j'allimente avec cette procédure :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
create procedure CreateCalendar
(
@year int
)
as
BEGIN
declare @dt1 datetime;
declare @dt2 datetime;
SET @dt1 = CONVERT(datetime, '01/01/' + cast(@year as varchar), 103);
SET @dt2 = CONVERT(datetime, '31/12/' + cast(@year as varchar), 103);
WITH Cal (dt) AS
(
SELECT @dt1
union ALL
SELECT dt + 1
FROM Cal
WHERE dt < @dt2
)
insert into Calendar ([day])
SELECT dt
FROM Cal
WHERE dt not in (select [day] from Calendar)
option (maxrecursion 366);
end
go |
Plusieurs choses :
1/ Vous remarquerez que dans ma procédure de remplissage de la table calendrier, j'utilise non pas le type "date" comme dans la table, mais le type "datetime". Je n'ai pas du tout compris pourquoi, mais lorsque j'utilise "date" dans la procédure, j'ai des erreurs de compilation (bon, à la limite, OSEF, puisque c'est du quasi one-shot de toute façon, et que ça fonctionne quand même).
2/ Ai-je un réel intérêt à utliser une colonne "id" de type "int" comme clé primaire à ma table "calendar" ? N'est-ce pas mieux si c'est la colonne "day" qui est utilisé comme clé primaire (donc ordonnée physiquement par ordre chronologique, et pas de double contrainte d'unicité) ?
Ensuite, dans mon code, j'ai par exemple ce genre de choses :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
create function ComputePrice(@camping_id int, @from datetime, @to datetime, @options OptionsType readonly)
RETURNS money
AS
BEGIN
return (
select sum(p.amount * oo.amount)
from season s
inner join pricelevel pl on pl.season_id = s.id
inner join [level] l on l.id = pl.level_id
inner join calendar c on c.[day] between pl.[from] and pl.[to]
cross join @options oo
inner join price p on p.level_id = l.id and p.option_id = oo.option_id
where s.camping_id = @camping_id
and c.[day] between @from and @to
);
END
GO |
On voit bien que mes jointures (et c'est toujours le cas) avec la table "calendar" portent non pas sur la colonne "id", mais la colonne "day".
Cependant, SQLPro, dans un ancien article (qui date de SQL Server 2005 il me semble) indiquait que l'utilisation d'une date (datetime) comme clé primaire nécessitait de mettre en place un paramétrage particulier. Ici il ne s'agit pas du type datetime, mais du type date, qui n'existait pas à l'époque...
Enfin, la procédure que j'ai mis en exemple n'est pas là par hasard...
Pensez-vous que le passage en paramètre d'une table soit performant ? Quelles autres solutions, plus performantes existes ?
Je pense notamment à l'utilisation d'une table temporaire, ce que j'ai failli faire de prime abord.
Merci d'avance pour vos réponses.