jeudi 25 novembre 2010

[SSRS] Ajouter un délimiteur au format d'export csv sur Reporting Service

Reporting services propose par défaut 7 formats d'export :
  • Fichier XML avec données de rapport
  • CSV (délimité par des virgules)
  • Fichier Acrobat (PDF)
  • MHTML (archive Web)
  • Excel
  • Fichier TIFF
  • Word
Lorsqu'on exporte en csv, le délimiteur par défaut est la virgule (il s'agit du format utilisé aux US)



Une demande qui revient régulièrement est de pouvoir exporter en csv avec un délimiteur point-virgule.

Mise en place:

Il faut pour cela aller éditer le fichier rsreportserver.config qui se trouve dans le répertoire \MSRS10.nomdelinstance\Reporting Services\ReportServer

Au niveau du noeud render, il suffit d'ajouter le bloc suivant (la première ligne est un copier-coller de la ligne d'extension CSV standard) :



Il suffit d'enregistrer le fichier et de redémarrer le service Reporing Services. On a maintenant accès dans la liste des exports à CSV (point-virgule) :



Si l'on fait un export pour vérifier que tout fonctionne, on a bien le résultat attendu :


To be continued...

mardi 23 novembre 2010

[SSAS] Exploiter et déchiffrer OlapQueryLog pour créer des rapports d'utilisation d'un cube

Nous avons souvent été confrontés à des clients voulant des rapports d'utilisation d'un cube, c'est-à-dire savoir qui utilise telle ou telle dimension ou groupe de mesures.
Et nous avons tous remarqué après avoir activé l'OlapQueryLog que les dataset étaient stockés sous la forme d'une suite de 0 et de 1.
Nous allons voir comment analyser et rendre visible ces résultats.

Première étape :

Il faut activer les logs de requêtages du cube sous Analysis Services (désactivés par défaut).
Pour cela, on doit aller dans les propriétés du serveur AS, et configurer les propriétés suivantes :
  • Log \ QueryLog \ CreateQueryLogTable
Active ou désactive les logs (true ou false)
  • Log \ QueryLog \ QueryLogConnectionString
Chaine de connexion à votre table de log
  • Log \ QueryLog \ QueryLogSampling
Entier n indiquant que vous enregistrez dans votre table toutes n-requêtes
  • Log \ QueryLog \ TableName 
Nom de votre table de log

Par exemple :




A partir de là, la table OlapQueryLog commence à se remplir au fur et à mesure des interrogations du cube. Mais comme on peut le voir, le champ dataset de cette table n'est pas exploitable en l'état :



Deuxième étape :

Elle consiste à rendre lisible les données de la table OlapQueryLog. Pour cela, il est important de comprendre le champ dataset. La suite de 0 et de 1 correspond à la séquence d'utilisation des attributs d'une dimension pour un groupe de mesures donné.

La première chose à faire est de charger la structure du cube dans une table, grâce par exemple à ce package SSIS (La manipulation est à refaire à chaque nouveau déploiement du cube, celui-ci réinitialisant la table OlapQueryLog). Il suffit de configurer les 4 variables :
  • CubeServer : adresse de votre serveur Analysis Services (eviter 'localhost' et préférer le nom de la machine)
  • InitialCatalog : nom de la base de données où vous voulez stocker votre table de structure
  • Server : adresse du serveur SQL où vous voulez stocker votre table de structure
  • TableName : nom de votre table de structure
Après exécution du package votre table aura la forme suivante :


Il suffit maintenant de dépiler les 0 et les 1 de notre dataset original. Ce que l'on peut faire avec la procédure stockée suivante :

CREATE proc [dbo].[LoadOlapQueryLog] (@User nvarchar(255)=NULL,@Cube varchar(100)=NULL,@Date datetime=NULL)
AS

CREATE TABLE TableCompteur ([number] [int] NOT NULL)
DECLARE @LongMax int
DECLARE @j int
select @LongMax=MAX(LEN(dataset)) from OlapQueryLog
set @j=1
WHILE (@j<=@LongMax)
BEGIN
INSERT INTO TableCompteur(number) values (@j)
SET @j=@j+1
END


