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 SQL : Sélectionner tout - Visualiser dans une fenêtre à part
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 SQL : Sélectionner tout - Visualiser dans une fenêtre à part
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 :
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".
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
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
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.
Partager