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 :
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
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.