select cs.[Server] ,
cs.[Database],
cs.[Cube],
cs.MeasuresGroupName,
cs.Dimension,
cs.Attribute,
OQL.MSOLAP_User,
StartTime,
Duration
from dbo.OlapQueryLog OQL
INNER JOIN TableCompteur
on TableCompteur.number<=LEN(OQL.dataset)
INNER JOIN CubeStructure CS
ON CS.[OLAPPATH]=OQL.MSOLAP_ObjectPath
AND CS.AttributeOrder = TableCompteur.number
WHERE substring(OQL.Dataset,TableCompteur.number,1)='1'
and (@User is null or OQL.MSOLAP_User=@User)
and (@Cube is null or cs.[Cube]=@Cube)
and (@Date is null or cast(StartTime as date)=cast(@Date as date))
DROP TABLE TableCompteur
RETURN

Après exécution de cette procédure vous obtenez la table suivante :



Elle donne bien la liste des différents attributs utilisés dans le cube de manière lisible et exploitable. Il ne vous reste plus qu'à créer des rapports se basant dessus pour diffuser les informations.

vendredi 19 novembre 2010

Sortie de la CPT1 SQL Server 2011 (nom de code Denali)

Le 10 novembre 2010, lors du PASS Summit 2010, Microsoft a mis disposition la première CPT de SQL Server Denali.


Au programme selon l'éditeur :

  • Une nouvelle plateforme à plus haute disponibilité et évolutive
  • Pour les développeurs : une productivité renforcée grâce à de nouveaux outils et de nouvelles features
  • Pour la BI : extension de la BI aux utilisateurs et une intégration/gestion des données de bout en bout.

C'est surtout cette dernière partie qui nous intéresse et qui passe à priori par trois évolutions majeures :
  • La refonte de la gestion serveur d'Integration Services et un nouveau service nommé Data Quality Services
  • Une interface full-web pour la création et la diffusion de rapports : Crescent
  • L'intégration dans Analysis Services du moteur de PowerPivot : Vertipaq

Plus d'informations et téléchargement à l'adresse suivante :

Premier article : Modélisation d'une dimension temps

Pour mon premier article, je souhaite parler d'un sujet qui va paraître évident à tout le monde et qui est la première pierre de tout système décisionnel : la dimension Temps


Pourquoi m'attarder dessus ? Tout simplement car je remarque très souvent chez mes clients que les choses les plus évidentes ne le sont pas forcément pour tout le monde.


Je parlerai essentiellement de deux choses :

  • La clé primaire de cette dimension
  • Le numéros de semaine et les années qui y sont rattachées

Clé primaire d'une dimension Temps :

On nous apprend très tôt que toute dimension d'un datawarehouse doit être un entier auto-incrémenté, et beaucoup l'applique également au temps.
Je préconise plutôt un entier de la forme YYYYMMDD (par exemple 20101119) comme clé primaire.
Ceci pour deux avantages :
  • Une requête sur les tables de faits ne nécessitent pas de jointures sur la dimension Temps car la date est stockée en clair.
  • Dans le cas d'une forte volumétrie qui vous impose de partitionner votre base de données relationnelle, votre fonction de partitionnement aura une valeur fonctionnelle : c'est-à-dire que vous définirez les plages de votre fonctions entre deux dates.

Numéros de semaine et année de la semaine :

Sauf besoin spécifique de votre client, celui-ci attend comme numéro de semaine, le numéro ISO de la semaine, car il s'agit de celui qui permet de comparer une semaine d'une année à l'autre.
Je vous donne le lien vers la définition de Wikipedia, mais pour faire simple, la première semaine d'une année est celle qui contient le premier jeudi de l'année.

SQL Server 2008 a introduit dans sa fonction datepart le mot-clé isowk, c'est pourquoi vous pouvez définir votre numéro de semaine directement à la création de votre table de dimension en créant une colonne calculée DATEPART(isowk,date).

Cette définition implique qu'une date n'est pas forcément rattachée à son année civile (par exemple le 1er janvier 2006 est rattaché à la semaine 52 de l'année 2005). Il faut donc ajouter une colonne année de la semaine dans notre table.
Celle-ci peut être aussi ajoutée grâce à une colonne calculée :
DATEPART(year,DATEADD(d,-(DATEPART(weekday,date)+5) % 7+3,date))
(plus de détails sur le calcul ici)


to be continued...