Reporting Services Déploiement
-
01-07-2019 - |
Question
Je dois créer un processus répétable pour déployer les rapports SQL Server Reporting Services. Je ne suis pas en faveur de l'utilisation de Visual Studio et / ou de Business Development Studio pour ce faire. La méthode rs.exe de scriptage des déploiements semble également assez maladroite. Quelqu'un at-il une manière très élégante de déployer des rapports? La clé ici est que je veux que le processus soit complètement automatisé.
La solution
Nous utilisons rs.exe. Une fois que nous avons développé le script, nous n’avons plus besoin de le toucher, cela fonctionne.
Voici le source (je l’ai légèrement modifié à la main pour supprimer les données sensibles sans avoir la possibilité de le tester, espérons que je n’ai rien freiné), il déploie des rapports et des images associées provenant de sous-répertoires pour différentes langues. Une source de données est également créée.
'=====================================================================
' File: PublishReports.rss
'
' Summary: Script that can be used with RS.exe to
' publish the reports.
'
' Rss file spans from beginnig of this comment to end of module
' (except of "End Module").
'=====================================================================
Dim langPaths As String() = {"en", "cs", "pl", "de"}
Dim filePath As String = Environment.CurrentDirectory
Public Sub Main()
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
'Create parent folder
Try
rs.CreateFolder(parentFolder, "/", Nothing)
Console.WriteLine("Parent folder created: {0}", parentFolder)
Catch e As Exception
Console.WriteLine(e.Message)
End Try
PublishLanguagesFromFolder(filePath)
End Sub
Public Sub PublishLanguagesFromFolder(ByVal folder As String)
Dim Lang As Integer
Dim langPath As String
For Lang = langPaths.GetLowerBound(0) To langPaths.GetUpperBound(0)
langPath = langPaths(Lang)
'Create the lang folder
Try
rs.CreateFolder(langPath, "/" + parentFolder, Nothing)
Console.WriteLine("Parent lang folder created: {0}", parentFolder + "/" + langPath)
Catch e As Exception
Console.WriteLine(e.Message)
End Try
'Create the shared data source
CreateDataSource("/" + parentFolder + "/" + langPath)
'Publish reports and images
PublishFolderContents(folder + "\" + langPath, "/" + parentFolder + "/" + langPath)
Next 'Lang
End Sub
Public Sub CreateDataSource(ByVal targetFolder As String)
Dim name As String = "data source"
'Data source definition.
Dim definition As New DataSourceDefinition
definition.CredentialRetrieval = CredentialRetrievalEnum.Store
definition.ConnectString = "data source=" + dbServer + ";initial catalog=" + db
definition.Enabled = True
definition.EnabledSpecified = True
definition.Extension = "SQL"
definition.ImpersonateUser = False
definition.ImpersonateUserSpecified = True
'Use the default prompt string.
definition.Prompt = Nothing
definition.WindowsCredentials = False
'Login information
definition.UserName = "user"
definition.Password = "password"
Try
'name, folder, overwrite, definition, properties
rs.CreateDataSource(name, targetFolder, True, definition, Nothing)
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub
Public Sub PublishFolderContents(ByVal sourceFolder As String, ByVal targetFolder As String)
Dim di As New DirectoryInfo(sourceFolder)
Dim fis As FileInfo() = di.GetFiles()
Dim fi As FileInfo
Dim fileName As String
For Each fi In fis
fileName = fi.Name
Select Case fileName.Substring(fileName.Length - 4).ToUpper
Case ".RDL"
PublishReport(sourceFolder, fileName, targetFolder)
Case ".JPG", ".JPEG"
PublishResource(sourceFolder, fileName, "image/jpeg", targetFolder)
Case ".GIF", ".PNG", ".BMP"
PublishResource(sourceFolder, fileName, "image/" + fileName.Substring(fileName.Length - 3).ToLower, targetFolder)
End Select
Next fi
End Sub
Public Sub PublishReport(ByVal sourceFolder As String, ByVal reportName As String, ByVal targetFolder As String)
Dim definition As [Byte]() = Nothing
Dim warnings As Warning() = Nothing
Try
Dim stream As FileStream = File.OpenRead(sourceFolder + "\" + reportName)
definition = New [Byte](stream.Length) {}
stream.Read(definition, 0, CInt(stream.Length))
stream.Close()
Catch e As IOException
Console.WriteLine(e.Message)
End Try
Try
'name, folder, overwrite, definition, properties
warnings = rs.CreateReport(reportName.Substring(0, reportName.Length - 4), targetFolder, True, definition, Nothing)
If Not (warnings Is Nothing) Then
Dim warning As Warning
For Each warning In warnings
Console.WriteLine(warning.Message)
Next warning
Else
Console.WriteLine("Report: {0} published successfully with no warnings", targetFolder + "/" + reportName)
End If
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub
Public Sub PublishResource(ByVal sourceFolder As String, ByVal resourceName As String, ByVal resourceMIME As String, ByVal targetFolder As String)
Dim definition As [Byte]() = Nothing
Dim warnings As Warning() = Nothing
Try
Dim stream As FileStream = File.OpenRead(sourceFolder + "\" + resourceName)
definition = New [Byte](stream.Length) {}
stream.Read(definition, 0, CInt(stream.Length))
stream.Close()
Catch e As IOException
Console.WriteLine(e.Message)
End Try
Try
'name, folder, overwrite, definition, MIME, properties
rs.CreateResource(resourceName, targetFolder, True, definition, resourceMIME, Nothing)
Console.WriteLine("Resource: {0} with MIME {1} created successfully", targetFolder + "/" + resourceName, resourceMIME)
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub
Voici le lot pour appeler le fichier rs.exe:
SET ReportServer=%1
SET DBServer=%2
SET DBName=%3
SET ReportFolder=%4
rs -i PublishReports.rss -s %ReportServer% -v dbServer="%DBServer%" -v db="%DBName%" -v parentFolder="%ReportFolder%" >PublishReports.log 2>&1
pause
Autres conseils
J'ai utilisé le script @David fourni, mais j'ai dû ajouter du code ( Je tape ceci comme réponse car ce serait trop long pour un commentaire.
Le problème est le suivant: s’il existe déjà une " source de données partagée " attaché à un rapport dans la définition de rapport, il ne s'agit jamais de la même source de données que celle créée dans le script.
Cela apparaît également dans l'avertissement émis par le message "CreateReport". méthode:
L'ensemble de données '' fait référence à la source de données partagée '', qui n'est pas publiée sur le serveur de rapports.
La source de données doit donc être définie explicitement par la suite. J'ai apporté les modifications de code suivantes:
J'ai ajouté une variable globale:
Dim dataSourceRefs(0) As DataSource
À la fin de la méthode CreateDataSource, cette variable est renseignée:
Dim dsr As New DataSourceReference
dsr.Reference = "/" + parentFolder + "/" + db
Dim ds As New DataSource
ds.Item = CType(dsr, DataSourceDefinitionOrReference)
ds.Name = db
dataSourceRefs(0) = ds
Et dans la méthode PublishReport, cette source de données est explicitement définie (après l'appel de CreateReport):
rs.SetItemDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)
Notez que ce dernier appel concerne uniquement RS 2005 ou une version ultérieure. Si vous souhaitez charger vos rapports sur un serveur RS 2000, vous devez utiliser l'option Définir Rapport DataSources:
.rs.SetReportDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)
Bien pas vraiment élégant. Nous avons créé notre propre outil qui utilise le service Web reportingservices2005. Nous avons trouvé que c'était le moyen le plus fiable d'obtenir ce que nous voulions.
Ce n’est pas vraiment difficile et vous permet de l’étendre à d’autres tâches telles que la création de sources de données et de dossiers, si nécessaire.
Je recommande vivement RSScripter . Comme indiqué dans l'aperçu:
Reporting Services Scripter est un .NET Application Windows Forms qui permet script et transfert de tous Reporting Microsoft SQL Server Articles du catalogue de services pour vous aider les transférer d'un serveur à un autre. Il peut également être utilisé pour facilement déplacer des objets sur la masse d'un rapport Dossier de services à un autre sur le même serveur. En fonction du script options choisies, Reporting Services Scripter peut également transférer tout le catalogue les propriétés d'élément telles que les descriptions, Options d'historique, options d'exécution (y compris les rapports spécifiques et partagés horaires), des abonnements (normaux et piloté par les données) et rapport côté serveur paramètres.
Je sais que vous dites que vous n'êtes pas en faveur de Business Development Studio, mais j'ai trouvé les outils intégrés très fiables et faciles à utiliser.
Avez-vous examiné des solutions d’intégration continue telles que CruiseControl.NET? Si vous êtes en mesure de déployer des rapports à l'aide de rs.exe, vous pouvez configurer un processus automatisé dans CruiseControl pour créer et déployer vos rapports sur un minuteur ou à chaque fois qu'un rapport est modifié.
Dans notre environnement, nous développons sous VS avec contrôle de version, puis déployons vers DEV SSRS. Une fois le rapport validé, nous utilisons le programme ReportSync pour déployer des rapports de ReportServer DEV
à ReportServer PROD
. Les scripts RS.EXE ont toujours leur place, mais j'ai trouvé que ReportSync était un moyen beaucoup plus simple et agile de promouvoir un rapport.
ReportSync:
ReportSync
est un programme open source gratuit à télécharger et à utiliser. Il fonctionne très bien pour télécharger des rapports en bloc et peut même transférer un rapport d’un serveur à un autre.
Comment télécharger le programme?
-
Téléchargez les fichiers de code source à partir de Github: Phires / ReportSynch , Run VS, Open le fichier de solution (.SLN), compilez le programme, recherchez le fichier exécutable (.EXE) dans le dossier C: \ Temp \ reportsync-master \ bin \ Release . Enfin, avez sauvegardé le fichier .EXE à utiliser régulièrement
-
Comment copier des rapports SSRS sur un nouveau serveur si je ne suis pas le propriétaire des rapports - > Réponse ReportSync par nunespascal
Comment déployer un rapport?
- Lancez l'exécutable et l'interface se lancera.
- Utilisez les dialogues
SOURCE
etDESTINATION
pour choisir unrapport unique
,plusieurs rapports
ou untout le dossier des rapports
. Vous pouvez choisir le dossier cible de votre choix. (CONSEIL: vous pouvez même cibler le même serveur si vous souhaitez dupliquer un rapport sur le même serveur.) - Après avoir effectué vos sélections, appuyez sur le
bouton de synchronisation
.
- Accédez au serveur cible et validez la prise en compte de la modification en consultant la date de modification par.
Cet outil a été très pratique, mais j’ai remarqué quelques bizarreries. Par exemple, lorsque je souhaite mettre à jour un seul rapport qui existe déjà dans la destination
, voici ce que je dois sélectionner-- [ Source: Rapport > Cible: dossier > Sync
]. AVERTISSEMENT: vous pensez peut-être sélectionner le rapport du serveur cible pour le mettre à jour, mais j'ai déjà essayé et le rapport n'est pas mis à jour.
Que peut faire ReportSync?
-
Il existe également une fonctionnalité
Export
, qui fonctionne à merveille pour vider simplement tous les fichiers RDL dans un dossier auquel je peux accéder. Ceci est utile dans le cas où vous devez migrer le serveur, ajouter les fichiers à un projet de solution VS ou faire quoi que ce soit d'autre que tous les fichiers. -
Lors de mes tests, ce programme ne migre pas les autres contenus - abonnements, sources de données partagées, ensembles de données partagés. Cela s'applique uniquement aux fichiers de rapport.
Je sais que ce message est ancien, mais je l'ai trouvé lors de la recherche de scripts RS.EXE. J'ai donc pensé répondre à cette question.